From eeded2cdeba00bb273417dc4901ea8ad344bfb18 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Thu, 8 Feb 2024 15:11:54 +0100 Subject: [PATCH 01/39] first iteration on storage multi keys --- subxt/src/storage/storage_address.rs | 275 +++++++++++++++++---------- 1 file changed, 177 insertions(+), 98 deletions(-) diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 893474b518..86ff19bdfb 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -9,9 +9,10 @@ use crate::{ utils::{Encoded, Static}, }; use derivative::Derivative; +use scale_encode::EncodeAsType; use scale_info::TypeDef; use std::borrow::Cow; -use subxt_metadata::{StorageEntryType, StorageHasher}; +use subxt_metadata::{StorageEntryMetadata, StorageEntryType, StorageHasher}; /// This represents a storage address. Anything implementing this trait /// can be used to fetch and iterate over storage entries. @@ -53,61 +54,152 @@ pub struct Yes; /// A concrete storage address. This can be created from static values (ie those generated /// via the `subxt` macro) or dynamic values via [`dynamic`]. #[derive(Derivative)] -#[derivative( - Clone(bound = "StorageKey: Clone"), - Debug(bound = "StorageKey: std::fmt::Debug") -)] -pub struct Address { +#[derivative(Clone(bound = "Keys: Clone"), Debug(bound = "Keys: std::fmt::Debug"))] +pub struct Address { pallet_name: Cow<'static, str>, entry_name: Cow<'static, str>, - storage_entry_keys: Vec, + keys: Keys, validation_hash: Option<[u8; 32]>, _marker: std::marker::PhantomData<(ReturnTy, Fetchable, Defaultable, Iterable)>, } +#[derive(Derivative)] +#[derivative(Clone(bound = "K: Clone"), Debug(bound = "K: std::fmt::Debug"))] +pub enum StorageKey { + Encoded(Static), + Bare(K), +} + +impl StorageKey { + pub fn new_encoded(key_ty: &K) -> StorageKey { + StorageKey::Encoded(Static(Encoded(key_ty.encode()))) + } +} + +impl EncodeAsType for StorageKey { + fn encode_as_type_to( + &self, + type_id: u32, + types: &scale_info::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + match self { + StorageKey::Encoded(e) => e.encode_as_type_to(type_id, types, out), + StorageKey::Bare(e) => e.encode_as_type_to(type_id, types, out), + } + } +} + +pub trait StorageMultiKey { + fn keys_iter(&self) -> impl ExactSizeIterator; +} + +/// Implement `StorageMultiKey` for `()` which can be used for keyless storage entries +impl StorageMultiKey for () { + fn keys_iter(&self) -> impl ExactSizeIterator { + // Note: this returns the storage root address of the storage entry. + // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. + std::iter::empty() + } +} + +impl StorageMultiKey for StorageKey { + fn keys_iter(&self) -> impl ExactSizeIterator { + // Note: this returns the storage root address of the storage entry. + // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. + std::iter::once(self as &dyn EncodeAsType) + } +} + +impl StorageMultiKey for Vec> { + fn keys_iter(&self) -> impl ExactSizeIterator { + // Note: this returns the storage root address of the storage entry. + // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. + self.iter().map(|e| e as &dyn EncodeAsType) + } +} + +// impl StorageMultiKey for (StorageKey, StorageKey) { +// fn keys_iter(&self) -> impl ExactSizeIterator { +// let arr = [&self.0 as &dyn EncodeAsType, &self.1 as &dyn EncodeAsType]; +// arr.into_iter() +// } +// } + +macro_rules! impl_tuples { + ($($ty:ident $n:tt),+) => {{ + impl<$($ty: EncodeAsType),+> StorageMultiKey for ($( StorageKey<$ty >),+) { + fn keys_iter(&self) -> impl ExactSizeIterator { + let arr = [$( + &self.$n as &dyn EncodeAsType + ),+]; + arr.into_iter() + } + } + }}; +} + +#[rustfmt::skip] +const _: () = { + impl_tuples!(A 0, B 1); + impl_tuples!(A 0, B 1, C 2); + impl_tuples!(A 0, B 1, C 2, D 3); + impl_tuples!(A 0, B 1, C 2, D 3, E 4); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7); +}; + +// todo! impl MultiStorageKey for Vec> and for (StorageKey, StorageKey), ... +// impl MultiStorageKey + /// A typical storage address constructed at runtime rather than via the `subxt` macro; this /// has no restriction on what it can be used for (since we don't statically know). -pub type DynamicAddress = Address; +pub type DynamicAddress = Address; -impl - Address -where - StorageKey: EncodeWithMetadata, - ReturnTy: DecodeWithMetadata, -{ - /// Create a new [`Address`] to use to access a storage entry. - pub fn new( - pallet_name: impl Into, - entry_name: impl Into, - storage_entry_keys: Vec, - ) -> Self { +impl DynamicAddress { + pub fn new(pallet_name: impl Into, entry_name: impl Into, keys: Keys) -> Self { Self { pallet_name: Cow::Owned(pallet_name.into()), entry_name: Cow::Owned(entry_name.into()), - storage_entry_keys: storage_entry_keys.into_iter().collect(), + keys, validation_hash: None, _marker: std::marker::PhantomData, } } +} +impl + Address +where + Keys: StorageMultiKey, + ReturnTy: DecodeWithMetadata, +{ /// Create a new [`Address`] using static strings for the pallet and call name. /// This is only expected to be used from codegen. #[doc(hidden)] pub fn new_static( pallet_name: &'static str, entry_name: &'static str, - storage_entry_keys: Vec, + keys: Keys, hash: [u8; 32], ) -> Self { Self { pallet_name: Cow::Borrowed(pallet_name), entry_name: Cow::Borrowed(entry_name), - storage_entry_keys: storage_entry_keys.into_iter().collect(), + keys, validation_hash: Some(hash), _marker: std::marker::PhantomData, } } +} +impl + Address +where + Keys: StorageMultiKey, + ReturnTy: DecodeWithMetadata, +{ /// Do not validate this storage entry prior to accessing it. pub fn unvalidated(self) -> Self { Self { @@ -124,10 +216,10 @@ where } } -impl StorageAddress - for Address +impl StorageAddress + for Address where - StorageKey: EncodeWithMetadata, + Keys: StorageMultiKey, ReturnTy: DecodeWithMetadata, { type Target = ReturnTy; @@ -152,78 +244,65 @@ where .entry_by_name(self.entry_name()) .ok_or_else(|| MetadataError::StorageEntryNotFound(self.entry_name().to_owned()))?; - match entry.entry_type() { - StorageEntryType::Plain(_) => { - if !self.storage_entry_keys.is_empty() { - Err(StorageAddressError::WrongNumberOfKeys { - expected: 0, - actual: self.storage_entry_keys.len(), - } - .into()) - } else { - Ok(()) - } + let keys_iter = self.keys.keys_iter(); + let keys_len = keys_iter.len(); + + if keys_len == 0 { + return Ok(()); + } + + let StorageEntryType::Map { + hashers, key_ty, .. + } = entry.entry_type() + else { + // Plain entries are only okay, if keys_len == 0, see early return above. + return Err(StorageAddressError::WrongNumberOfKeys { + expected: 0, + actual: keys_len, } - StorageEntryType::Map { - hashers, key_ty, .. - } => { - let ty = metadata - .types() - .resolve(*key_ty) - .ok_or(MetadataError::TypeNotFound(*key_ty))?; - - // If the provided keys are empty, the storage address must be - // equal to the storage root address. - if self.storage_entry_keys.is_empty() { - return Ok(()); - } - - // If the key is a tuple, we encode each value to the corresponding tuple type. - // If the key is not a tuple, encode a single value to the key type. - let type_ids = match &ty.type_def { - TypeDef::Tuple(tuple) => { - either::Either::Left(tuple.fields.iter().map(|f| f.id)) - } - _other => either::Either::Right(std::iter::once(*key_ty)), - }; - - if type_ids.len() < self.storage_entry_keys.len() { - // Provided more keys than fields. - return Err(StorageAddressError::WrongNumberOfKeys { - expected: type_ids.len(), - actual: self.storage_entry_keys.len(), - } - .into()); - } - - if hashers.len() == 1 { - // One hasher; hash a tuple of all SCALE encoded bytes with the one hash function. - let mut input = Vec::new(); - let iter = self.storage_entry_keys.iter().zip(type_ids); - for (key, type_id) in iter { - key.encode_with_metadata(type_id, metadata, &mut input)?; - } - hash_bytes(&input, &hashers[0], bytes); - Ok(()) - } else if hashers.len() >= type_ids.len() { - let iter = self.storage_entry_keys.iter().zip(type_ids).zip(hashers); - // A hasher per field; encode and hash each field independently. - for ((key, type_id), hasher) in iter { - let mut input = Vec::new(); - key.encode_with_metadata(type_id, metadata, &mut input)?; - hash_bytes(&input, hasher, bytes); - } - Ok(()) - } else { - // Provided more fields than hashers. - Err(StorageAddressError::WrongNumberOfHashers { - hashers: hashers.len(), - fields: type_ids.len(), - } - .into()) - } + .into()); + }; + + let ty = metadata + .types() + .resolve(*key_ty) + .ok_or(MetadataError::TypeNotFound(*key_ty))?; + + // If the key is a tuple, we encode each value to the corresponding tuple type. + // If the key is not a tuple, encode a single value to the key type. + let type_ids = match &ty.type_def { + TypeDef::Tuple(tuple) => either::Either::Left(tuple.fields.iter().map(|f| f.id)), + _other => either::Either::Right(std::iter::once(*key_ty)), + }; + + // Provided more fields than hashers: This is unacceptable (on the contrary, providing more hashers than keys is ok) + if hashers.len() < type_ids.len() { + return Err(StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: type_ids.len(), + } + .into()); + } + + if hashers.len() == 1 { + // One hasher; hash a tuple of all SCALE encoded bytes with the one hash function. + let mut input = Vec::new(); + let iter = keys_iter.zip(type_ids); + for (key, type_id) in iter { + key.encode_with_metadata(type_id, metadata, &mut input)?; + } + hash_bytes(&input, &hashers[0], bytes); + } else { + // A hasher per field; encode and hash each field independently. + let iter = keys_iter.zip(type_ids).zip(hashers); + for ((key, type_id), hasher) in iter { + let mut input = Vec::new(); + key.encode_with_metadata(type_id, metadata, &mut input)?; + hash_bytes(&input, hasher, bytes); } } + + Ok(()) } fn validation_hash(&self) -> Option<[u8; 32]> { @@ -242,11 +321,11 @@ pub fn make_static_storage_map_key(t: T) -> StaticStorageMapKe } /// Construct a new dynamic storage lookup. -pub fn dynamic( +pub fn dynamic( pallet_name: impl Into, entry_name: impl Into, - storage_entry_keys: Vec, -) -> DynamicAddress { + storage_entry_keys: Keys, +) -> DynamicAddress { DynamicAddress::new(pallet_name, entry_name, storage_entry_keys) } From 4f052d066113a80445ad544d03c1c56464faadc1 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Thu, 8 Feb 2024 15:37:36 +0100 Subject: [PATCH 02/39] decoding values from concat style hashers --- subxt/src/storage/storage_address.rs | 105 +++++++++++++++++++++------ 1 file changed, 82 insertions(+), 23 deletions(-) diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 86ff19bdfb..2237c38a2a 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -63,33 +63,64 @@ pub struct Address, } -#[derive(Derivative)] -#[derivative(Clone(bound = "K: Clone"), Debug(bound = "K: std::fmt::Debug"))] -pub enum StorageKey { - Encoded(Static), - Bare(K), -} +// #[derive(Derivative)] +// #[derivative(Clone(bound = "K: Clone"), Debug(bound = "K: std::fmt::Debug"))] +// pub enum StorageKey { +// Encoded(Static), +// Bare(K), +// } -impl StorageKey { - pub fn new_encoded(key_ty: &K) -> StorageKey { - StorageKey::Encoded(Static(Encoded(key_ty.encode()))) - } +// impl StorageKey { +// pub fn new_encoded(key_ty: &K) -> StorageKey { +// StorageKey::Encoded(Static(Encoded(key_ty.encode()))) +// } +// } + +// impl EncodeAsType for StorageKey { +// fn encode_as_type_to( +// &self, +// type_id: u32, +// types: &scale_info::PortableRegistry, +// out: &mut Vec, +// ) -> Result<(), scale_encode::Error> { +// match self { +// StorageKey::Encoded(e) => e.encode_as_type_to(type_id, types, out), +// StorageKey::Bare(e) => e.encode_as_type_to(type_id, types, out), +// } +// } +// } + +/// A storage key, mostly used for static encoded values. +/// The original value is only given during construction, but can be +pub struct StorageKey { + bytes: Static, + _marker: std::marker::PhantomData, } -impl EncodeAsType for StorageKey { - fn encode_as_type_to( - &self, - type_id: u32, - types: &scale_info::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - match self { - StorageKey::Encoded(e) => e.encode_as_type_to(type_id, types, out), - StorageKey::Bare(e) => e.encode_as_type_to(type_id, types, out), +impl StorageKey { + pub fn new(key: &K) -> Self { + StorageKey { + bytes: Static(Encoded(key.encode())), + _marker: std::marker::PhantomData, } } + + pub fn bytes(&self) -> &[u8] { + &self.bytes.0 .0 + } } +// impl EncodeAsType for StorageKey { +// fn encode_as_type_to( +// &self, +// type_id: u32, +// types: &scale_info::PortableRegistry, +// out: &mut Vec, +// ) -> Result<(), scale_encode::Error> { +// self.bytes.encode_as_type_to(type_id, types, out) +// } +// } + pub trait StorageMultiKey { fn keys_iter(&self) -> impl ExactSizeIterator; } @@ -107,11 +138,11 @@ impl StorageMultiKey for StorageKey { fn keys_iter(&self) -> impl ExactSizeIterator { // Note: this returns the storage root address of the storage entry. // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. - std::iter::once(self as &dyn EncodeAsType) + std::iter::once(&self.bytes as &dyn EncodeAsType) } } -impl StorageMultiKey for Vec> { +impl StorageMultiKey for Vec { fn keys_iter(&self) -> impl ExactSizeIterator { // Note: this returns the storage root address of the storage entry. // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. @@ -131,7 +162,7 @@ macro_rules! impl_tuples { impl<$($ty: EncodeAsType),+> StorageMultiKey for ($( StorageKey<$ty >),+) { fn keys_iter(&self) -> impl ExactSizeIterator { let arr = [$( - &self.$n as &dyn EncodeAsType + &self.$n.bytes as &dyn EncodeAsType ),+]; arr.into_iter() } @@ -158,6 +189,7 @@ const _: () = { pub type DynamicAddress = Address; impl DynamicAddress { + /// Creates a new dynamic address. As `Keys` you can use a `Vec` pub fn new(pallet_name: impl Into, entry_name: impl Into, keys: Keys) -> Self { Self { pallet_name: Cow::Owned(pallet_name.into()), @@ -347,3 +379,30 @@ fn hash_bytes(input: &[u8], hasher: &StorageHasher, bytes: &mut Vec) { } } } + +/// Tries to recover from the hash, the bytes of the value that was originially hashed. +/// Note: this only returns `Some(..)` for concat-style hashers. +pub fn value_bytes_from_hash_bytes<'a>(hash: &'a [u8], hasher: &StorageHasher) -> Option<&'a [u8]> { + match hasher { + StorageHasher::Blake2_128Concat => Some(&hash[16..0]), + StorageHasher::Twox64Concat => Some(&hash[8..0]), + StorageHasher::Blake2_128 + | StorageHasher::Blake2_256 + | StorageHasher::Twox128 + | StorageHasher::Twox256 + | StorageHasher::Identity => None, + } +} + +/// Tries to recover an encoded value from a concat-style hash. +pub fn value_from_hash_bytes( + hash: &[u8], + hasher: &StorageHasher, +) -> Option> { + let value_bytes = value_bytes_from_hash_bytes(hash, hasher)?; + let value = match V::decode(&mut &value_bytes[..]) { + Ok(value) => value, + Err(err) => return Some(Err(err.into())), + }; + Some(Ok(value)) +} From e4e44379af84845d3e93f4198cb89cdfe6609778 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Thu, 8 Feb 2024 17:19:51 +0100 Subject: [PATCH 03/39] move util functions and remove comments --- subxt/src/storage/storage_address.rs | 83 ++++------------------------ subxt/src/storage/utils.rs | 29 ++++++++++ 2 files changed, 39 insertions(+), 73 deletions(-) diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 2237c38a2a..c34adedb3f 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -12,7 +12,7 @@ use derivative::Derivative; use scale_encode::EncodeAsType; use scale_info::TypeDef; use std::borrow::Cow; -use subxt_metadata::{StorageEntryMetadata, StorageEntryType, StorageHasher}; +use subxt_metadata::{StorageEntryType, StorageHasher}; /// This represents a storage address. Anything implementing this trait /// can be used to fetch and iterate over storage entries. @@ -63,33 +63,6 @@ pub struct Address, } -// #[derive(Derivative)] -// #[derivative(Clone(bound = "K: Clone"), Debug(bound = "K: std::fmt::Debug"))] -// pub enum StorageKey { -// Encoded(Static), -// Bare(K), -// } - -// impl StorageKey { -// pub fn new_encoded(key_ty: &K) -> StorageKey { -// StorageKey::Encoded(Static(Encoded(key_ty.encode()))) -// } -// } - -// impl EncodeAsType for StorageKey { -// fn encode_as_type_to( -// &self, -// type_id: u32, -// types: &scale_info::PortableRegistry, -// out: &mut Vec, -// ) -> Result<(), scale_encode::Error> { -// match self { -// StorageKey::Encoded(e) => e.encode_as_type_to(type_id, types, out), -// StorageKey::Bare(e) => e.encode_as_type_to(type_id, types, out), -// } -// } -// } - /// A storage key, mostly used for static encoded values. /// The original value is only given during construction, but can be pub struct StorageKey { @@ -110,17 +83,6 @@ impl StorageKey { } } -// impl EncodeAsType for StorageKey { -// fn encode_as_type_to( -// &self, -// type_id: u32, -// types: &scale_info::PortableRegistry, -// out: &mut Vec, -// ) -> Result<(), scale_encode::Error> { -// self.bytes.encode_as_type_to(type_id, types, out) -// } -// } - pub trait StorageMultiKey { fn keys_iter(&self) -> impl ExactSizeIterator; } @@ -150,13 +112,15 @@ impl StorageMultiKey for Vec { } } -// impl StorageMultiKey for (StorageKey, StorageKey) { -// fn keys_iter(&self) -> impl ExactSizeIterator { -// let arr = [&self.0 as &dyn EncodeAsType, &self.1 as &dyn EncodeAsType]; -// arr.into_iter() -// } -// } - +/// Generates StorageMultiKey implementations for tuples, e.g. +/// ```rs,norun +/// impl StorageMultiKey for (StorageKey, StorageKey) { +/// fn keys_iter(&self) -> impl ExactSizeIterator { +/// let arr = [&self.0 as &dyn EncodeAsType, &self.1 as &dyn EncodeAsType]; +/// arr.into_iter() +/// } +/// } +/// ``` macro_rules! impl_tuples { ($($ty:ident $n:tt),+) => {{ impl<$($ty: EncodeAsType),+> StorageMultiKey for ($( StorageKey<$ty >),+) { @@ -379,30 +343,3 @@ fn hash_bytes(input: &[u8], hasher: &StorageHasher, bytes: &mut Vec) { } } } - -/// Tries to recover from the hash, the bytes of the value that was originially hashed. -/// Note: this only returns `Some(..)` for concat-style hashers. -pub fn value_bytes_from_hash_bytes<'a>(hash: &'a [u8], hasher: &StorageHasher) -> Option<&'a [u8]> { - match hasher { - StorageHasher::Blake2_128Concat => Some(&hash[16..0]), - StorageHasher::Twox64Concat => Some(&hash[8..0]), - StorageHasher::Blake2_128 - | StorageHasher::Blake2_256 - | StorageHasher::Twox128 - | StorageHasher::Twox256 - | StorageHasher::Identity => None, - } -} - -/// Tries to recover an encoded value from a concat-style hash. -pub fn value_from_hash_bytes( - hash: &[u8], - hasher: &StorageHasher, -) -> Option> { - let value_bytes = value_bytes_from_hash_bytes(hash, hasher)?; - let value = match V::decode(&mut &value_bytes[..]) { - Ok(value) => value, - Err(err) => return Some(Err(err.into())), - }; - Some(Ok(value)) -} diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index 728a581baf..93360c9a39 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -6,6 +6,8 @@ //! aren't things that should ever be overridden, and so don't exist on //! the trait itself. +use subxt_metadata::StorageHasher; + use super::StorageAddress; use crate::{error::Error, metadata::Metadata}; @@ -37,3 +39,30 @@ pub(crate) fn storage_address_root_bytes(addr: &Address write_storage_address_root_bytes(addr, &mut bytes); bytes } + +/// Tries to recover an encoded value from a concat-style hash. +pub fn recover_value_from_hash( + hash: &[u8], + hasher: &StorageHasher, +) -> Option> { + let value_bytes = value_bytes_from_hash_bytes(hash, hasher)?; + let value = match V::decode(&mut &value_bytes[..]) { + Ok(value) => value, + Err(err) => return Some(Err(err.into())), + }; + Some(Ok(value)) +} + +/// Tries to recover from the hash, the bytes of the value that was originially hashed. +/// Note: this only returns `Some(..)` for concat-style hashers. +fn value_bytes_from_hash_bytes<'a>(hash: &'a [u8], hasher: &StorageHasher) -> Option<&'a [u8]> { + match hasher { + StorageHasher::Blake2_128Concat => Some(&hash[16..0]), + StorageHasher::Twox64Concat => Some(&hash[8..0]), + StorageHasher::Blake2_128 + | StorageHasher::Blake2_256 + | StorageHasher::Twox128 + | StorageHasher::Twox256 + | StorageHasher::Identity => None, + } +} From 3f20d770dc653c23f41e5cfafa2b05d243b0fcc1 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Fri, 9 Feb 2024 09:47:47 +0100 Subject: [PATCH 04/39] change codegen for storage keys and fix examples --- codegen/src/api/storage.rs | 23 +- subxt/src/storage/mod.rs | 3 +- subxt/src/storage/storage_address.rs | 24 +- subxt/src/storage/utils.rs | 16 +- .../src/full_client/codegen/polkadot.rs | 2326 ++++++++--------- 5 files changed, 1123 insertions(+), 1269 deletions(-) diff --git a/codegen/src/api/storage.rs b/codegen/src/api/storage.rs index 9ea3832e94..41ebb4fd3e 100644 --- a/codegen/src/api/storage.rs +++ b/codegen/src/api/storage.rs @@ -148,7 +148,24 @@ fn generate_storage_entry_fns( }; let is_fetchable_type = is_fetchable.then_some(quote!(#crate_path::storage::address::Yes)).unwrap_or(quote!(())); let is_iterable_type = is_iterable.then_some(quote!(#crate_path::storage::address::Yes)).unwrap_or(quote!(())); - let key_impls = keys_slice.iter().map(|(field_name, _, _)| quote!( #crate_path::storage::address::make_static_storage_map_key(#field_name.borrow()) )); + let (keys, keys_type) = match keys_slice.len(){ + 0 => (quote!( () ), quote!( () )), + 1 => { + let field_name = &keys_slice[0].0; + let keys = quote!( #crate_path::storage::address::StorageKey::new(#field_name.borrow()) ); + let path = &keys_slice[0].2; + let path = quote!( #crate_path::storage::address::StorageKey<#path> ); + (keys, path) + } + _ => { + let keys_iter = keys_slice.iter().map(|(field_name, _, _)| quote!( #crate_path::storage::address::StorageKey::new(#field_name.borrow()) )); + let keys = quote!( (#(#keys_iter,)*) ); + let paths_iter = keys_slice.iter().map(|(_, _, path_to_alias)| quote!( #crate_path::storage::address::StorageKey<#path_to_alias> ) ); + let paths = quote!( (#(#paths_iter,)*) ); + (keys, paths) + } + }; + let key_args = keys_slice.iter().map(|(field_name, _, path_to_alias )| { quote!( #field_name: impl ::std::borrow::Borrow<#path_to_alias> ) }); @@ -159,7 +176,7 @@ fn generate_storage_entry_fns( &self, #(#key_args,)* ) -> #crate_path::storage::address::Address::< - #crate_path::storage::address::StaticStorageMapKey, + #keys_type, #alias_storage_path, #is_fetchable_type, #is_defaultable_type, @@ -168,7 +185,7 @@ fn generate_storage_entry_fns( #crate_path::storage::address::Address::new_static( #pallet_name, #storage_name, - vec![#(#key_impls,)*], + #keys, [#(#storage_hash,)*] ) } diff --git a/subxt/src/storage/mod.rs b/subxt/src/storage/mod.rs index 0219cd8caf..6307e88c06 100644 --- a/subxt/src/storage/mod.rs +++ b/subxt/src/storage/mod.rs @@ -18,8 +18,7 @@ pub use storage_type::Storage; /// entry lives and how to properly decode it. pub mod address { pub use super::storage_address::{ - dynamic, make_static_storage_map_key, Address, DynamicAddress, StaticStorageMapKey, - StorageAddress, Yes, + dynamic, Address, DynamicAddress, StorageAddress, StorageKey, Yes, }; } diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index c34adedb3f..709c2230e2 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -65,12 +65,13 @@ pub struct Address { +pub struct StorageKey { bytes: Static, _marker: std::marker::PhantomData, } -impl StorageKey { +impl StorageKey { + /// Creates a new static storage key pub fn new(key: &K) -> Self { StorageKey { bytes: Static(Encoded(key.encode())), @@ -78,12 +79,16 @@ impl StorageKey { } } + /// Returns the scale-encoded bytes that make up this key pub fn bytes(&self) -> &[u8] { &self.bytes.0 .0 } } +/// This trait should be implemented by anything that can be used as one or multiple storage keys. pub trait StorageMultiKey { + /// Iterator over the storage keys, each key implements EncodeAsType to + /// give the corresponding bytes to a `StorageHasher`. fn keys_iter(&self) -> impl ExactSizeIterator; } @@ -96,7 +101,8 @@ impl StorageMultiKey for () { } } -impl StorageMultiKey for StorageKey { +// Note: The ?Sized bound is necessary to support e.g. `StorageKey<[u8]>`. +impl StorageMultiKey for StorageKey { fn keys_iter(&self) -> impl ExactSizeIterator { // Note: this returns the storage root address of the storage entry. // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. @@ -123,7 +129,7 @@ impl StorageMultiKey for Vec { /// ``` macro_rules! impl_tuples { ($($ty:ident $n:tt),+) => {{ - impl<$($ty: EncodeAsType),+> StorageMultiKey for ($( StorageKey<$ty >),+) { + impl<$($ty: EncodeAsType + ?Sized),+> StorageMultiKey for ($( StorageKey<$ty >),+) { fn keys_iter(&self) -> impl ExactSizeIterator { let arr = [$( &self.$n.bytes as &dyn EncodeAsType @@ -306,16 +312,6 @@ where } } -/// A static storage key; this is some pre-encoded bytes -/// likely provided by the generated interface. -pub type StaticStorageMapKey = Static; - -// Used in codegen to construct the above. -#[doc(hidden)] -pub fn make_static_storage_map_key(t: T) -> StaticStorageMapKey { - Static(Encoded(t.encode())) -} - /// Construct a new dynamic storage lookup. pub fn dynamic( pallet_name: impl Into, diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index 93360c9a39..a78c75002a 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -57,8 +57,20 @@ pub fn recover_value_from_hash( /// Note: this only returns `Some(..)` for concat-style hashers. fn value_bytes_from_hash_bytes<'a>(hash: &'a [u8], hasher: &StorageHasher) -> Option<&'a [u8]> { match hasher { - StorageHasher::Blake2_128Concat => Some(&hash[16..0]), - StorageHasher::Twox64Concat => Some(&hash[8..0]), + StorageHasher::Blake2_128Concat => { + if hash.len() > 16 { + Some(&hash[16..]) + } else { + None + } + } + StorageHasher::Twox64Concat => { + if hash.len() > 8 { + Some(&hash[8..]) + } else { + None + } + } StorageHasher::Blake2_128 | StorageHasher::Blake2_256 | StorageHasher::Twox128 diff --git a/testing/integration-tests/src/full_client/codegen/polkadot.rs b/testing/integration-tests/src/full_client/codegen/polkadot.rs index 03502244c3..8a85d5fcab 100644 --- a/testing/integration-tests/src/full_client/codegen/polkadot.rs +++ b/testing/integration-tests/src/full_client/codegen/polkadot.rs @@ -4719,7 +4719,7 @@ pub mod api { pub fn account_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::account::Account, (), ::subxt::storage::address::Yes, @@ -4728,7 +4728,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "Account", - vec![], + (), [ 14u8, 233u8, 115u8, 214u8, 0u8, 109u8, 222u8, 121u8, 162u8, 65u8, 60u8, 175u8, 209u8, 79u8, 222u8, 124u8, 22u8, 235u8, 138u8, 176u8, 133u8, @@ -4741,7 +4741,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::account::Account, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4750,9 +4750,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "Account", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 14u8, 233u8, 115u8, 214u8, 0u8, 109u8, 222u8, 121u8, 162u8, 65u8, 60u8, 175u8, 209u8, 79u8, 222u8, 124u8, 22u8, 235u8, 138u8, 176u8, 133u8, @@ -4764,7 +4762,7 @@ pub mod api { pub fn extrinsic_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::extrinsic_count::ExtrinsicCount, ::subxt::storage::address::Yes, (), @@ -4773,7 +4771,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "ExtrinsicCount", - vec![], + (), [ 102u8, 76u8, 236u8, 42u8, 40u8, 231u8, 33u8, 222u8, 123u8, 147u8, 153u8, 148u8, 234u8, 203u8, 181u8, 119u8, 6u8, 187u8, 177u8, 199u8, @@ -4786,7 +4784,7 @@ pub mod api { pub fn block_weight( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::block_weight::BlockWeight, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4795,7 +4793,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "BlockWeight", - vec![], + (), [ 158u8, 46u8, 228u8, 89u8, 210u8, 214u8, 84u8, 154u8, 50u8, 68u8, 63u8, 62u8, 43u8, 42u8, 99u8, 27u8, 54u8, 42u8, 146u8, 44u8, 241u8, 216u8, @@ -4807,7 +4805,7 @@ pub mod api { pub fn all_extrinsics_len( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::all_extrinsics_len::AllExtrinsicsLen, ::subxt::storage::address::Yes, (), @@ -4816,7 +4814,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "AllExtrinsicsLen", - vec![], + (), [ 117u8, 86u8, 61u8, 243u8, 41u8, 51u8, 102u8, 214u8, 137u8, 100u8, 243u8, 185u8, 122u8, 174u8, 187u8, 117u8, 86u8, 189u8, 63u8, 135u8, @@ -4829,7 +4827,7 @@ pub mod api { pub fn block_hash_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::block_hash::BlockHash, (), ::subxt::storage::address::Yes, @@ -4838,7 +4836,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "BlockHash", - vec![], + (), [ 217u8, 32u8, 215u8, 253u8, 24u8, 182u8, 207u8, 178u8, 157u8, 24u8, 103u8, 100u8, 195u8, 165u8, 69u8, 152u8, 112u8, 181u8, 56u8, 192u8, @@ -4852,7 +4850,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::block_hash::BlockHash, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4861,9 +4859,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "BlockHash", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 217u8, 32u8, 215u8, 253u8, 24u8, 182u8, 207u8, 178u8, 157u8, 24u8, 103u8, 100u8, 195u8, 165u8, 69u8, 152u8, 112u8, 181u8, 56u8, 192u8, @@ -4876,7 +4872,7 @@ pub mod api { pub fn extrinsic_data_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::extrinsic_data::ExtrinsicData, (), ::subxt::storage::address::Yes, @@ -4885,7 +4881,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "ExtrinsicData", - vec![], + (), [ 160u8, 180u8, 122u8, 18u8, 196u8, 26u8, 2u8, 37u8, 115u8, 232u8, 133u8, 220u8, 106u8, 245u8, 4u8, 129u8, 42u8, 84u8, 241u8, 45u8, 199u8, 179u8, @@ -4898,7 +4894,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::extrinsic_data::ExtrinsicData, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4907,9 +4903,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "ExtrinsicData", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 160u8, 180u8, 122u8, 18u8, 196u8, 26u8, 2u8, 37u8, 115u8, 232u8, 133u8, 220u8, 106u8, 245u8, 4u8, 129u8, 42u8, 84u8, 241u8, 45u8, 199u8, 179u8, @@ -4921,7 +4915,7 @@ pub mod api { pub fn number( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::number::Number, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4930,7 +4924,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "Number", - vec![], + (), [ 30u8, 194u8, 177u8, 90u8, 194u8, 232u8, 46u8, 180u8, 85u8, 129u8, 14u8, 9u8, 8u8, 8u8, 23u8, 95u8, 230u8, 5u8, 13u8, 105u8, 125u8, 2u8, 22u8, @@ -4942,7 +4936,7 @@ pub mod api { pub fn parent_hash( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::parent_hash::ParentHash, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4951,7 +4945,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "ParentHash", - vec![], + (), [ 26u8, 130u8, 11u8, 216u8, 155u8, 71u8, 128u8, 170u8, 30u8, 153u8, 21u8, 192u8, 62u8, 93u8, 137u8, 80u8, 120u8, 81u8, 202u8, 94u8, 248u8, 125u8, @@ -4963,7 +4957,7 @@ pub mod api { pub fn digest( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::digest::Digest, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4972,7 +4966,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "Digest", - vec![], + (), [ 61u8, 64u8, 237u8, 91u8, 145u8, 232u8, 17u8, 254u8, 181u8, 16u8, 234u8, 91u8, 51u8, 140u8, 254u8, 131u8, 98u8, 135u8, 21u8, 37u8, 251u8, 20u8, @@ -4990,7 +4984,7 @@ pub mod api { pub fn events( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::events::Events, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4999,7 +4993,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "Events", - vec![], + (), [ 250u8, 105u8, 172u8, 217u8, 228u8, 110u8, 176u8, 187u8, 176u8, 96u8, 251u8, 246u8, 10u8, 91u8, 10u8, 130u8, 149u8, 248u8, 60u8, 2u8, 95u8, @@ -5012,7 +5006,7 @@ pub mod api { pub fn event_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::event_count::EventCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5021,7 +5015,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "EventCount", - vec![], + (), [ 175u8, 24u8, 252u8, 184u8, 210u8, 167u8, 146u8, 143u8, 164u8, 80u8, 151u8, 205u8, 189u8, 189u8, 55u8, 220u8, 47u8, 101u8, 181u8, 33u8, @@ -5043,7 +5037,7 @@ pub mod api { pub fn event_topics_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::event_topics::EventTopics, (), ::subxt::storage::address::Yes, @@ -5052,7 +5046,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "EventTopics", - vec![], + (), [ 40u8, 225u8, 14u8, 75u8, 44u8, 176u8, 76u8, 34u8, 143u8, 107u8, 69u8, 133u8, 114u8, 13u8, 172u8, 250u8, 141u8, 73u8, 12u8, 65u8, 217u8, 63u8, @@ -5074,7 +5068,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::event_topics::EventTopics, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5083,9 +5077,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "EventTopics", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 40u8, 225u8, 14u8, 75u8, 44u8, 176u8, 76u8, 34u8, 143u8, 107u8, 69u8, 133u8, 114u8, 13u8, 172u8, 250u8, 141u8, 73u8, 12u8, 65u8, 217u8, 63u8, @@ -5097,7 +5089,7 @@ pub mod api { pub fn last_runtime_upgrade( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::last_runtime_upgrade::LastRuntimeUpgrade, ::subxt::storage::address::Yes, (), @@ -5106,7 +5098,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "LastRuntimeUpgrade", - vec![], + (), [ 137u8, 29u8, 175u8, 75u8, 197u8, 208u8, 91u8, 207u8, 156u8, 87u8, 148u8, 68u8, 91u8, 140u8, 22u8, 233u8, 1u8, 229u8, 56u8, 34u8, 40u8, @@ -5118,7 +5110,7 @@ pub mod api { pub fn upgraded_to_u32_ref_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::upgraded_to_u32_ref_count::UpgradedToU32RefCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5127,7 +5119,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "UpgradedToU32RefCount", - vec![], + (), [ 229u8, 73u8, 9u8, 132u8, 186u8, 116u8, 151u8, 171u8, 145u8, 29u8, 34u8, 130u8, 52u8, 146u8, 124u8, 175u8, 79u8, 189u8, 147u8, 230u8, 234u8, @@ -5140,7 +5132,7 @@ pub mod api { pub fn upgraded_to_triple_ref_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::upgraded_to_triple_ref_count::UpgradedToTripleRefCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5149,7 +5141,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "UpgradedToTripleRefCount", - vec![], + (), [ 97u8, 66u8, 124u8, 243u8, 27u8, 167u8, 147u8, 81u8, 254u8, 201u8, 101u8, 24u8, 40u8, 231u8, 14u8, 179u8, 154u8, 163u8, 71u8, 81u8, 185u8, @@ -5162,7 +5154,7 @@ pub mod api { pub fn execution_phase( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::execution_phase::ExecutionPhase, ::subxt::storage::address::Yes, (), @@ -5171,7 +5163,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "ExecutionPhase", - vec![], + (), [ 191u8, 129u8, 100u8, 134u8, 126u8, 116u8, 154u8, 203u8, 220u8, 200u8, 0u8, 26u8, 161u8, 250u8, 133u8, 205u8, 146u8, 24u8, 5u8, 156u8, 158u8, @@ -5183,7 +5175,7 @@ pub mod api { pub fn authorized_upgrade( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::authorized_upgrade::AuthorizedUpgrade, ::subxt::storage::address::Yes, (), @@ -5192,7 +5184,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "AuthorizedUpgrade", - vec![], + (), [ 165u8, 97u8, 27u8, 138u8, 2u8, 28u8, 55u8, 92u8, 96u8, 96u8, 168u8, 169u8, 55u8, 178u8, 44u8, 127u8, 58u8, 140u8, 206u8, 178u8, 1u8, 37u8, @@ -5563,7 +5555,7 @@ pub mod api { pub fn epoch_index( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::epoch_index::EpochIndex, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5572,7 +5564,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "EpochIndex", - vec![], + (), [ 32u8, 82u8, 130u8, 31u8, 190u8, 162u8, 237u8, 189u8, 104u8, 244u8, 30u8, 199u8, 179u8, 0u8, 161u8, 107u8, 72u8, 240u8, 201u8, 222u8, @@ -5585,7 +5577,7 @@ pub mod api { pub fn authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::authorities::Authorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5594,7 +5586,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "Authorities", - vec![], + (), [ 67u8, 196u8, 244u8, 13u8, 246u8, 245u8, 198u8, 98u8, 81u8, 55u8, 182u8, 187u8, 214u8, 5u8, 181u8, 76u8, 251u8, 213u8, 144u8, 166u8, 36u8, @@ -5608,7 +5600,7 @@ pub mod api { pub fn genesis_slot( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::genesis_slot::GenesisSlot, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5617,7 +5609,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "GenesisSlot", - vec![], + (), [ 218u8, 174u8, 152u8, 76u8, 188u8, 214u8, 7u8, 88u8, 253u8, 187u8, 139u8, 234u8, 51u8, 28u8, 220u8, 57u8, 73u8, 1u8, 18u8, 205u8, 80u8, @@ -5630,7 +5622,7 @@ pub mod api { pub fn current_slot( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::current_slot::CurrentSlot, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5639,7 +5631,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "CurrentSlot", - vec![], + (), [ 112u8, 199u8, 115u8, 248u8, 217u8, 242u8, 45u8, 231u8, 178u8, 53u8, 236u8, 167u8, 219u8, 238u8, 81u8, 243u8, 39u8, 140u8, 68u8, 19u8, @@ -5661,7 +5653,7 @@ pub mod api { pub fn randomness( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::randomness::Randomness, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5670,7 +5662,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "Randomness", - vec![], + (), [ 36u8, 15u8, 52u8, 73u8, 195u8, 177u8, 186u8, 125u8, 134u8, 11u8, 103u8, 248u8, 170u8, 237u8, 105u8, 239u8, 168u8, 204u8, 147u8, 52u8, 15u8, @@ -5683,7 +5675,7 @@ pub mod api { pub fn pending_epoch_config_change( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pending_epoch_config_change::PendingEpochConfigChange, ::subxt::storage::address::Yes, (), @@ -5692,7 +5684,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "PendingEpochConfigChange", - vec![], + (), [ 79u8, 216u8, 84u8, 210u8, 83u8, 149u8, 122u8, 160u8, 159u8, 164u8, 16u8, 134u8, 154u8, 104u8, 77u8, 254u8, 139u8, 18u8, 163u8, 59u8, 92u8, @@ -5704,7 +5696,7 @@ pub mod api { pub fn next_randomness( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_randomness::NextRandomness, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5713,7 +5705,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "NextRandomness", - vec![], + (), [ 96u8, 191u8, 139u8, 171u8, 144u8, 92u8, 33u8, 58u8, 23u8, 219u8, 164u8, 121u8, 59u8, 209u8, 112u8, 244u8, 50u8, 8u8, 14u8, 244u8, 103u8, 125u8, @@ -5725,7 +5717,7 @@ pub mod api { pub fn next_authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_authorities::NextAuthorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5734,7 +5726,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "NextAuthorities", - vec![], + (), [ 116u8, 95u8, 126u8, 199u8, 237u8, 90u8, 202u8, 227u8, 247u8, 56u8, 201u8, 113u8, 239u8, 191u8, 151u8, 56u8, 156u8, 133u8, 61u8, 64u8, @@ -5755,7 +5747,7 @@ pub mod api { pub fn segment_index( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::segment_index::SegmentIndex, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5764,7 +5756,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "SegmentIndex", - vec![], + (), [ 145u8, 91u8, 142u8, 240u8, 184u8, 94u8, 68u8, 52u8, 130u8, 3u8, 75u8, 175u8, 155u8, 130u8, 66u8, 9u8, 150u8, 242u8, 123u8, 111u8, 124u8, @@ -5777,7 +5769,7 @@ pub mod api { pub fn under_construction_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::under_construction::UnderConstruction, (), ::subxt::storage::address::Yes, @@ -5786,7 +5778,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "UnderConstruction", - vec![], + (), [ 120u8, 120u8, 59u8, 247u8, 50u8, 6u8, 220u8, 14u8, 2u8, 76u8, 203u8, 244u8, 232u8, 144u8, 253u8, 191u8, 101u8, 35u8, 99u8, 85u8, 111u8, @@ -5799,7 +5791,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::under_construction::UnderConstruction, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5808,9 +5800,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "UnderConstruction", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 120u8, 120u8, 59u8, 247u8, 50u8, 6u8, 220u8, 14u8, 2u8, 76u8, 203u8, 244u8, 232u8, 144u8, 253u8, 191u8, 101u8, 35u8, 99u8, 85u8, 111u8, @@ -5823,7 +5813,7 @@ pub mod api { pub fn initialized( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::initialized::Initialized, ::subxt::storage::address::Yes, (), @@ -5832,7 +5822,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "Initialized", - vec![], + (), [ 169u8, 217u8, 237u8, 78u8, 186u8, 202u8, 206u8, 213u8, 54u8, 85u8, 206u8, 166u8, 22u8, 138u8, 236u8, 60u8, 211u8, 169u8, 12u8, 183u8, @@ -5848,7 +5838,7 @@ pub mod api { pub fn author_vrf_randomness( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::author_vrf_randomness::AuthorVrfRandomness, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5857,7 +5847,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "AuthorVrfRandomness", - vec![], + (), [ 160u8, 157u8, 62u8, 48u8, 196u8, 136u8, 63u8, 132u8, 155u8, 183u8, 91u8, 201u8, 146u8, 29u8, 192u8, 142u8, 168u8, 152u8, 197u8, 233u8, @@ -5874,7 +5864,7 @@ pub mod api { pub fn epoch_start( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::epoch_start::EpochStart, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5883,7 +5873,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "EpochStart", - vec![], + (), [ 144u8, 133u8, 140u8, 56u8, 241u8, 203u8, 199u8, 123u8, 244u8, 126u8, 196u8, 151u8, 214u8, 204u8, 243u8, 244u8, 210u8, 198u8, 174u8, 126u8, @@ -5900,7 +5890,7 @@ pub mod api { pub fn lateness( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::lateness::Lateness, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5909,7 +5899,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "Lateness", - vec![], + (), [ 229u8, 214u8, 133u8, 149u8, 32u8, 159u8, 26u8, 22u8, 252u8, 131u8, 200u8, 191u8, 231u8, 176u8, 178u8, 127u8, 33u8, 212u8, 139u8, 220u8, @@ -5923,7 +5913,7 @@ pub mod api { pub fn epoch_config( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::epoch_config::EpochConfig, ::subxt::storage::address::Yes, (), @@ -5932,7 +5922,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "EpochConfig", - vec![], + (), [ 151u8, 58u8, 93u8, 2u8, 19u8, 98u8, 41u8, 144u8, 241u8, 70u8, 195u8, 37u8, 126u8, 241u8, 111u8, 65u8, 16u8, 228u8, 111u8, 220u8, 241u8, @@ -5946,7 +5936,7 @@ pub mod api { pub fn next_epoch_config( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_epoch_config::NextEpochConfig, ::subxt::storage::address::Yes, (), @@ -5955,7 +5945,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "NextEpochConfig", - vec![], + (), [ 65u8, 54u8, 74u8, 141u8, 193u8, 124u8, 130u8, 238u8, 106u8, 27u8, 221u8, 189u8, 103u8, 53u8, 39u8, 243u8, 212u8, 216u8, 75u8, 185u8, @@ -5975,7 +5965,7 @@ pub mod api { pub fn skipped_epochs( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::skipped_epochs::SkippedEpochs, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5984,7 +5974,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "SkippedEpochs", - vec![], + (), [ 120u8, 167u8, 144u8, 97u8, 41u8, 216u8, 103u8, 90u8, 3u8, 86u8, 196u8, 35u8, 160u8, 150u8, 144u8, 233u8, 128u8, 35u8, 119u8, 66u8, 6u8, 63u8, @@ -6138,7 +6128,7 @@ pub mod api { pub fn now( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::now::Now, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -6147,7 +6137,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Timestamp", "Now", - vec![], + (), [ 44u8, 50u8, 80u8, 30u8, 195u8, 146u8, 123u8, 238u8, 8u8, 163u8, 187u8, 92u8, 61u8, 39u8, 51u8, 29u8, 173u8, 169u8, 217u8, 158u8, 85u8, 187u8, @@ -6162,7 +6152,7 @@ pub mod api { pub fn did_update( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::did_update::DidUpdate, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -6171,7 +6161,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Timestamp", "DidUpdate", - vec![], + (), [ 229u8, 175u8, 246u8, 102u8, 237u8, 158u8, 212u8, 229u8, 238u8, 214u8, 205u8, 160u8, 164u8, 252u8, 195u8, 75u8, 139u8, 110u8, 22u8, 34u8, @@ -6522,7 +6512,7 @@ pub mod api { pub fn accounts_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::accounts::Accounts, (), (), @@ -6531,7 +6521,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Indices", "Accounts", - vec![], + (), [ 48u8, 189u8, 43u8, 119u8, 32u8, 168u8, 28u8, 12u8, 245u8, 81u8, 119u8, 182u8, 23u8, 201u8, 33u8, 147u8, 128u8, 171u8, 155u8, 134u8, 71u8, @@ -6545,7 +6535,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::accounts::Accounts, ::subxt::storage::address::Yes, (), @@ -6554,9 +6544,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Indices", "Accounts", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 48u8, 189u8, 43u8, 119u8, 32u8, 168u8, 28u8, 12u8, 245u8, 81u8, 119u8, 182u8, 23u8, 201u8, 33u8, 147u8, 128u8, 171u8, 155u8, 134u8, 71u8, @@ -7478,7 +7466,7 @@ pub mod api { pub fn total_issuance( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::total_issuance::TotalIssuance, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7487,7 +7475,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "TotalIssuance", - vec![], + (), [ 116u8, 70u8, 119u8, 194u8, 69u8, 37u8, 116u8, 206u8, 171u8, 70u8, 171u8, 210u8, 226u8, 111u8, 184u8, 204u8, 206u8, 11u8, 68u8, 72u8, @@ -7500,7 +7488,7 @@ pub mod api { pub fn inactive_issuance( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::inactive_issuance::InactiveIssuance, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7509,7 +7497,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "InactiveIssuance", - vec![], + (), [ 212u8, 185u8, 19u8, 50u8, 250u8, 72u8, 173u8, 50u8, 4u8, 104u8, 161u8, 249u8, 77u8, 247u8, 204u8, 248u8, 11u8, 18u8, 57u8, 4u8, 82u8, 110u8, @@ -7544,7 +7532,7 @@ pub mod api { pub fn account_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::account::Account, (), ::subxt::storage::address::Yes, @@ -7553,7 +7541,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Account", - vec![], + (), [ 213u8, 38u8, 200u8, 69u8, 218u8, 0u8, 112u8, 181u8, 160u8, 23u8, 96u8, 90u8, 3u8, 88u8, 126u8, 22u8, 103u8, 74u8, 64u8, 69u8, 29u8, 247u8, @@ -7589,7 +7577,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::account::Account, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7598,9 +7586,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Account", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 213u8, 38u8, 200u8, 69u8, 218u8, 0u8, 112u8, 181u8, 160u8, 23u8, 96u8, 90u8, 3u8, 88u8, 126u8, 22u8, 103u8, 74u8, 64u8, 69u8, 29u8, 247u8, @@ -7613,7 +7599,7 @@ pub mod api { pub fn locks_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::locks::Locks, (), ::subxt::storage::address::Yes, @@ -7622,7 +7608,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Locks", - vec![], + (), [ 10u8, 223u8, 55u8, 0u8, 249u8, 69u8, 168u8, 41u8, 75u8, 35u8, 120u8, 167u8, 18u8, 132u8, 9u8, 20u8, 91u8, 51u8, 27u8, 69u8, 136u8, 187u8, @@ -7636,7 +7622,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::locks::Locks, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7645,9 +7631,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Locks", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 10u8, 223u8, 55u8, 0u8, 249u8, 69u8, 168u8, 41u8, 75u8, 35u8, 120u8, 167u8, 18u8, 132u8, 9u8, 20u8, 91u8, 51u8, 27u8, 69u8, 136u8, 187u8, @@ -7659,7 +7643,7 @@ pub mod api { pub fn reserves_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::reserves::Reserves, (), ::subxt::storage::address::Yes, @@ -7668,7 +7652,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Reserves", - vec![], + (), [ 112u8, 10u8, 241u8, 77u8, 64u8, 187u8, 106u8, 159u8, 13u8, 153u8, 140u8, 178u8, 182u8, 50u8, 1u8, 55u8, 149u8, 92u8, 196u8, 229u8, 170u8, @@ -7681,7 +7665,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::reserves::Reserves, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7690,9 +7674,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Reserves", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 112u8, 10u8, 241u8, 77u8, 64u8, 187u8, 106u8, 159u8, 13u8, 153u8, 140u8, 178u8, 182u8, 50u8, 1u8, 55u8, 149u8, 92u8, 196u8, 229u8, 170u8, @@ -7704,7 +7686,7 @@ pub mod api { pub fn holds_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::holds::Holds, (), ::subxt::storage::address::Yes, @@ -7713,7 +7695,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Holds", - vec![], + (), [ 181u8, 39u8, 29u8, 45u8, 45u8, 198u8, 129u8, 210u8, 189u8, 183u8, 121u8, 125u8, 57u8, 90u8, 95u8, 107u8, 51u8, 13u8, 22u8, 105u8, 191u8, @@ -7727,7 +7709,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::holds::Holds, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7736,9 +7718,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Holds", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 181u8, 39u8, 29u8, 45u8, 45u8, 198u8, 129u8, 210u8, 189u8, 183u8, 121u8, 125u8, 57u8, 90u8, 95u8, 107u8, 51u8, 13u8, 22u8, 105u8, 191u8, @@ -7751,7 +7731,7 @@ pub mod api { pub fn freezes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::freezes::Freezes, (), ::subxt::storage::address::Yes, @@ -7760,7 +7740,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Freezes", - vec![], + (), [ 69u8, 49u8, 165u8, 76u8, 135u8, 142u8, 179u8, 118u8, 50u8, 109u8, 53u8, 112u8, 110u8, 94u8, 30u8, 93u8, 173u8, 38u8, 27u8, 142u8, 19u8, 5u8, @@ -7773,7 +7753,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::freezes::Freezes, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7782,9 +7762,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Freezes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 69u8, 49u8, 165u8, 76u8, 135u8, 142u8, 179u8, 118u8, 50u8, 109u8, 53u8, 112u8, 110u8, 94u8, 30u8, 93u8, 173u8, 38u8, 27u8, 142u8, 19u8, 5u8, @@ -7929,7 +7907,7 @@ pub mod api { pub fn next_fee_multiplier( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_fee_multiplier::NextFeeMultiplier, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7938,7 +7916,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "TransactionPayment", "NextFeeMultiplier", - vec![], + (), [ 247u8, 39u8, 81u8, 170u8, 225u8, 226u8, 82u8, 147u8, 34u8, 113u8, 147u8, 213u8, 59u8, 80u8, 139u8, 35u8, 36u8, 196u8, 152u8, 19u8, 9u8, @@ -7950,7 +7928,7 @@ pub mod api { pub fn storage_version( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::storage_version::StorageVersion, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7959,7 +7937,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "TransactionPayment", "StorageVersion", - vec![], + (), [ 105u8, 243u8, 158u8, 241u8, 159u8, 231u8, 253u8, 6u8, 4u8, 32u8, 85u8, 178u8, 126u8, 31u8, 203u8, 134u8, 154u8, 38u8, 122u8, 155u8, 150u8, @@ -8030,7 +8008,7 @@ pub mod api { pub fn author( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::author::Author, ::subxt::storage::address::Yes, (), @@ -8039,7 +8017,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Authorship", "Author", - vec![], + (), [ 247u8, 192u8, 118u8, 227u8, 47u8, 20u8, 203u8, 199u8, 216u8, 87u8, 220u8, 50u8, 166u8, 61u8, 168u8, 213u8, 253u8, 62u8, 202u8, 199u8, @@ -8110,7 +8088,7 @@ pub mod api { pub fn reports_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::reports::Reports, (), (), @@ -8119,7 +8097,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Offences", "Reports", - vec![], + (), [ 255u8, 234u8, 162u8, 48u8, 243u8, 210u8, 198u8, 231u8, 218u8, 142u8, 167u8, 10u8, 232u8, 223u8, 239u8, 55u8, 74u8, 23u8, 14u8, 236u8, 88u8, @@ -8133,7 +8111,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::reports::Reports, ::subxt::storage::address::Yes, (), @@ -8142,9 +8120,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Offences", "Reports", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 255u8, 234u8, 162u8, 48u8, 243u8, 210u8, 198u8, 231u8, 218u8, 142u8, 167u8, 10u8, 232u8, 223u8, 239u8, 55u8, 74u8, 23u8, 14u8, 236u8, 88u8, @@ -8157,7 +8133,7 @@ pub mod api { pub fn concurrent_reports_index_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::concurrent_reports_index::ConcurrentReportsIndex, (), ::subxt::storage::address::Yes, @@ -8166,7 +8142,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Offences", "ConcurrentReportsIndex", - vec![], + (), [ 170u8, 186u8, 72u8, 29u8, 251u8, 38u8, 193u8, 195u8, 109u8, 86u8, 0u8, 241u8, 20u8, 235u8, 108u8, 126u8, 215u8, 82u8, 73u8, 113u8, 199u8, @@ -8180,7 +8156,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::concurrent_reports_index::ConcurrentReportsIndex, (), ::subxt::storage::address::Yes, @@ -8189,9 +8165,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Offences", "ConcurrentReportsIndex", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 170u8, 186u8, 72u8, 29u8, 251u8, 38u8, 193u8, 195u8, 109u8, 86u8, 0u8, 241u8, 20u8, 235u8, 108u8, 126u8, 215u8, 82u8, 73u8, 113u8, 199u8, @@ -8206,7 +8180,14 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey< + types::concurrent_reports_index::Param0, + >, + ::subxt::storage::address::StorageKey< + types::concurrent_reports_index::Param1, + >, + ), types::concurrent_reports_index::ConcurrentReportsIndex, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8215,10 +8196,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Offences", "ConcurrentReportsIndex", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 170u8, 186u8, 72u8, 29u8, 251u8, 38u8, 193u8, 195u8, 109u8, 86u8, 0u8, 241u8, 20u8, 235u8, 108u8, 126u8, 215u8, 82u8, 73u8, 113u8, 199u8, @@ -8253,7 +8234,7 @@ pub mod api { pub fn historical_sessions_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::historical_sessions::HistoricalSessions, (), (), @@ -8262,7 +8243,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Historical", "HistoricalSessions", - vec![], + (), [ 9u8, 138u8, 247u8, 141u8, 178u8, 146u8, 124u8, 81u8, 162u8, 211u8, 205u8, 149u8, 222u8, 254u8, 253u8, 188u8, 170u8, 242u8, 218u8, 41u8, @@ -8276,7 +8257,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::historical_sessions::HistoricalSessions, ::subxt::storage::address::Yes, (), @@ -8285,9 +8266,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Historical", "HistoricalSessions", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 9u8, 138u8, 247u8, 141u8, 178u8, 146u8, 124u8, 81u8, 162u8, 211u8, 205u8, 149u8, 222u8, 254u8, 253u8, 188u8, 170u8, 242u8, 218u8, 41u8, @@ -8300,7 +8279,7 @@ pub mod api { pub fn stored_range( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::stored_range::StoredRange, ::subxt::storage::address::Yes, (), @@ -8309,7 +8288,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Historical", "StoredRange", - vec![], + (), [ 134u8, 32u8, 250u8, 13u8, 201u8, 25u8, 54u8, 243u8, 231u8, 81u8, 252u8, 231u8, 68u8, 217u8, 235u8, 43u8, 22u8, 223u8, 220u8, 133u8, 198u8, @@ -8516,7 +8495,7 @@ pub mod api { pub fn authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::authorities::Authorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8525,7 +8504,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "Authorities", - vec![], + (), [ 53u8, 171u8, 94u8, 33u8, 46u8, 83u8, 105u8, 120u8, 123u8, 201u8, 141u8, 71u8, 131u8, 150u8, 51u8, 121u8, 67u8, 45u8, 249u8, 146u8, 85u8, 113u8, @@ -8537,7 +8516,7 @@ pub mod api { pub fn validator_set_id( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::validator_set_id::ValidatorSetId, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8546,7 +8525,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "ValidatorSetId", - vec![], + (), [ 168u8, 84u8, 23u8, 134u8, 153u8, 30u8, 183u8, 176u8, 206u8, 100u8, 109u8, 86u8, 109u8, 126u8, 146u8, 175u8, 173u8, 1u8, 253u8, 42u8, @@ -8559,7 +8538,7 @@ pub mod api { pub fn next_authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_authorities::NextAuthorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8568,7 +8547,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "NextAuthorities", - vec![], + (), [ 87u8, 180u8, 0u8, 85u8, 209u8, 13u8, 131u8, 103u8, 8u8, 226u8, 42u8, 72u8, 38u8, 47u8, 190u8, 78u8, 62u8, 4u8, 161u8, 130u8, 87u8, 196u8, @@ -8589,7 +8568,7 @@ pub mod api { pub fn set_id_session_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::set_id_session::SetIdSession, (), (), @@ -8598,7 +8577,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "SetIdSession", - vec![], + (), [ 47u8, 0u8, 239u8, 121u8, 187u8, 213u8, 254u8, 50u8, 238u8, 10u8, 162u8, 65u8, 189u8, 166u8, 37u8, 74u8, 82u8, 81u8, 160u8, 20u8, 180u8, 253u8, @@ -8620,7 +8599,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::set_id_session::SetIdSession, ::subxt::storage::address::Yes, (), @@ -8629,9 +8608,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "SetIdSession", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 47u8, 0u8, 239u8, 121u8, 187u8, 213u8, 254u8, 50u8, 238u8, 10u8, 162u8, 65u8, 189u8, 166u8, 37u8, 74u8, 82u8, 81u8, 160u8, 20u8, 180u8, 253u8, @@ -8645,7 +8622,7 @@ pub mod api { pub fn genesis_block( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::genesis_block::GenesisBlock, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8654,7 +8631,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "GenesisBlock", - vec![], + (), [ 198u8, 155u8, 11u8, 240u8, 189u8, 245u8, 159u8, 127u8, 55u8, 33u8, 48u8, 29u8, 209u8, 119u8, 163u8, 24u8, 28u8, 22u8, 163u8, 163u8, 124u8, @@ -8748,7 +8725,7 @@ pub mod api { pub fn root_hash( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::root_hash::RootHash, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8757,7 +8734,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "RootHash", - vec![], + (), [ 111u8, 206u8, 173u8, 92u8, 67u8, 49u8, 150u8, 113u8, 90u8, 245u8, 38u8, 254u8, 76u8, 250u8, 167u8, 66u8, 130u8, 129u8, 251u8, 220u8, 172u8, @@ -8769,7 +8746,7 @@ pub mod api { pub fn number_of_leaves( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::number_of_leaves::NumberOfLeaves, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8778,7 +8755,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "NumberOfLeaves", - vec![], + (), [ 123u8, 58u8, 149u8, 174u8, 85u8, 45u8, 20u8, 115u8, 241u8, 0u8, 51u8, 174u8, 234u8, 60u8, 230u8, 59u8, 237u8, 144u8, 170u8, 32u8, 4u8, 0u8, @@ -8793,7 +8770,7 @@ pub mod api { pub fn nodes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::nodes::Nodes, (), (), @@ -8802,7 +8779,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "Nodes", - vec![], + (), [ 27u8, 84u8, 41u8, 195u8, 146u8, 81u8, 211u8, 189u8, 63u8, 125u8, 173u8, 206u8, 69u8, 198u8, 202u8, 213u8, 89u8, 31u8, 89u8, 177u8, 76u8, 154u8, @@ -8818,7 +8795,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::nodes::Nodes, ::subxt::storage::address::Yes, (), @@ -8827,9 +8804,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "Nodes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 27u8, 84u8, 41u8, 195u8, 146u8, 81u8, 211u8, 189u8, 63u8, 125u8, 173u8, 206u8, 69u8, 198u8, 202u8, 213u8, 89u8, 31u8, 89u8, 177u8, 76u8, 154u8, @@ -8868,7 +8843,7 @@ pub mod api { pub fn beefy_authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::beefy_authorities::BeefyAuthorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8877,7 +8852,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MmrLeaf", "BeefyAuthorities", - vec![], + (), [ 128u8, 35u8, 176u8, 79u8, 224u8, 58u8, 214u8, 234u8, 231u8, 71u8, 227u8, 153u8, 180u8, 189u8, 66u8, 44u8, 47u8, 174u8, 0u8, 83u8, 121u8, @@ -8892,7 +8867,7 @@ pub mod api { pub fn beefy_next_authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::beefy_next_authorities::BeefyNextAuthorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -8901,7 +8876,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MmrLeaf", "BeefyNextAuthorities", - vec![], + (), [ 97u8, 71u8, 52u8, 111u8, 120u8, 251u8, 183u8, 155u8, 177u8, 100u8, 236u8, 142u8, 204u8, 117u8, 95u8, 40u8, 201u8, 36u8, 32u8, 82u8, 38u8, @@ -9075,7 +9050,7 @@ pub mod api { pub fn validators( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::validators::Validators, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9084,7 +9059,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "Validators", - vec![], + (), [ 50u8, 86u8, 154u8, 222u8, 249u8, 209u8, 156u8, 22u8, 155u8, 25u8, 133u8, 194u8, 210u8, 50u8, 38u8, 28u8, 139u8, 201u8, 90u8, 139u8, @@ -9097,7 +9072,7 @@ pub mod api { pub fn current_index( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::current_index::CurrentIndex, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9106,7 +9081,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "CurrentIndex", - vec![], + (), [ 167u8, 151u8, 125u8, 150u8, 159u8, 21u8, 78u8, 217u8, 237u8, 183u8, 135u8, 65u8, 187u8, 114u8, 188u8, 206u8, 16u8, 32u8, 69u8, 208u8, @@ -9120,7 +9095,7 @@ pub mod api { pub fn queued_changed( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::queued_changed::QueuedChanged, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9129,7 +9104,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "QueuedChanged", - vec![], + (), [ 184u8, 137u8, 224u8, 137u8, 31u8, 236u8, 95u8, 164u8, 102u8, 225u8, 198u8, 227u8, 140u8, 37u8, 113u8, 57u8, 59u8, 4u8, 202u8, 102u8, 117u8, @@ -9143,7 +9118,7 @@ pub mod api { pub fn queued_keys( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::queued_keys::QueuedKeys, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9152,7 +9127,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "QueuedKeys", - vec![], + (), [ 123u8, 8u8, 241u8, 219u8, 141u8, 50u8, 254u8, 247u8, 130u8, 71u8, 105u8, 18u8, 149u8, 204u8, 28u8, 104u8, 184u8, 6u8, 165u8, 31u8, 153u8, @@ -9169,7 +9144,7 @@ pub mod api { pub fn disabled_validators( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::disabled_validators::DisabledValidators, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9178,7 +9153,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "DisabledValidators", - vec![], + (), [ 213u8, 19u8, 168u8, 234u8, 187u8, 200u8, 180u8, 97u8, 234u8, 189u8, 36u8, 233u8, 158u8, 184u8, 45u8, 35u8, 129u8, 213u8, 133u8, 8u8, 104u8, @@ -9190,7 +9165,7 @@ pub mod api { pub fn next_keys_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_keys::NextKeys, (), (), @@ -9199,7 +9174,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "NextKeys", - vec![], + (), [ 13u8, 219u8, 184u8, 220u8, 199u8, 150u8, 34u8, 166u8, 125u8, 46u8, 26u8, 160u8, 113u8, 243u8, 227u8, 6u8, 121u8, 176u8, 222u8, 250u8, @@ -9213,7 +9188,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::next_keys::NextKeys, ::subxt::storage::address::Yes, (), @@ -9222,9 +9197,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "NextKeys", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 13u8, 219u8, 184u8, 220u8, 199u8, 150u8, 34u8, 166u8, 125u8, 46u8, 26u8, 160u8, 113u8, 243u8, 227u8, 6u8, 121u8, 176u8, 222u8, 250u8, @@ -9237,7 +9210,7 @@ pub mod api { pub fn key_owner_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::key_owner::KeyOwner, (), (), @@ -9246,7 +9219,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "KeyOwner", - vec![], + (), [ 217u8, 204u8, 21u8, 114u8, 247u8, 129u8, 32u8, 242u8, 93u8, 91u8, 253u8, 253u8, 248u8, 90u8, 12u8, 202u8, 195u8, 25u8, 18u8, 100u8, @@ -9260,7 +9233,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::key_owner::KeyOwner, (), (), @@ -9269,9 +9242,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "KeyOwner", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 217u8, 204u8, 21u8, 114u8, 247u8, 129u8, 32u8, 242u8, 93u8, 91u8, 253u8, 253u8, 248u8, 90u8, 12u8, 202u8, 195u8, 25u8, 18u8, 100u8, @@ -9286,7 +9257,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::key_owner::KeyOwner, ::subxt::storage::address::Yes, (), @@ -9295,10 +9269,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "KeyOwner", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 217u8, 204u8, 21u8, 114u8, 247u8, 129u8, 32u8, 242u8, 93u8, 91u8, 253u8, 253u8, 248u8, 90u8, 12u8, 202u8, 195u8, 25u8, 18u8, 100u8, @@ -9578,7 +9552,7 @@ pub mod api { pub fn state( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::state::State, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9587,7 +9561,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "State", - vec![], + (), [ 73u8, 71u8, 112u8, 83u8, 238u8, 75u8, 44u8, 9u8, 180u8, 33u8, 30u8, 121u8, 98u8, 96u8, 61u8, 133u8, 16u8, 70u8, 30u8, 249u8, 34u8, 148u8, @@ -9599,7 +9573,7 @@ pub mod api { pub fn pending_change( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pending_change::PendingChange, ::subxt::storage::address::Yes, (), @@ -9608,7 +9582,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "PendingChange", - vec![], + (), [ 150u8, 194u8, 185u8, 248u8, 239u8, 43u8, 141u8, 253u8, 61u8, 106u8, 74u8, 164u8, 209u8, 204u8, 206u8, 200u8, 32u8, 38u8, 11u8, 78u8, 84u8, @@ -9621,7 +9595,7 @@ pub mod api { pub fn next_forced( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_forced::NextForced, ::subxt::storage::address::Yes, (), @@ -9630,7 +9604,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "NextForced", - vec![], + (), [ 3u8, 231u8, 56u8, 18u8, 87u8, 112u8, 227u8, 126u8, 180u8, 131u8, 255u8, 141u8, 82u8, 34u8, 61u8, 47u8, 234u8, 37u8, 95u8, 62u8, 33u8, 235u8, @@ -9642,7 +9616,7 @@ pub mod api { pub fn stalled( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::stalled::Stalled, ::subxt::storage::address::Yes, (), @@ -9651,7 +9625,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "Stalled", - vec![], + (), [ 6u8, 81u8, 205u8, 142u8, 195u8, 48u8, 0u8, 247u8, 108u8, 170u8, 10u8, 249u8, 72u8, 206u8, 32u8, 103u8, 109u8, 57u8, 51u8, 21u8, 144u8, 204u8, @@ -9664,7 +9638,7 @@ pub mod api { pub fn current_set_id( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::current_set_id::CurrentSetId, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9673,7 +9647,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "CurrentSetId", - vec![], + (), [ 234u8, 215u8, 218u8, 42u8, 30u8, 76u8, 129u8, 40u8, 125u8, 137u8, 207u8, 47u8, 46u8, 213u8, 159u8, 50u8, 175u8, 81u8, 155u8, 123u8, @@ -9695,7 +9669,7 @@ pub mod api { pub fn set_id_session_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::set_id_session::SetIdSession, (), (), @@ -9704,7 +9678,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "SetIdSession", - vec![], + (), [ 47u8, 0u8, 239u8, 121u8, 187u8, 213u8, 254u8, 50u8, 238u8, 10u8, 162u8, 65u8, 189u8, 166u8, 37u8, 74u8, 82u8, 81u8, 160u8, 20u8, 180u8, 253u8, @@ -9726,7 +9700,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::set_id_session::SetIdSession, ::subxt::storage::address::Yes, (), @@ -9735,9 +9709,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "SetIdSession", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 47u8, 0u8, 239u8, 121u8, 187u8, 213u8, 254u8, 50u8, 238u8, 10u8, 162u8, 65u8, 189u8, 166u8, 37u8, 74u8, 82u8, 81u8, 160u8, 20u8, 180u8, 253u8, @@ -9749,7 +9721,7 @@ pub mod api { pub fn authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::authorities::Authorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9758,7 +9730,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "Authorities", - vec![], + (), [ 67u8, 196u8, 244u8, 13u8, 246u8, 245u8, 198u8, 98u8, 81u8, 55u8, 182u8, 187u8, 214u8, 5u8, 181u8, 76u8, 251u8, 213u8, 144u8, 166u8, 36u8, @@ -9854,7 +9826,7 @@ pub mod api { pub fn keys( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::keys::Keys, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9863,7 +9835,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AuthorityDiscovery", "Keys", - vec![], + (), [ 111u8, 104u8, 188u8, 46u8, 152u8, 140u8, 137u8, 244u8, 52u8, 214u8, 115u8, 156u8, 39u8, 239u8, 15u8, 168u8, 193u8, 125u8, 57u8, 195u8, @@ -9876,7 +9848,7 @@ pub mod api { pub fn next_keys( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_keys::NextKeys, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -9885,7 +9857,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AuthorityDiscovery", "NextKeys", - vec![], + (), [ 171u8, 107u8, 15u8, 108u8, 125u8, 102u8, 193u8, 240u8, 127u8, 160u8, 53u8, 1u8, 208u8, 36u8, 134u8, 4u8, 216u8, 26u8, 156u8, 143u8, 154u8, @@ -10680,7 +10652,7 @@ pub mod api { pub fn proposal_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::proposal_count::ProposalCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -10689,7 +10661,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "ProposalCount", - vec![], + (), [ 91u8, 238u8, 246u8, 106u8, 95u8, 66u8, 83u8, 134u8, 1u8, 225u8, 164u8, 216u8, 113u8, 101u8, 203u8, 200u8, 113u8, 97u8, 246u8, 228u8, 140u8, @@ -10701,7 +10673,7 @@ pub mod api { pub fn proposals_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::proposals::Proposals, (), (), @@ -10710,7 +10682,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "Proposals", - vec![], + (), [ 207u8, 135u8, 145u8, 146u8, 48u8, 10u8, 252u8, 40u8, 20u8, 115u8, 205u8, 41u8, 173u8, 83u8, 115u8, 46u8, 106u8, 40u8, 130u8, 157u8, @@ -10724,7 +10696,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::proposals::Proposals, ::subxt::storage::address::Yes, (), @@ -10733,9 +10705,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "Proposals", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 207u8, 135u8, 145u8, 146u8, 48u8, 10u8, 252u8, 40u8, 20u8, 115u8, 205u8, 41u8, 173u8, 83u8, 115u8, 46u8, 106u8, 40u8, 130u8, 157u8, @@ -10748,7 +10718,7 @@ pub mod api { pub fn deactivated( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::deactivated::Deactivated, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -10757,7 +10727,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "Deactivated", - vec![], + (), [ 120u8, 221u8, 159u8, 56u8, 161u8, 44u8, 54u8, 233u8, 47u8, 114u8, 170u8, 150u8, 52u8, 24u8, 137u8, 212u8, 122u8, 247u8, 40u8, 17u8, @@ -10770,7 +10740,7 @@ pub mod api { pub fn approvals( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::approvals::Approvals, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -10779,7 +10749,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "Approvals", - vec![], + (), [ 78u8, 147u8, 186u8, 235u8, 17u8, 40u8, 247u8, 235u8, 67u8, 222u8, 3u8, 14u8, 248u8, 17u8, 67u8, 180u8, 93u8, 161u8, 64u8, 35u8, 119u8, 194u8, @@ -10791,7 +10761,7 @@ pub mod api { pub fn spend_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::spend_count::SpendCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -10800,7 +10770,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "SpendCount", - vec![], + (), [ 220u8, 74u8, 248u8, 52u8, 243u8, 209u8, 42u8, 236u8, 27u8, 98u8, 76u8, 153u8, 129u8, 176u8, 34u8, 177u8, 33u8, 132u8, 21u8, 71u8, 206u8, @@ -10813,7 +10783,7 @@ pub mod api { pub fn spends_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::spends::Spends, (), (), @@ -10822,7 +10792,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "Spends", - vec![], + (), [ 207u8, 104u8, 63u8, 103u8, 177u8, 66u8, 236u8, 100u8, 122u8, 213u8, 125u8, 153u8, 180u8, 219u8, 124u8, 22u8, 88u8, 161u8, 188u8, 197u8, @@ -10836,7 +10806,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::spends::Spends, ::subxt::storage::address::Yes, (), @@ -10845,9 +10815,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "Spends", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 207u8, 104u8, 63u8, 103u8, 177u8, 66u8, 236u8, 100u8, 122u8, 213u8, 125u8, 153u8, 180u8, 219u8, 124u8, 22u8, 88u8, 161u8, 188u8, 197u8, @@ -11347,7 +11315,7 @@ pub mod api { pub fn voting_for_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::voting_for::VotingFor, (), ::subxt::storage::address::Yes, @@ -11356,7 +11324,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ConvictionVoting", "VotingFor", - vec![], + (), [ 76u8, 63u8, 153u8, 193u8, 39u8, 137u8, 186u8, 29u8, 202u8, 56u8, 169u8, 56u8, 103u8, 138u8, 192u8, 18u8, 179u8, 114u8, 56u8, 121u8, 197u8, @@ -11370,7 +11338,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::voting_for::VotingFor, (), ::subxt::storage::address::Yes, @@ -11379,9 +11347,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ConvictionVoting", "VotingFor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 76u8, 63u8, 153u8, 193u8, 39u8, 137u8, 186u8, 29u8, 202u8, 56u8, 169u8, 56u8, 103u8, 138u8, 192u8, 18u8, 179u8, 114u8, 56u8, 121u8, 197u8, @@ -11396,7 +11362,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::voting_for::VotingFor, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -11405,10 +11374,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ConvictionVoting", "VotingFor", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 76u8, 63u8, 153u8, 193u8, 39u8, 137u8, 186u8, 29u8, 202u8, 56u8, 169u8, 56u8, 103u8, 138u8, 192u8, 18u8, 179u8, 114u8, 56u8, 121u8, 197u8, @@ -11422,7 +11391,7 @@ pub mod api { pub fn class_locks_for_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::class_locks_for::ClassLocksFor, (), ::subxt::storage::address::Yes, @@ -11431,7 +11400,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ConvictionVoting", "ClassLocksFor", - vec![], + (), [ 74u8, 74u8, 8u8, 82u8, 215u8, 61u8, 13u8, 9u8, 44u8, 222u8, 33u8, 245u8, 195u8, 124u8, 6u8, 174u8, 65u8, 245u8, 71u8, 42u8, 47u8, 46u8, @@ -11446,7 +11415,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::class_locks_for::ClassLocksFor, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -11455,9 +11424,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ConvictionVoting", "ClassLocksFor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 74u8, 74u8, 8u8, 82u8, 215u8, 61u8, 13u8, 9u8, 44u8, 222u8, 33u8, 245u8, 195u8, 124u8, 6u8, 174u8, 65u8, 245u8, 71u8, 42u8, 47u8, 46u8, @@ -12348,7 +12315,7 @@ pub mod api { pub fn referendum_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::referendum_count::ReferendumCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -12357,7 +12324,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "ReferendumCount", - vec![], + (), [ 64u8, 145u8, 232u8, 153u8, 121u8, 87u8, 128u8, 253u8, 170u8, 192u8, 139u8, 18u8, 0u8, 33u8, 243u8, 11u8, 238u8, 222u8, 244u8, 5u8, 247u8, @@ -12370,7 +12337,7 @@ pub mod api { pub fn referendum_info_for_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::referendum_info_for::ReferendumInfoFor, (), (), @@ -12379,7 +12346,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "ReferendumInfoFor", - vec![], + (), [ 244u8, 215u8, 156u8, 181u8, 105u8, 12u8, 138u8, 249u8, 173u8, 158u8, 171u8, 67u8, 107u8, 228u8, 45u8, 180u8, 252u8, 244u8, 186u8, 78u8, @@ -12393,7 +12360,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::referendum_info_for::ReferendumInfoFor, ::subxt::storage::address::Yes, (), @@ -12402,9 +12369,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "ReferendumInfoFor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 244u8, 215u8, 156u8, 181u8, 105u8, 12u8, 138u8, 249u8, 173u8, 158u8, 171u8, 67u8, 107u8, 228u8, 45u8, 180u8, 252u8, 244u8, 186u8, 78u8, @@ -12420,7 +12385,7 @@ pub mod api { pub fn track_queue_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::track_queue::TrackQueue, (), ::subxt::storage::address::Yes, @@ -12429,7 +12394,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "TrackQueue", - vec![], + (), [ 125u8, 59u8, 111u8, 68u8, 27u8, 236u8, 82u8, 55u8, 83u8, 159u8, 105u8, 20u8, 241u8, 118u8, 58u8, 141u8, 103u8, 60u8, 246u8, 49u8, 121u8, @@ -12445,7 +12410,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::track_queue::TrackQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -12454,9 +12419,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "TrackQueue", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 125u8, 59u8, 111u8, 68u8, 27u8, 236u8, 82u8, 55u8, 83u8, 159u8, 105u8, 20u8, 241u8, 118u8, 58u8, 141u8, 103u8, 60u8, 246u8, 49u8, 121u8, @@ -12468,7 +12431,7 @@ pub mod api { pub fn deciding_count_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::deciding_count::DecidingCount, (), ::subxt::storage::address::Yes, @@ -12477,7 +12440,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "DecidingCount", - vec![], + (), [ 203u8, 89u8, 158u8, 179u8, 194u8, 82u8, 248u8, 162u8, 93u8, 140u8, 146u8, 51u8, 110u8, 232u8, 51u8, 1u8, 128u8, 212u8, 199u8, 14u8, 182u8, @@ -12491,7 +12454,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::deciding_count::DecidingCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -12500,9 +12463,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "DecidingCount", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 203u8, 89u8, 158u8, 179u8, 194u8, 82u8, 248u8, 162u8, 93u8, 140u8, 146u8, 51u8, 110u8, 232u8, 51u8, 1u8, 128u8, 212u8, 199u8, 14u8, 182u8, @@ -12520,7 +12481,7 @@ pub mod api { pub fn metadata_of_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::metadata_of::MetadataOf, (), (), @@ -12529,7 +12490,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "MetadataOf", - vec![], + (), [ 159u8, 250u8, 56u8, 189u8, 247u8, 165u8, 206u8, 166u8, 91u8, 139u8, 124u8, 164u8, 25u8, 246u8, 199u8, 36u8, 159u8, 56u8, 227u8, 136u8, 4u8, @@ -12548,7 +12509,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::metadata_of::MetadataOf, ::subxt::storage::address::Yes, (), @@ -12557,9 +12518,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "MetadataOf", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 159u8, 250u8, 56u8, 189u8, 247u8, 165u8, 206u8, 166u8, 91u8, 139u8, 124u8, 164u8, 25u8, 246u8, 199u8, 36u8, 159u8, 56u8, 227u8, 136u8, 4u8, @@ -13071,7 +13030,7 @@ pub mod api { pub fn member_count_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::member_count::MemberCount, (), ::subxt::storage::address::Yes, @@ -13080,7 +13039,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "MemberCount", - vec![], + (), [ 0u8, 141u8, 66u8, 91u8, 155u8, 74u8, 17u8, 191u8, 143u8, 41u8, 231u8, 56u8, 123u8, 219u8, 145u8, 27u8, 197u8, 62u8, 118u8, 237u8, 30u8, 7u8, @@ -13094,7 +13053,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::member_count::MemberCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -13103,9 +13062,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "MemberCount", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 0u8, 141u8, 66u8, 91u8, 155u8, 74u8, 17u8, 191u8, 143u8, 41u8, 231u8, 56u8, 123u8, 219u8, 145u8, 27u8, 197u8, 62u8, 118u8, 237u8, 30u8, 7u8, @@ -13117,7 +13074,7 @@ pub mod api { pub fn members_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::members::Members, (), (), @@ -13126,7 +13083,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "Members", - vec![], + (), [ 101u8, 183u8, 36u8, 241u8, 67u8, 8u8, 252u8, 116u8, 110u8, 153u8, 117u8, 210u8, 128u8, 80u8, 130u8, 163u8, 38u8, 76u8, 230u8, 107u8, @@ -13140,7 +13097,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::members::Members, ::subxt::storage::address::Yes, (), @@ -13149,9 +13106,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "Members", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 101u8, 183u8, 36u8, 241u8, 67u8, 8u8, 252u8, 116u8, 110u8, 153u8, 117u8, 210u8, 128u8, 80u8, 130u8, 163u8, 38u8, 76u8, 230u8, 107u8, @@ -13164,7 +13119,7 @@ pub mod api { pub fn id_to_index_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::id_to_index::IdToIndex, (), (), @@ -13173,7 +13128,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "IdToIndex", - vec![], + (), [ 121u8, 225u8, 69u8, 131u8, 194u8, 3u8, 82u8, 27u8, 129u8, 152u8, 157u8, 45u8, 39u8, 47u8, 166u8, 28u8, 42u8, 92u8, 217u8, 189u8, 160u8, 102u8, @@ -13186,7 +13141,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::id_to_index::IdToIndex, (), (), @@ -13195,9 +13150,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "IdToIndex", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 121u8, 225u8, 69u8, 131u8, 194u8, 3u8, 82u8, 27u8, 129u8, 152u8, 157u8, 45u8, 39u8, 47u8, 166u8, 28u8, 42u8, 92u8, 217u8, 189u8, 160u8, 102u8, @@ -13211,7 +13164,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::id_to_index::IdToIndex, ::subxt::storage::address::Yes, (), @@ -13220,10 +13176,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "IdToIndex", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 121u8, 225u8, 69u8, 131u8, 194u8, 3u8, 82u8, 27u8, 129u8, 152u8, 157u8, 45u8, 39u8, 47u8, 166u8, 28u8, 42u8, 92u8, 217u8, 189u8, 160u8, 102u8, @@ -13236,7 +13192,7 @@ pub mod api { pub fn index_to_id_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::index_to_id::IndexToId, (), (), @@ -13245,7 +13201,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "IndexToId", - vec![], + (), [ 110u8, 48u8, 214u8, 224u8, 56u8, 195u8, 186u8, 24u8, 111u8, 37u8, 15u8, 153u8, 245u8, 101u8, 229u8, 149u8, 216u8, 185u8, 7u8, 242u8, 196u8, @@ -13260,7 +13216,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::index_to_id::IndexToId, (), (), @@ -13269,9 +13225,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "IndexToId", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 110u8, 48u8, 214u8, 224u8, 56u8, 195u8, 186u8, 24u8, 111u8, 37u8, 15u8, 153u8, 245u8, 101u8, 229u8, 149u8, 216u8, 185u8, 7u8, 242u8, 196u8, @@ -13287,7 +13241,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::index_to_id::IndexToId, ::subxt::storage::address::Yes, (), @@ -13296,10 +13253,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "IndexToId", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 110u8, 48u8, 214u8, 224u8, 56u8, 195u8, 186u8, 24u8, 111u8, 37u8, 15u8, 153u8, 245u8, 101u8, 229u8, 149u8, 216u8, 185u8, 7u8, 242u8, 196u8, @@ -13312,7 +13269,7 @@ pub mod api { pub fn voting_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::voting::Voting, (), (), @@ -13321,7 +13278,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "Voting", - vec![], + (), [ 180u8, 146u8, 236u8, 178u8, 30u8, 50u8, 161u8, 50u8, 140u8, 110u8, 220u8, 1u8, 109u8, 209u8, 17u8, 94u8, 234u8, 223u8, 222u8, 177u8, @@ -13335,7 +13292,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::voting::Voting, (), (), @@ -13344,9 +13301,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "Voting", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 180u8, 146u8, 236u8, 178u8, 30u8, 50u8, 161u8, 50u8, 140u8, 110u8, 220u8, 1u8, 109u8, 209u8, 17u8, 94u8, 234u8, 223u8, 222u8, 177u8, @@ -13361,7 +13316,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::voting::Voting, ::subxt::storage::address::Yes, (), @@ -13370,10 +13328,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "Voting", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 180u8, 146u8, 236u8, 178u8, 30u8, 50u8, 161u8, 50u8, 140u8, 110u8, 220u8, 1u8, 109u8, 209u8, 17u8, 94u8, 234u8, 223u8, 222u8, 177u8, @@ -13385,7 +13343,7 @@ pub mod api { pub fn voting_cleanup_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::voting_cleanup::VotingCleanup, (), (), @@ -13394,7 +13352,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "VotingCleanup", - vec![], + (), [ 223u8, 130u8, 79u8, 104u8, 94u8, 221u8, 222u8, 72u8, 187u8, 95u8, 231u8, 59u8, 28u8, 119u8, 191u8, 63u8, 40u8, 186u8, 58u8, 254u8, 14u8, @@ -13406,7 +13364,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::voting_cleanup::VotingCleanup, ::subxt::storage::address::Yes, (), @@ -13415,9 +13373,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "VotingCleanup", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 223u8, 130u8, 79u8, 104u8, 94u8, 221u8, 222u8, 72u8, 187u8, 95u8, 231u8, 59u8, 28u8, 119u8, 191u8, 63u8, 40u8, 186u8, 58u8, 254u8, 14u8, @@ -14260,7 +14216,7 @@ pub mod api { pub fn referendum_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::referendum_count::ReferendumCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -14269,7 +14225,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "ReferendumCount", - vec![], + (), [ 64u8, 145u8, 232u8, 153u8, 121u8, 87u8, 128u8, 253u8, 170u8, 192u8, 139u8, 18u8, 0u8, 33u8, 243u8, 11u8, 238u8, 222u8, 244u8, 5u8, 247u8, @@ -14282,7 +14238,7 @@ pub mod api { pub fn referendum_info_for_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::referendum_info_for::ReferendumInfoFor, (), (), @@ -14291,7 +14247,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "ReferendumInfoFor", - vec![], + (), [ 64u8, 146u8, 31u8, 207u8, 209u8, 86u8, 44u8, 53u8, 78u8, 240u8, 222u8, 131u8, 225u8, 83u8, 114u8, 205u8, 225u8, 20u8, 128u8, 183u8, 19u8, @@ -14305,7 +14261,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::referendum_info_for::ReferendumInfoFor, ::subxt::storage::address::Yes, (), @@ -14314,9 +14270,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "ReferendumInfoFor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 64u8, 146u8, 31u8, 207u8, 209u8, 86u8, 44u8, 53u8, 78u8, 240u8, 222u8, 131u8, 225u8, 83u8, 114u8, 205u8, 225u8, 20u8, 128u8, 183u8, 19u8, @@ -14332,7 +14286,7 @@ pub mod api { pub fn track_queue_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::track_queue::TrackQueue, (), ::subxt::storage::address::Yes, @@ -14341,7 +14295,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "TrackQueue", - vec![], + (), [ 187u8, 113u8, 225u8, 99u8, 159u8, 207u8, 182u8, 41u8, 116u8, 136u8, 119u8, 196u8, 152u8, 50u8, 192u8, 22u8, 171u8, 182u8, 237u8, 228u8, @@ -14358,7 +14312,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::track_queue::TrackQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -14367,9 +14321,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "TrackQueue", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 187u8, 113u8, 225u8, 99u8, 159u8, 207u8, 182u8, 41u8, 116u8, 136u8, 119u8, 196u8, 152u8, 50u8, 192u8, 22u8, 171u8, 182u8, 237u8, 228u8, @@ -14382,7 +14334,7 @@ pub mod api { pub fn deciding_count_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::deciding_count::DecidingCount, (), ::subxt::storage::address::Yes, @@ -14391,7 +14343,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "DecidingCount", - vec![], + (), [ 203u8, 89u8, 158u8, 179u8, 194u8, 82u8, 248u8, 162u8, 93u8, 140u8, 146u8, 51u8, 110u8, 232u8, 51u8, 1u8, 128u8, 212u8, 199u8, 14u8, 182u8, @@ -14405,7 +14357,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::deciding_count::DecidingCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -14414,9 +14366,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "DecidingCount", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 203u8, 89u8, 158u8, 179u8, 194u8, 82u8, 248u8, 162u8, 93u8, 140u8, 146u8, 51u8, 110u8, 232u8, 51u8, 1u8, 128u8, 212u8, 199u8, 14u8, 182u8, @@ -14434,7 +14384,7 @@ pub mod api { pub fn metadata_of_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::metadata_of::MetadataOf, (), (), @@ -14443,7 +14393,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "MetadataOf", - vec![], + (), [ 159u8, 250u8, 56u8, 189u8, 247u8, 165u8, 206u8, 166u8, 91u8, 139u8, 124u8, 164u8, 25u8, 246u8, 199u8, 36u8, 159u8, 56u8, 227u8, 136u8, 4u8, @@ -14462,7 +14412,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::metadata_of::MetadataOf, ::subxt::storage::address::Yes, (), @@ -14471,9 +14421,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "MetadataOf", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 159u8, 250u8, 56u8, 189u8, 247u8, 165u8, 206u8, 166u8, 91u8, 139u8, 124u8, 164u8, 25u8, 246u8, 199u8, 36u8, 159u8, 56u8, 227u8, 136u8, 4u8, @@ -14855,7 +14803,7 @@ pub mod api { pub fn whitelisted_call_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::whitelisted_call::WhitelistedCall, (), (), @@ -14864,7 +14812,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Whitelist", "WhitelistedCall", - vec![], + (), [ 82u8, 208u8, 214u8, 72u8, 225u8, 35u8, 51u8, 212u8, 25u8, 138u8, 30u8, 87u8, 54u8, 232u8, 72u8, 132u8, 4u8, 9u8, 28u8, 143u8, 251u8, 106u8, @@ -14876,7 +14824,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::whitelisted_call::WhitelistedCall, ::subxt::storage::address::Yes, (), @@ -14885,9 +14833,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Whitelist", "WhitelistedCall", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 82u8, 208u8, 214u8, 72u8, 225u8, 35u8, 51u8, 212u8, 25u8, 138u8, 30u8, 87u8, 54u8, 232u8, 72u8, 132u8, 4u8, 9u8, 28u8, 143u8, 251u8, 106u8, @@ -15232,7 +15178,7 @@ pub mod api { pub fn claims_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::claims::Claims, (), (), @@ -15241,7 +15187,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Claims", - vec![], + (), [ 148u8, 115u8, 159u8, 169u8, 36u8, 116u8, 15u8, 108u8, 57u8, 195u8, 226u8, 180u8, 187u8, 112u8, 114u8, 63u8, 3u8, 205u8, 113u8, 141u8, @@ -15254,7 +15200,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::claims::Claims, ::subxt::storage::address::Yes, (), @@ -15263,9 +15209,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Claims", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 148u8, 115u8, 159u8, 169u8, 36u8, 116u8, 15u8, 108u8, 57u8, 195u8, 226u8, 180u8, 187u8, 112u8, 114u8, 63u8, 3u8, 205u8, 113u8, 141u8, @@ -15277,7 +15221,7 @@ pub mod api { pub fn total( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::total::Total, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -15286,7 +15230,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Total", - vec![], + (), [ 188u8, 31u8, 219u8, 189u8, 49u8, 213u8, 203u8, 89u8, 125u8, 58u8, 232u8, 159u8, 131u8, 155u8, 166u8, 113u8, 99u8, 24u8, 40u8, 242u8, @@ -15302,7 +15246,7 @@ pub mod api { pub fn vesting_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::vesting::Vesting, (), (), @@ -15311,7 +15255,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Vesting", - vec![], + (), [ 206u8, 106u8, 195u8, 101u8, 55u8, 137u8, 50u8, 105u8, 137u8, 87u8, 230u8, 34u8, 255u8, 94u8, 210u8, 186u8, 179u8, 72u8, 24u8, 194u8, @@ -15328,7 +15272,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::vesting::Vesting, ::subxt::storage::address::Yes, (), @@ -15337,9 +15281,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Vesting", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 206u8, 106u8, 195u8, 101u8, 55u8, 137u8, 50u8, 105u8, 137u8, 87u8, 230u8, 34u8, 255u8, 94u8, 210u8, 186u8, 179u8, 72u8, 24u8, 194u8, @@ -15352,7 +15294,7 @@ pub mod api { pub fn signing_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::signing::Signing, (), (), @@ -15361,7 +15303,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Signing", - vec![], + (), [ 111u8, 90u8, 178u8, 121u8, 241u8, 28u8, 169u8, 231u8, 61u8, 189u8, 113u8, 207u8, 26u8, 153u8, 189u8, 15u8, 192u8, 25u8, 22u8, 22u8, 124u8, @@ -15374,7 +15316,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::signing::Signing, ::subxt::storage::address::Yes, (), @@ -15383,9 +15325,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Signing", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 111u8, 90u8, 178u8, 121u8, 241u8, 28u8, 169u8, 231u8, 61u8, 189u8, 113u8, 207u8, 26u8, 153u8, 189u8, 15u8, 192u8, 25u8, 22u8, 22u8, 124u8, @@ -15397,7 +15337,7 @@ pub mod api { pub fn preclaims_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::preclaims::Preclaims, (), (), @@ -15406,7 +15346,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Preclaims", - vec![], + (), [ 197u8, 114u8, 147u8, 235u8, 203u8, 255u8, 94u8, 113u8, 151u8, 119u8, 224u8, 147u8, 48u8, 246u8, 124u8, 38u8, 190u8, 237u8, 226u8, 65u8, @@ -15420,7 +15360,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::preclaims::Preclaims, ::subxt::storage::address::Yes, (), @@ -15429,9 +15369,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Preclaims", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 197u8, 114u8, 147u8, 235u8, 203u8, 255u8, 94u8, 113u8, 151u8, 119u8, 224u8, 147u8, 48u8, 246u8, 124u8, 38u8, 190u8, 237u8, 226u8, 65u8, @@ -17307,7 +17245,7 @@ pub mod api { pub fn identity_of_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::identity_of::IdentityOf, (), (), @@ -17316,7 +17254,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "IdentityOf", - vec![], + (), [ 0u8, 73u8, 213u8, 52u8, 49u8, 235u8, 238u8, 43u8, 119u8, 12u8, 35u8, 162u8, 230u8, 24u8, 246u8, 200u8, 44u8, 254u8, 13u8, 84u8, 10u8, 27u8, @@ -17332,7 +17270,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::identity_of::IdentityOf, ::subxt::storage::address::Yes, (), @@ -17341,9 +17279,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "IdentityOf", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 0u8, 73u8, 213u8, 52u8, 49u8, 235u8, 238u8, 43u8, 119u8, 12u8, 35u8, 162u8, 230u8, 24u8, 246u8, 200u8, 44u8, 254u8, 13u8, 84u8, 10u8, 27u8, @@ -17356,7 +17292,7 @@ pub mod api { pub fn super_of_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::super_of::SuperOf, (), (), @@ -17365,7 +17301,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "SuperOf", - vec![], + (), [ 84u8, 72u8, 64u8, 14u8, 56u8, 9u8, 143u8, 100u8, 141u8, 163u8, 36u8, 55u8, 38u8, 254u8, 164u8, 17u8, 3u8, 110u8, 88u8, 175u8, 161u8, 65u8, @@ -17379,7 +17315,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::super_of::SuperOf, ::subxt::storage::address::Yes, (), @@ -17388,9 +17324,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "SuperOf", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 84u8, 72u8, 64u8, 14u8, 56u8, 9u8, 143u8, 100u8, 141u8, 163u8, 36u8, 55u8, 38u8, 254u8, 164u8, 17u8, 3u8, 110u8, 88u8, 175u8, 161u8, 65u8, @@ -17406,7 +17340,7 @@ pub mod api { pub fn subs_of_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::subs_of::SubsOf, (), ::subxt::storage::address::Yes, @@ -17415,7 +17349,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "SubsOf", - vec![], + (), [ 164u8, 140u8, 52u8, 123u8, 220u8, 118u8, 147u8, 3u8, 67u8, 22u8, 191u8, 18u8, 186u8, 21u8, 154u8, 8u8, 205u8, 224u8, 163u8, 173u8, 174u8, @@ -17433,7 +17367,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::subs_of::SubsOf, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -17442,9 +17376,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "SubsOf", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 164u8, 140u8, 52u8, 123u8, 220u8, 118u8, 147u8, 3u8, 67u8, 22u8, 191u8, 18u8, 186u8, 21u8, 154u8, 8u8, 205u8, 224u8, 163u8, 173u8, 174u8, @@ -17460,7 +17392,7 @@ pub mod api { pub fn registrars( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::registrars::Registrars, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -17469,7 +17401,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "Registrars", - vec![], + (), [ 167u8, 99u8, 159u8, 117u8, 103u8, 243u8, 208u8, 113u8, 57u8, 225u8, 27u8, 25u8, 188u8, 120u8, 15u8, 40u8, 134u8, 169u8, 108u8, 134u8, 83u8, @@ -17482,7 +17414,7 @@ pub mod api { pub fn username_authorities_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::username_authorities::UsernameAuthorities, (), (), @@ -17491,7 +17423,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "UsernameAuthorities", - vec![], + (), [ 89u8, 102u8, 60u8, 184u8, 127u8, 244u8, 3u8, 61u8, 209u8, 78u8, 178u8, 44u8, 159u8, 27u8, 7u8, 0u8, 22u8, 116u8, 42u8, 240u8, 130u8, 93u8, @@ -17504,7 +17436,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::username_authorities::UsernameAuthorities, ::subxt::storage::address::Yes, (), @@ -17513,9 +17445,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "UsernameAuthorities", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 89u8, 102u8, 60u8, 184u8, 127u8, 244u8, 3u8, 61u8, 209u8, 78u8, 178u8, 44u8, 159u8, 27u8, 7u8, 0u8, 22u8, 116u8, 42u8, 240u8, 130u8, 93u8, @@ -17531,7 +17461,7 @@ pub mod api { pub fn account_of_username_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::account_of_username::AccountOfUsername, (), (), @@ -17540,7 +17470,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "AccountOfUsername", - vec![], + (), [ 131u8, 96u8, 207u8, 217u8, 223u8, 54u8, 51u8, 156u8, 8u8, 238u8, 134u8, 57u8, 42u8, 110u8, 180u8, 107u8, 30u8, 109u8, 162u8, 110u8, 178u8, @@ -17558,7 +17488,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::account_of_username::AccountOfUsername, ::subxt::storage::address::Yes, (), @@ -17567,9 +17497,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "AccountOfUsername", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 131u8, 96u8, 207u8, 217u8, 223u8, 54u8, 51u8, 156u8, 8u8, 238u8, 134u8, 57u8, 42u8, 110u8, 180u8, 107u8, 30u8, 109u8, 162u8, 110u8, 178u8, @@ -17587,7 +17515,7 @@ pub mod api { pub fn pending_usernames_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pending_usernames::PendingUsernames, (), (), @@ -17596,7 +17524,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "PendingUsernames", - vec![], + (), [ 237u8, 213u8, 92u8, 249u8, 11u8, 169u8, 104u8, 7u8, 201u8, 133u8, 164u8, 64u8, 191u8, 172u8, 169u8, 229u8, 206u8, 105u8, 190u8, 113u8, @@ -17615,7 +17543,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::pending_usernames::PendingUsernames, ::subxt::storage::address::Yes, (), @@ -17624,9 +17552,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "PendingUsernames", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 237u8, 213u8, 92u8, 249u8, 11u8, 169u8, 104u8, 7u8, 201u8, 133u8, 164u8, 64u8, 191u8, 172u8, 169u8, 229u8, 206u8, 105u8, 190u8, 113u8, @@ -19070,7 +18996,7 @@ pub mod api { pub fn parameters( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::parameters::Parameters, ::subxt::storage::address::Yes, (), @@ -19079,7 +19005,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Parameters", - vec![], + (), [ 69u8, 147u8, 95u8, 26u8, 245u8, 207u8, 83u8, 57u8, 229u8, 34u8, 205u8, 202u8, 182u8, 180u8, 219u8, 86u8, 152u8, 140u8, 212u8, 145u8, 7u8, @@ -19092,7 +19018,7 @@ pub mod api { pub fn pot( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pot::Pot, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -19101,7 +19027,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Pot", - vec![], + (), [ 98u8, 77u8, 215u8, 220u8, 51u8, 87u8, 188u8, 65u8, 72u8, 231u8, 34u8, 161u8, 61u8, 59u8, 66u8, 105u8, 128u8, 23u8, 249u8, 27u8, 10u8, 0u8, @@ -19113,7 +19039,7 @@ pub mod api { pub fn founder( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::founder::Founder, ::subxt::storage::address::Yes, (), @@ -19122,7 +19048,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Founder", - vec![], + (), [ 14u8, 6u8, 181u8, 186u8, 64u8, 213u8, 48u8, 110u8, 242u8, 50u8, 144u8, 77u8, 38u8, 127u8, 161u8, 54u8, 204u8, 119u8, 1u8, 218u8, 12u8, 57u8, @@ -19134,7 +19060,7 @@ pub mod api { pub fn head( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::head::Head, ::subxt::storage::address::Yes, (), @@ -19143,7 +19069,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Head", - vec![], + (), [ 95u8, 2u8, 23u8, 237u8, 130u8, 169u8, 84u8, 51u8, 1u8, 178u8, 234u8, 194u8, 139u8, 35u8, 222u8, 150u8, 246u8, 176u8, 97u8, 103u8, 211u8, @@ -19156,7 +19082,7 @@ pub mod api { pub fn rules( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::rules::Rules, ::subxt::storage::address::Yes, (), @@ -19165,7 +19091,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Rules", - vec![], + (), [ 119u8, 249u8, 119u8, 89u8, 243u8, 239u8, 149u8, 15u8, 238u8, 40u8, 172u8, 198u8, 24u8, 107u8, 57u8, 39u8, 155u8, 36u8, 13u8, 72u8, 153u8, @@ -19178,7 +19104,7 @@ pub mod api { pub fn members_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::members::Members, (), (), @@ -19187,7 +19113,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Members", - vec![], + (), [ 207u8, 227u8, 130u8, 247u8, 29u8, 198u8, 129u8, 83u8, 3u8, 6u8, 19u8, 37u8, 163u8, 227u8, 0u8, 94u8, 8u8, 166u8, 111u8, 70u8, 101u8, 65u8, @@ -19200,7 +19126,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::members::Members, ::subxt::storage::address::Yes, (), @@ -19209,9 +19135,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Members", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 207u8, 227u8, 130u8, 247u8, 29u8, 198u8, 129u8, 83u8, 3u8, 6u8, 19u8, 37u8, 163u8, 227u8, 0u8, 94u8, 8u8, 166u8, 111u8, 70u8, 101u8, 65u8, @@ -19223,7 +19147,7 @@ pub mod api { pub fn payouts_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::payouts::Payouts, (), ::subxt::storage::address::Yes, @@ -19232,7 +19156,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Payouts", - vec![], + (), [ 251u8, 249u8, 170u8, 219u8, 131u8, 113u8, 178u8, 165u8, 173u8, 36u8, 175u8, 199u8, 57u8, 188u8, 59u8, 226u8, 4u8, 45u8, 36u8, 173u8, 113u8, @@ -19245,7 +19169,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::payouts::Payouts, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -19254,9 +19178,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Payouts", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 251u8, 249u8, 170u8, 219u8, 131u8, 113u8, 178u8, 165u8, 173u8, 36u8, 175u8, 199u8, 57u8, 188u8, 59u8, 226u8, 4u8, 45u8, 36u8, 173u8, 113u8, @@ -19268,7 +19190,7 @@ pub mod api { pub fn member_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::member_count::MemberCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -19277,7 +19199,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "MemberCount", - vec![], + (), [ 251u8, 200u8, 97u8, 38u8, 125u8, 162u8, 19u8, 100u8, 249u8, 254u8, 42u8, 93u8, 64u8, 171u8, 2u8, 200u8, 129u8, 228u8, 211u8, 229u8, 152u8, @@ -19291,7 +19213,7 @@ pub mod api { pub fn member_by_index_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::member_by_index::MemberByIndex, (), (), @@ -19300,7 +19222,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "MemberByIndex", - vec![], + (), [ 13u8, 233u8, 212u8, 149u8, 220u8, 158u8, 17u8, 27u8, 201u8, 61u8, 202u8, 248u8, 192u8, 37u8, 199u8, 73u8, 32u8, 140u8, 204u8, 206u8, @@ -19315,7 +19237,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::member_by_index::MemberByIndex, ::subxt::storage::address::Yes, (), @@ -19324,9 +19246,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "MemberByIndex", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 13u8, 233u8, 212u8, 149u8, 220u8, 158u8, 17u8, 27u8, 201u8, 61u8, 202u8, 248u8, 192u8, 37u8, 199u8, 73u8, 32u8, 140u8, 204u8, 206u8, @@ -19339,7 +19259,7 @@ pub mod api { pub fn suspended_members_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::suspended_members::SuspendedMembers, (), (), @@ -19348,7 +19268,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "SuspendedMembers", - vec![], + (), [ 156u8, 11u8, 75u8, 79u8, 74u8, 79u8, 98u8, 89u8, 63u8, 83u8, 84u8, 249u8, 177u8, 227u8, 113u8, 21u8, 26u8, 165u8, 129u8, 5u8, 129u8, @@ -19362,7 +19282,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::suspended_members::SuspendedMembers, ::subxt::storage::address::Yes, (), @@ -19371,9 +19291,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "SuspendedMembers", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 156u8, 11u8, 75u8, 79u8, 74u8, 79u8, 98u8, 89u8, 63u8, 83u8, 84u8, 249u8, 177u8, 227u8, 113u8, 21u8, 26u8, 165u8, 129u8, 5u8, 129u8, @@ -19386,7 +19304,7 @@ pub mod api { pub fn round_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::round_count::RoundCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -19395,7 +19313,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "RoundCount", - vec![], + (), [ 61u8, 189u8, 115u8, 157u8, 36u8, 97u8, 192u8, 96u8, 138u8, 168u8, 222u8, 58u8, 117u8, 199u8, 176u8, 146u8, 232u8, 167u8, 52u8, 190u8, @@ -19408,7 +19326,7 @@ pub mod api { pub fn bids( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::bids::Bids, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -19417,7 +19335,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Bids", - vec![], + (), [ 220u8, 159u8, 208u8, 176u8, 118u8, 11u8, 21u8, 34u8, 3u8, 101u8, 233u8, 212u8, 149u8, 156u8, 235u8, 135u8, 142u8, 220u8, 76u8, 99u8, 60u8, @@ -19428,7 +19346,7 @@ pub mod api { pub fn candidates_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::candidates::Candidates, (), (), @@ -19437,7 +19355,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Candidates", - vec![], + (), [ 52u8, 250u8, 201u8, 163u8, 0u8, 5u8, 156u8, 84u8, 96u8, 130u8, 228u8, 205u8, 34u8, 75u8, 121u8, 209u8, 82u8, 15u8, 247u8, 21u8, 54u8, 177u8, @@ -19449,7 +19367,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::candidates::Candidates, ::subxt::storage::address::Yes, (), @@ -19458,9 +19376,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Candidates", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 52u8, 250u8, 201u8, 163u8, 0u8, 5u8, 156u8, 84u8, 96u8, 130u8, 228u8, 205u8, 34u8, 75u8, 121u8, 209u8, 82u8, 15u8, 247u8, 21u8, 54u8, 177u8, @@ -19472,7 +19388,7 @@ pub mod api { pub fn skeptic( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::skeptic::Skeptic, ::subxt::storage::address::Yes, (), @@ -19481,7 +19397,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Skeptic", - vec![], + (), [ 121u8, 103u8, 195u8, 11u8, 87u8, 129u8, 61u8, 69u8, 218u8, 17u8, 101u8, 207u8, 249u8, 207u8, 18u8, 103u8, 253u8, 240u8, 132u8, 46u8, 47u8, @@ -19494,7 +19410,7 @@ pub mod api { pub fn votes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::votes::Votes, (), (), @@ -19503,7 +19419,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Votes", - vec![], + (), [ 34u8, 201u8, 151u8, 130u8, 149u8, 159u8, 32u8, 201u8, 127u8, 178u8, 77u8, 214u8, 73u8, 158u8, 11u8, 247u8, 188u8, 156u8, 146u8, 59u8, @@ -19517,7 +19433,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::votes::Votes, (), (), @@ -19526,9 +19442,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Votes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 34u8, 201u8, 151u8, 130u8, 149u8, 159u8, 32u8, 201u8, 127u8, 178u8, 77u8, 214u8, 73u8, 158u8, 11u8, 247u8, 188u8, 156u8, 146u8, 59u8, @@ -19543,7 +19457,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::votes::Votes, ::subxt::storage::address::Yes, (), @@ -19552,10 +19469,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Votes", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 34u8, 201u8, 151u8, 130u8, 149u8, 159u8, 32u8, 201u8, 127u8, 178u8, 77u8, 214u8, 73u8, 158u8, 11u8, 247u8, 188u8, 156u8, 146u8, 59u8, @@ -19568,7 +19485,7 @@ pub mod api { pub fn vote_clear_cursor_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::vote_clear_cursor::VoteClearCursor, (), (), @@ -19577,7 +19494,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "VoteClearCursor", - vec![], + (), [ 157u8, 200u8, 216u8, 228u8, 235u8, 144u8, 13u8, 111u8, 252u8, 213u8, 209u8, 114u8, 157u8, 159u8, 47u8, 125u8, 45u8, 152u8, 27u8, 145u8, @@ -19591,7 +19508,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::vote_clear_cursor::VoteClearCursor, ::subxt::storage::address::Yes, (), @@ -19600,9 +19517,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "VoteClearCursor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 157u8, 200u8, 216u8, 228u8, 235u8, 144u8, 13u8, 111u8, 252u8, 213u8, 209u8, 114u8, 157u8, 159u8, 47u8, 125u8, 45u8, 152u8, 27u8, 145u8, @@ -19617,7 +19532,7 @@ pub mod api { pub fn next_head( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_head::NextHead, ::subxt::storage::address::Yes, (), @@ -19626,7 +19541,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "NextHead", - vec![], + (), [ 64u8, 118u8, 253u8, 247u8, 56u8, 39u8, 156u8, 38u8, 150u8, 234u8, 190u8, 11u8, 45u8, 236u8, 15u8, 181u8, 6u8, 165u8, 226u8, 99u8, 46u8, @@ -19638,7 +19553,7 @@ pub mod api { pub fn challenge_round_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::challenge_round_count::ChallengeRoundCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -19647,7 +19562,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "ChallengeRoundCount", - vec![], + (), [ 111u8, 74u8, 218u8, 126u8, 43u8, 20u8, 75u8, 119u8, 166u8, 4u8, 56u8, 24u8, 206u8, 10u8, 236u8, 17u8, 62u8, 124u8, 129u8, 39u8, 197u8, 157u8, @@ -19659,7 +19574,7 @@ pub mod api { pub fn defending( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::defending::Defending, ::subxt::storage::address::Yes, (), @@ -19668,7 +19583,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Defending", - vec![], + (), [ 22u8, 165u8, 42u8, 82u8, 129u8, 214u8, 77u8, 50u8, 110u8, 35u8, 16u8, 44u8, 222u8, 47u8, 238u8, 209u8, 171u8, 254u8, 208u8, 3u8, 2u8, 87u8, @@ -19680,7 +19595,7 @@ pub mod api { pub fn defender_votes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::defender_votes::DefenderVotes, (), (), @@ -19689,7 +19604,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "DefenderVotes", - vec![], + (), [ 208u8, 137u8, 138u8, 215u8, 215u8, 207u8, 236u8, 140u8, 175u8, 50u8, 110u8, 228u8, 48u8, 174u8, 16u8, 59u8, 72u8, 108u8, 7u8, 183u8, 119u8, @@ -19703,7 +19618,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::defender_votes::DefenderVotes, (), (), @@ -19712,9 +19627,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "DefenderVotes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 208u8, 137u8, 138u8, 215u8, 215u8, 207u8, 236u8, 140u8, 175u8, 50u8, 110u8, 228u8, 48u8, 174u8, 16u8, 59u8, 72u8, 108u8, 7u8, 183u8, 119u8, @@ -19729,7 +19642,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::defender_votes::DefenderVotes, ::subxt::storage::address::Yes, (), @@ -19738,10 +19654,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "DefenderVotes", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 208u8, 137u8, 138u8, 215u8, 215u8, 207u8, 236u8, 140u8, 175u8, 50u8, 110u8, 228u8, 48u8, 174u8, 16u8, 59u8, 72u8, 108u8, 7u8, 183u8, 119u8, @@ -20453,7 +20369,7 @@ pub mod api { pub fn recoverable_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::recoverable::Recoverable, (), (), @@ -20462,7 +20378,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "Recoverable", - vec![], + (), [ 112u8, 7u8, 56u8, 46u8, 138u8, 197u8, 63u8, 234u8, 140u8, 123u8, 145u8, 106u8, 189u8, 190u8, 247u8, 61u8, 250u8, 67u8, 107u8, 42u8, 170u8, @@ -20475,7 +20391,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::recoverable::Recoverable, ::subxt::storage::address::Yes, (), @@ -20484,9 +20400,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "Recoverable", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 112u8, 7u8, 56u8, 46u8, 138u8, 197u8, 63u8, 234u8, 140u8, 123u8, 145u8, 106u8, 189u8, 190u8, 247u8, 61u8, 250u8, 67u8, 107u8, 42u8, 170u8, @@ -20501,7 +20415,7 @@ pub mod api { pub fn active_recoveries_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::active_recoveries::ActiveRecoveries, (), (), @@ -20510,7 +20424,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "ActiveRecoveries", - vec![], + (), [ 104u8, 252u8, 28u8, 142u8, 48u8, 26u8, 91u8, 201u8, 184u8, 163u8, 180u8, 197u8, 189u8, 71u8, 144u8, 88u8, 225u8, 13u8, 183u8, 84u8, @@ -20527,7 +20441,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::active_recoveries::ActiveRecoveries, (), (), @@ -20536,9 +20450,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "ActiveRecoveries", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 104u8, 252u8, 28u8, 142u8, 48u8, 26u8, 91u8, 201u8, 184u8, 163u8, 180u8, 197u8, 189u8, 71u8, 144u8, 88u8, 225u8, 13u8, 183u8, 84u8, @@ -20556,7 +20468,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::active_recoveries::ActiveRecoveries, ::subxt::storage::address::Yes, (), @@ -20565,10 +20480,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "ActiveRecoveries", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 104u8, 252u8, 28u8, 142u8, 48u8, 26u8, 91u8, 201u8, 184u8, 163u8, 180u8, 197u8, 189u8, 71u8, 144u8, 88u8, 225u8, 13u8, 183u8, 84u8, @@ -20583,7 +20498,7 @@ pub mod api { pub fn proxy_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::proxy::Proxy, (), (), @@ -20592,7 +20507,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "Proxy", - vec![], + (), [ 161u8, 242u8, 17u8, 183u8, 161u8, 47u8, 87u8, 110u8, 201u8, 177u8, 199u8, 157u8, 30u8, 131u8, 49u8, 89u8, 182u8, 86u8, 152u8, 19u8, 199u8, @@ -20607,7 +20522,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::proxy::Proxy, ::subxt::storage::address::Yes, (), @@ -20616,9 +20531,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "Proxy", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 161u8, 242u8, 17u8, 183u8, 161u8, 47u8, 87u8, 110u8, 201u8, 177u8, 199u8, 157u8, 30u8, 131u8, 49u8, 89u8, 182u8, 86u8, 152u8, 19u8, 199u8, @@ -21055,7 +20968,7 @@ pub mod api { pub fn vesting_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::vesting::Vesting, (), (), @@ -21064,7 +20977,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Vesting", "Vesting", - vec![], + (), [ 95u8, 168u8, 217u8, 248u8, 149u8, 86u8, 195u8, 93u8, 73u8, 206u8, 105u8, 165u8, 33u8, 173u8, 232u8, 81u8, 147u8, 254u8, 50u8, 228u8, @@ -21078,7 +20991,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::vesting::Vesting, ::subxt::storage::address::Yes, (), @@ -21087,9 +21000,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Vesting", "Vesting", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 95u8, 168u8, 217u8, 248u8, 149u8, 86u8, 195u8, 93u8, 73u8, 206u8, 105u8, 165u8, 33u8, 173u8, 232u8, 81u8, 147u8, 254u8, 50u8, 228u8, @@ -21104,7 +21015,7 @@ pub mod api { pub fn storage_version( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::storage_version::StorageVersion, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -21113,7 +21024,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Vesting", "StorageVersion", - vec![], + (), [ 230u8, 137u8, 180u8, 133u8, 142u8, 124u8, 231u8, 234u8, 223u8, 10u8, 154u8, 98u8, 158u8, 253u8, 228u8, 80u8, 5u8, 9u8, 91u8, 210u8, 252u8, @@ -21666,7 +21577,7 @@ pub mod api { pub fn incomplete_since( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::incomplete_since::IncompleteSince, ::subxt::storage::address::Yes, (), @@ -21675,7 +21586,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "IncompleteSince", - vec![], + (), [ 250u8, 83u8, 64u8, 167u8, 205u8, 59u8, 225u8, 97u8, 205u8, 12u8, 76u8, 130u8, 197u8, 4u8, 111u8, 208u8, 92u8, 217u8, 145u8, 119u8, 38u8, @@ -21687,7 +21598,7 @@ pub mod api { pub fn agenda_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::agenda::Agenda, (), ::subxt::storage::address::Yes, @@ -21696,7 +21607,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Agenda", - vec![], + (), [ 10u8, 123u8, 252u8, 106u8, 154u8, 9u8, 245u8, 203u8, 188u8, 254u8, 20u8, 41u8, 6u8, 226u8, 78u8, 188u8, 0u8, 173u8, 143u8, 44u8, 117u8, @@ -21709,7 +21620,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::agenda::Agenda, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -21718,9 +21629,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Agenda", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 10u8, 123u8, 252u8, 106u8, 154u8, 9u8, 245u8, 203u8, 188u8, 254u8, 20u8, 41u8, 6u8, 226u8, 78u8, 188u8, 0u8, 173u8, 143u8, 44u8, 117u8, @@ -21735,7 +21644,7 @@ pub mod api { pub fn lookup_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::lookup::Lookup, (), (), @@ -21744,7 +21653,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Lookup", - vec![], + (), [ 24u8, 87u8, 96u8, 127u8, 136u8, 205u8, 238u8, 174u8, 71u8, 110u8, 65u8, 98u8, 228u8, 167u8, 99u8, 71u8, 171u8, 186u8, 12u8, 218u8, 137u8, 70u8, @@ -21760,7 +21669,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::lookup::Lookup, ::subxt::storage::address::Yes, (), @@ -21769,9 +21678,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Lookup", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 24u8, 87u8, 96u8, 127u8, 136u8, 205u8, 238u8, 174u8, 71u8, 110u8, 65u8, 98u8, 228u8, 167u8, 99u8, 71u8, 171u8, 186u8, 12u8, 218u8, 137u8, 70u8, @@ -22487,7 +22394,7 @@ pub mod api { pub fn proxies_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::proxies::Proxies, (), ::subxt::storage::address::Yes, @@ -22496,7 +22403,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Proxy", "Proxies", - vec![], + (), [ 92u8, 131u8, 10u8, 14u8, 241u8, 148u8, 230u8, 81u8, 54u8, 152u8, 147u8, 180u8, 85u8, 28u8, 87u8, 215u8, 110u8, 13u8, 158u8, 207u8, 77u8, 102u8, @@ -22510,7 +22417,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::proxies::Proxies, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -22519,9 +22426,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Proxy", "Proxies", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 92u8, 131u8, 10u8, 14u8, 241u8, 148u8, 230u8, 81u8, 54u8, 152u8, 147u8, 180u8, 85u8, 28u8, 87u8, 215u8, 110u8, 13u8, 158u8, 207u8, 77u8, 102u8, @@ -22533,7 +22438,7 @@ pub mod api { pub fn announcements_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::announcements::Announcements, (), ::subxt::storage::address::Yes, @@ -22542,7 +22447,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Proxy", "Announcements", - vec![], + (), [ 129u8, 228u8, 198u8, 210u8, 90u8, 69u8, 151u8, 198u8, 206u8, 174u8, 148u8, 58u8, 134u8, 14u8, 53u8, 56u8, 234u8, 71u8, 84u8, 247u8, 246u8, @@ -22556,7 +22461,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::announcements::Announcements, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -22565,9 +22470,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Proxy", "Announcements", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 129u8, 228u8, 198u8, 210u8, 90u8, 69u8, 151u8, 198u8, 206u8, 174u8, 148u8, 58u8, 134u8, 14u8, 53u8, 56u8, 234u8, 71u8, 84u8, 247u8, 246u8, @@ -23053,7 +22956,7 @@ pub mod api { pub fn multisigs_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::multisigs::Multisigs, (), (), @@ -23062,7 +22965,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Multisig", "Multisigs", - vec![], + (), [ 154u8, 109u8, 45u8, 18u8, 155u8, 151u8, 81u8, 28u8, 86u8, 127u8, 189u8, 151u8, 49u8, 61u8, 12u8, 149u8, 84u8, 61u8, 110u8, 197u8, 200u8, 140u8, @@ -23075,7 +22978,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::multisigs::Multisigs, (), (), @@ -23084,9 +22987,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Multisig", "Multisigs", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 154u8, 109u8, 45u8, 18u8, 155u8, 151u8, 81u8, 28u8, 86u8, 127u8, 189u8, 151u8, 49u8, 61u8, 12u8, 149u8, 84u8, 61u8, 110u8, 197u8, 200u8, 140u8, @@ -23100,7 +23001,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::multisigs::Multisigs, ::subxt::storage::address::Yes, (), @@ -23109,10 +23013,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Multisig", "Multisigs", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 154u8, 109u8, 45u8, 18u8, 155u8, 151u8, 81u8, 28u8, 86u8, 127u8, 189u8, 151u8, 49u8, 61u8, 12u8, 149u8, 84u8, 61u8, 110u8, 197u8, 200u8, 140u8, @@ -23495,7 +23399,7 @@ pub mod api { pub fn status_for_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::status_for::StatusFor, (), (), @@ -23504,7 +23408,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "StatusFor", - vec![], + (), [ 187u8, 100u8, 54u8, 112u8, 96u8, 129u8, 36u8, 149u8, 127u8, 226u8, 126u8, 171u8, 72u8, 189u8, 59u8, 126u8, 204u8, 125u8, 67u8, 204u8, @@ -23518,7 +23422,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::status_for::StatusFor, ::subxt::storage::address::Yes, (), @@ -23527,9 +23431,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "StatusFor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 187u8, 100u8, 54u8, 112u8, 96u8, 129u8, 36u8, 149u8, 127u8, 226u8, 126u8, 171u8, 72u8, 189u8, 59u8, 126u8, 204u8, 125u8, 67u8, 204u8, @@ -23542,7 +23444,7 @@ pub mod api { pub fn request_status_for_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::request_status_for::RequestStatusFor, (), (), @@ -23551,7 +23453,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "RequestStatusFor", - vec![], + (), [ 72u8, 59u8, 254u8, 211u8, 96u8, 223u8, 10u8, 64u8, 6u8, 139u8, 213u8, 85u8, 14u8, 29u8, 166u8, 37u8, 140u8, 124u8, 186u8, 156u8, 172u8, @@ -23564,7 +23466,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::request_status_for::RequestStatusFor, ::subxt::storage::address::Yes, (), @@ -23573,9 +23475,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "RequestStatusFor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 72u8, 59u8, 254u8, 211u8, 96u8, 223u8, 10u8, 64u8, 6u8, 139u8, 213u8, 85u8, 14u8, 29u8, 166u8, 37u8, 140u8, 124u8, 186u8, 156u8, 172u8, @@ -23586,7 +23486,7 @@ pub mod api { pub fn preimage_for_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::preimage_for::PreimageFor, (), (), @@ -23595,7 +23495,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "PreimageFor", - vec![], + (), [ 106u8, 5u8, 17u8, 46u8, 6u8, 184u8, 177u8, 113u8, 169u8, 34u8, 119u8, 141u8, 117u8, 40u8, 30u8, 94u8, 187u8, 35u8, 206u8, 216u8, 143u8, @@ -23608,7 +23508,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::preimage_for::PreimageFor, (), (), @@ -23617,9 +23517,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "PreimageFor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 106u8, 5u8, 17u8, 46u8, 6u8, 184u8, 177u8, 113u8, 169u8, 34u8, 119u8, 141u8, 117u8, 40u8, 30u8, 94u8, 187u8, 35u8, 206u8, 216u8, 143u8, @@ -23633,7 +23531,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::preimage_for::PreimageFor, ::subxt::storage::address::Yes, (), @@ -23642,10 +23543,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "PreimageFor", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 106u8, 5u8, 17u8, 46u8, 6u8, 184u8, 177u8, 113u8, 169u8, 34u8, 119u8, 141u8, 117u8, 40u8, 30u8, 94u8, 187u8, 35u8, 206u8, 216u8, 143u8, @@ -23904,7 +23805,7 @@ pub mod api { pub fn conversion_rate_to_native_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::conversion_rate_to_native::ConversionRateToNative, (), (), @@ -23913,7 +23814,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssetRate", "ConversionRateToNative", - vec![], + (), [ 230u8, 127u8, 110u8, 126u8, 79u8, 168u8, 134u8, 97u8, 195u8, 105u8, 16u8, 57u8, 197u8, 104u8, 87u8, 144u8, 83u8, 188u8, 85u8, 253u8, 230u8, @@ -23929,7 +23830,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::conversion_rate_to_native::ConversionRateToNative, ::subxt::storage::address::Yes, (), @@ -23938,9 +23839,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssetRate", "ConversionRateToNative", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 230u8, 127u8, 110u8, 126u8, 79u8, 168u8, 134u8, 97u8, 195u8, 105u8, 16u8, 57u8, 197u8, 104u8, 87u8, 144u8, 83u8, 188u8, 85u8, 253u8, 230u8, @@ -24649,7 +24548,7 @@ pub mod api { pub fn bounty_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::bounty_count::BountyCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -24658,7 +24557,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Bounties", "BountyCount", - vec![], + (), [ 120u8, 204u8, 26u8, 150u8, 37u8, 81u8, 43u8, 223u8, 180u8, 252u8, 142u8, 144u8, 109u8, 5u8, 184u8, 72u8, 223u8, 230u8, 66u8, 196u8, 14u8, @@ -24671,7 +24570,7 @@ pub mod api { pub fn bounties_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::bounties::Bounties, (), (), @@ -24680,7 +24579,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Bounties", "Bounties", - vec![], + (), [ 183u8, 96u8, 172u8, 86u8, 167u8, 129u8, 51u8, 179u8, 238u8, 155u8, 196u8, 77u8, 158u8, 102u8, 188u8, 19u8, 79u8, 178u8, 145u8, 189u8, @@ -24694,7 +24593,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::bounties::Bounties, ::subxt::storage::address::Yes, (), @@ -24703,9 +24602,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Bounties", "Bounties", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 183u8, 96u8, 172u8, 86u8, 167u8, 129u8, 51u8, 179u8, 238u8, 155u8, 196u8, 77u8, 158u8, 102u8, 188u8, 19u8, 79u8, 178u8, 145u8, 189u8, @@ -24718,7 +24615,7 @@ pub mod api { pub fn bounty_descriptions_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::bounty_descriptions::BountyDescriptions, (), (), @@ -24727,7 +24624,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Bounties", "BountyDescriptions", - vec![], + (), [ 71u8, 40u8, 133u8, 84u8, 55u8, 207u8, 169u8, 189u8, 160u8, 51u8, 202u8, 144u8, 15u8, 226u8, 97u8, 114u8, 54u8, 247u8, 53u8, 26u8, 36u8, 54u8, @@ -24740,7 +24637,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::bounty_descriptions::BountyDescriptions, ::subxt::storage::address::Yes, (), @@ -24749,9 +24646,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Bounties", "BountyDescriptions", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 71u8, 40u8, 133u8, 84u8, 55u8, 207u8, 169u8, 189u8, 160u8, 51u8, 202u8, 144u8, 15u8, 226u8, 97u8, 114u8, 54u8, 247u8, 53u8, 26u8, 36u8, 54u8, @@ -24763,7 +24658,7 @@ pub mod api { pub fn bounty_approvals( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::bounty_approvals::BountyApprovals, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -24772,7 +24667,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Bounties", "BountyApprovals", - vec![], + (), [ 182u8, 228u8, 0u8, 46u8, 176u8, 25u8, 222u8, 180u8, 51u8, 57u8, 14u8, 0u8, 69u8, 160u8, 64u8, 27u8, 88u8, 29u8, 227u8, 146u8, 2u8, 121u8, @@ -25440,7 +25335,7 @@ pub mod api { pub fn child_bounty_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::child_bounty_count::ChildBountyCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -25449,7 +25344,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildBountyCount", - vec![], + (), [ 206u8, 1u8, 40u8, 132u8, 51u8, 139u8, 234u8, 20u8, 89u8, 86u8, 247u8, 107u8, 169u8, 252u8, 5u8, 180u8, 218u8, 24u8, 232u8, 94u8, 82u8, 135u8, @@ -25462,7 +25357,7 @@ pub mod api { pub fn parent_child_bounties_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::parent_child_bounties::ParentChildBounties, (), ::subxt::storage::address::Yes, @@ -25471,7 +25366,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ParentChildBounties", - vec![], + (), [ 52u8, 179u8, 242u8, 212u8, 91u8, 185u8, 176u8, 52u8, 100u8, 200u8, 1u8, 41u8, 184u8, 234u8, 234u8, 8u8, 123u8, 252u8, 131u8, 55u8, 109u8, @@ -25485,7 +25380,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::parent_child_bounties::ParentChildBounties, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -25494,9 +25389,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ParentChildBounties", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 52u8, 179u8, 242u8, 212u8, 91u8, 185u8, 176u8, 52u8, 100u8, 200u8, 1u8, 41u8, 184u8, 234u8, 234u8, 8u8, 123u8, 252u8, 131u8, 55u8, 109u8, @@ -25508,7 +25401,7 @@ pub mod api { pub fn child_bounties_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::child_bounties::ChildBounties, (), (), @@ -25517,7 +25410,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildBounties", - vec![], + (), [ 165u8, 240u8, 158u8, 204u8, 183u8, 190u8, 129u8, 65u8, 226u8, 8u8, 182u8, 103u8, 46u8, 162u8, 35u8, 155u8, 131u8, 45u8, 163u8, 64u8, @@ -25531,7 +25424,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::child_bounties::ChildBounties, (), (), @@ -25540,9 +25433,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildBounties", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 165u8, 240u8, 158u8, 204u8, 183u8, 190u8, 129u8, 65u8, 226u8, 8u8, 182u8, 103u8, 46u8, 162u8, 35u8, 155u8, 131u8, 45u8, 163u8, 64u8, @@ -25557,7 +25448,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::child_bounties::ChildBounties, ::subxt::storage::address::Yes, (), @@ -25566,10 +25460,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildBounties", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 165u8, 240u8, 158u8, 204u8, 183u8, 190u8, 129u8, 65u8, 226u8, 8u8, 182u8, 103u8, 46u8, 162u8, 35u8, 155u8, 131u8, 45u8, 163u8, 64u8, @@ -25582,7 +25476,7 @@ pub mod api { pub fn child_bounty_descriptions_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::child_bounty_descriptions::ChildBountyDescriptions, (), (), @@ -25591,7 +25485,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildBountyDescriptions", - vec![], + (), [ 192u8, 0u8, 220u8, 156u8, 109u8, 65u8, 113u8, 102u8, 119u8, 0u8, 109u8, 141u8, 211u8, 128u8, 237u8, 61u8, 28u8, 56u8, 206u8, 93u8, 183u8, 74u8, @@ -25604,7 +25498,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::child_bounty_descriptions::ChildBountyDescriptions, ::subxt::storage::address::Yes, (), @@ -25613,9 +25507,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildBountyDescriptions", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 192u8, 0u8, 220u8, 156u8, 109u8, 65u8, 113u8, 102u8, 119u8, 0u8, 109u8, 141u8, 211u8, 128u8, 237u8, 61u8, 28u8, 56u8, 206u8, 93u8, 183u8, 74u8, @@ -25627,7 +25519,7 @@ pub mod api { pub fn children_curator_fees_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::children_curator_fees::ChildrenCuratorFees, (), ::subxt::storage::address::Yes, @@ -25636,7 +25528,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildrenCuratorFees", - vec![], + (), [ 32u8, 16u8, 190u8, 193u8, 6u8, 80u8, 163u8, 16u8, 85u8, 111u8, 39u8, 141u8, 209u8, 70u8, 213u8, 167u8, 22u8, 12u8, 93u8, 17u8, 104u8, 94u8, @@ -25649,7 +25541,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::children_curator_fees::ChildrenCuratorFees, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -25658,9 +25550,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildrenCuratorFees", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 32u8, 16u8, 190u8, 193u8, 6u8, 80u8, 163u8, 16u8, 85u8, 111u8, 39u8, 141u8, 209u8, 70u8, 213u8, 167u8, 22u8, 12u8, 93u8, 17u8, 104u8, 94u8, @@ -26246,7 +26136,7 @@ pub mod api { pub fn queue_totals( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::queue_totals::QueueTotals, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -26255,7 +26145,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Nis", "QueueTotals", - vec![], + (), [ 40u8, 120u8, 43u8, 203u8, 97u8, 129u8, 61u8, 184u8, 137u8, 45u8, 201u8, 90u8, 227u8, 161u8, 52u8, 179u8, 9u8, 74u8, 104u8, 225u8, 209u8, 62u8, @@ -26267,7 +26157,7 @@ pub mod api { pub fn queues_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::queues::Queues, (), ::subxt::storage::address::Yes, @@ -26276,7 +26166,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Nis", "Queues", - vec![], + (), [ 144u8, 181u8, 173u8, 134u8, 6u8, 165u8, 174u8, 91u8, 75u8, 241u8, 142u8, 192u8, 246u8, 71u8, 132u8, 146u8, 181u8, 158u8, 125u8, 34u8, @@ -26290,7 +26180,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::queues::Queues, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -26299,9 +26189,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Nis", "Queues", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 144u8, 181u8, 173u8, 134u8, 6u8, 165u8, 174u8, 91u8, 75u8, 241u8, 142u8, 192u8, 246u8, 71u8, 132u8, 146u8, 181u8, 158u8, 125u8, 34u8, @@ -26314,7 +26202,7 @@ pub mod api { pub fn summary( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::summary::Summary, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -26323,7 +26211,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Nis", "Summary", - vec![], + (), [ 106u8, 21u8, 103u8, 47u8, 211u8, 234u8, 50u8, 222u8, 25u8, 209u8, 67u8, 117u8, 111u8, 6u8, 231u8, 245u8, 109u8, 52u8, 177u8, 20u8, 179u8, @@ -26336,7 +26224,7 @@ pub mod api { pub fn receipts_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::receipts::Receipts, (), (), @@ -26345,7 +26233,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Nis", "Receipts", - vec![], + (), [ 123u8, 179u8, 0u8, 14u8, 5u8, 132u8, 165u8, 192u8, 163u8, 22u8, 174u8, 22u8, 252u8, 44u8, 167u8, 22u8, 116u8, 170u8, 186u8, 118u8, 131u8, 5u8, @@ -26358,7 +26246,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::receipts::Receipts, ::subxt::storage::address::Yes, (), @@ -26367,9 +26255,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Nis", "Receipts", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 123u8, 179u8, 0u8, 14u8, 5u8, 132u8, 165u8, 192u8, 163u8, 22u8, 174u8, 22u8, 252u8, 44u8, 167u8, 22u8, 116u8, 170u8, 186u8, 118u8, 131u8, 5u8, @@ -27440,7 +27326,7 @@ pub mod api { pub fn total_issuance( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::total_issuance::TotalIssuance, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27449,7 +27335,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "TotalIssuance", - vec![], + (), [ 116u8, 70u8, 119u8, 194u8, 69u8, 37u8, 116u8, 206u8, 171u8, 70u8, 171u8, 210u8, 226u8, 111u8, 184u8, 204u8, 206u8, 11u8, 68u8, 72u8, @@ -27462,7 +27348,7 @@ pub mod api { pub fn inactive_issuance( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::inactive_issuance::InactiveIssuance, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27471,7 +27357,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "InactiveIssuance", - vec![], + (), [ 212u8, 185u8, 19u8, 50u8, 250u8, 72u8, 173u8, 50u8, 4u8, 104u8, 161u8, 249u8, 77u8, 247u8, 204u8, 248u8, 11u8, 18u8, 57u8, 4u8, 82u8, 110u8, @@ -27506,7 +27392,7 @@ pub mod api { pub fn account_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::account::Account, (), ::subxt::storage::address::Yes, @@ -27515,7 +27401,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Account", - vec![], + (), [ 213u8, 38u8, 200u8, 69u8, 218u8, 0u8, 112u8, 181u8, 160u8, 23u8, 96u8, 90u8, 3u8, 88u8, 126u8, 22u8, 103u8, 74u8, 64u8, 69u8, 29u8, 247u8, @@ -27551,7 +27437,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::account::Account, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27560,9 +27446,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Account", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 213u8, 38u8, 200u8, 69u8, 218u8, 0u8, 112u8, 181u8, 160u8, 23u8, 96u8, 90u8, 3u8, 88u8, 126u8, 22u8, 103u8, 74u8, 64u8, 69u8, 29u8, 247u8, @@ -27575,7 +27459,7 @@ pub mod api { pub fn locks_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::locks::Locks, (), ::subxt::storage::address::Yes, @@ -27584,7 +27468,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Locks", - vec![], + (), [ 10u8, 223u8, 55u8, 0u8, 249u8, 69u8, 168u8, 41u8, 75u8, 35u8, 120u8, 167u8, 18u8, 132u8, 9u8, 20u8, 91u8, 51u8, 27u8, 69u8, 136u8, 187u8, @@ -27598,7 +27482,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::locks::Locks, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27607,9 +27491,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Locks", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 10u8, 223u8, 55u8, 0u8, 249u8, 69u8, 168u8, 41u8, 75u8, 35u8, 120u8, 167u8, 18u8, 132u8, 9u8, 20u8, 91u8, 51u8, 27u8, 69u8, 136u8, 187u8, @@ -27621,7 +27503,7 @@ pub mod api { pub fn reserves_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::reserves::Reserves, (), ::subxt::storage::address::Yes, @@ -27630,7 +27512,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Reserves", - vec![], + (), [ 112u8, 10u8, 241u8, 77u8, 64u8, 187u8, 106u8, 159u8, 13u8, 153u8, 140u8, 178u8, 182u8, 50u8, 1u8, 55u8, 149u8, 92u8, 196u8, 229u8, 170u8, @@ -27643,7 +27525,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::reserves::Reserves, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27652,9 +27534,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Reserves", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 112u8, 10u8, 241u8, 77u8, 64u8, 187u8, 106u8, 159u8, 13u8, 153u8, 140u8, 178u8, 182u8, 50u8, 1u8, 55u8, 149u8, 92u8, 196u8, 229u8, 170u8, @@ -27666,7 +27546,7 @@ pub mod api { pub fn holds_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::holds::Holds, (), ::subxt::storage::address::Yes, @@ -27675,7 +27555,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Holds", - vec![], + (), [ 181u8, 39u8, 29u8, 45u8, 45u8, 198u8, 129u8, 210u8, 189u8, 183u8, 121u8, 125u8, 57u8, 90u8, 95u8, 107u8, 51u8, 13u8, 22u8, 105u8, 191u8, @@ -27689,7 +27569,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::holds::Holds, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27698,9 +27578,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Holds", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 181u8, 39u8, 29u8, 45u8, 45u8, 198u8, 129u8, 210u8, 189u8, 183u8, 121u8, 125u8, 57u8, 90u8, 95u8, 107u8, 51u8, 13u8, 22u8, 105u8, 191u8, @@ -27713,7 +27591,7 @@ pub mod api { pub fn freezes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::freezes::Freezes, (), ::subxt::storage::address::Yes, @@ -27722,7 +27600,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Freezes", - vec![], + (), [ 69u8, 49u8, 165u8, 76u8, 135u8, 142u8, 179u8, 118u8, 50u8, 109u8, 53u8, 112u8, 110u8, 94u8, 30u8, 93u8, 173u8, 38u8, 27u8, 142u8, 19u8, 5u8, @@ -27735,7 +27613,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::freezes::Freezes, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27744,9 +27622,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Freezes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 69u8, 49u8, 165u8, 76u8, 135u8, 142u8, 179u8, 118u8, 50u8, 109u8, 53u8, 112u8, 110u8, 94u8, 30u8, 93u8, 173u8, 38u8, 27u8, 142u8, 19u8, 5u8, @@ -29705,7 +29581,7 @@ pub mod api { pub fn active_config( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::active_config::ActiveConfig, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -29714,7 +29590,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Configuration", "ActiveConfig", - vec![], + (), [ 241u8, 129u8, 175u8, 69u8, 121u8, 171u8, 135u8, 98u8, 205u8, 87u8, 244u8, 201u8, 27u8, 143u8, 112u8, 77u8, 83u8, 107u8, 22u8, 120u8, 58u8, @@ -29732,7 +29608,7 @@ pub mod api { pub fn pending_configs( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pending_configs::PendingConfigs, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -29741,7 +29617,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Configuration", "PendingConfigs", - vec![], + (), [ 29u8, 220u8, 218u8, 233u8, 222u8, 28u8, 203u8, 86u8, 0u8, 34u8, 78u8, 157u8, 206u8, 57u8, 211u8, 206u8, 34u8, 22u8, 126u8, 92u8, 13u8, 71u8, @@ -29754,7 +29630,7 @@ pub mod api { pub fn bypass_consistency_check( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::bypass_consistency_check::BypassConsistencyCheck, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -29763,7 +29639,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Configuration", "BypassConsistencyCheck", - vec![], + (), [ 109u8, 201u8, 130u8, 189u8, 167u8, 112u8, 171u8, 180u8, 100u8, 146u8, 23u8, 174u8, 199u8, 230u8, 185u8, 155u8, 178u8, 45u8, 24u8, 66u8, @@ -29820,7 +29696,7 @@ pub mod api { pub fn current_session_index( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::current_session_index::CurrentSessionIndex, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -29829,7 +29705,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasShared", "CurrentSessionIndex", - vec![], + (), [ 250u8, 164u8, 179u8, 84u8, 199u8, 245u8, 116u8, 48u8, 86u8, 127u8, 50u8, 117u8, 236u8, 41u8, 107u8, 238u8, 151u8, 236u8, 68u8, 78u8, @@ -29843,7 +29719,7 @@ pub mod api { pub fn active_validator_indices( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::active_validator_indices::ActiveValidatorIndices, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -29852,7 +29728,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasShared", "ActiveValidatorIndices", - vec![], + (), [ 80u8, 207u8, 217u8, 195u8, 69u8, 151u8, 27u8, 205u8, 227u8, 89u8, 71u8, 180u8, 91u8, 116u8, 82u8, 193u8, 108u8, 115u8, 40u8, 247u8, 160u8, @@ -29865,7 +29741,7 @@ pub mod api { pub fn active_validator_keys( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::active_validator_keys::ActiveValidatorKeys, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -29874,7 +29750,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasShared", "ActiveValidatorKeys", - vec![], + (), [ 155u8, 151u8, 155u8, 8u8, 23u8, 38u8, 91u8, 12u8, 94u8, 69u8, 228u8, 185u8, 14u8, 219u8, 215u8, 98u8, 235u8, 222u8, 157u8, 180u8, 230u8, @@ -29887,7 +29763,7 @@ pub mod api { pub fn allowed_relay_parents( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::allowed_relay_parents::AllowedRelayParents, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -29896,7 +29772,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasShared", "AllowedRelayParents", - vec![], + (), [ 12u8, 170u8, 241u8, 120u8, 39u8, 216u8, 90u8, 37u8, 119u8, 212u8, 161u8, 90u8, 233u8, 124u8, 92u8, 43u8, 212u8, 206u8, 153u8, 103u8, @@ -30071,7 +29947,7 @@ pub mod api { pub fn availability_bitfields_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::availability_bitfields::AvailabilityBitfields, (), (), @@ -30080,7 +29956,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "AvailabilityBitfields", - vec![], + (), [ 163u8, 169u8, 217u8, 160u8, 147u8, 165u8, 186u8, 21u8, 171u8, 177u8, 74u8, 69u8, 55u8, 205u8, 46u8, 13u8, 253u8, 83u8, 55u8, 190u8, 22u8, @@ -30093,7 +29969,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::availability_bitfields::AvailabilityBitfields, ::subxt::storage::address::Yes, (), @@ -30102,9 +29978,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "AvailabilityBitfields", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 163u8, 169u8, 217u8, 160u8, 147u8, 165u8, 186u8, 21u8, 171u8, 177u8, 74u8, 69u8, 55u8, 205u8, 46u8, 13u8, 253u8, 83u8, 55u8, 190u8, 22u8, @@ -30116,7 +29990,7 @@ pub mod api { pub fn pending_availability_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pending_availability::PendingAvailability, (), (), @@ -30125,7 +29999,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "PendingAvailability", - vec![], + (), [ 164u8, 175u8, 34u8, 182u8, 190u8, 147u8, 42u8, 185u8, 162u8, 130u8, 33u8, 159u8, 234u8, 242u8, 90u8, 119u8, 2u8, 195u8, 48u8, 150u8, 135u8, @@ -30138,7 +30012,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::pending_availability::PendingAvailability, ::subxt::storage::address::Yes, (), @@ -30147,9 +30021,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "PendingAvailability", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 164u8, 175u8, 34u8, 182u8, 190u8, 147u8, 42u8, 185u8, 162u8, 130u8, 33u8, 159u8, 234u8, 242u8, 90u8, 119u8, 2u8, 195u8, 48u8, 150u8, 135u8, @@ -30161,7 +30033,7 @@ pub mod api { pub fn pending_availability_commitments_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pending_availability_commitments::PendingAvailabilityCommitments, (), (), @@ -30170,7 +30042,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "PendingAvailabilityCommitments", - vec![], + (), [ 196u8, 210u8, 210u8, 16u8, 246u8, 105u8, 121u8, 178u8, 5u8, 48u8, 40u8, 183u8, 63u8, 147u8, 48u8, 74u8, 20u8, 83u8, 76u8, 84u8, 41u8, 30u8, @@ -30183,7 +30055,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::pending_availability_commitments::Param0, + >, types::pending_availability_commitments::PendingAvailabilityCommitments, ::subxt::storage::address::Yes, (), @@ -30192,9 +30066,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "PendingAvailabilityCommitments", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 196u8, 210u8, 210u8, 16u8, 246u8, 105u8, 121u8, 178u8, 5u8, 48u8, 40u8, 183u8, 63u8, 147u8, 48u8, 74u8, 20u8, 83u8, 76u8, 84u8, 41u8, 30u8, @@ -30291,7 +30163,7 @@ pub mod api { pub fn included( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::included::Included, ::subxt::storage::address::Yes, (), @@ -30300,7 +30172,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInherent", "Included", - vec![], + (), [ 108u8, 164u8, 163u8, 34u8, 27u8, 124u8, 202u8, 167u8, 48u8, 130u8, 155u8, 211u8, 148u8, 130u8, 76u8, 16u8, 5u8, 250u8, 211u8, 174u8, 90u8, @@ -30312,7 +30184,7 @@ pub mod api { pub fn on_chain_votes( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::on_chain_votes::OnChainVotes, ::subxt::storage::address::Yes, (), @@ -30321,7 +30193,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInherent", "OnChainVotes", - vec![], + (), [ 65u8, 20u8, 36u8, 37u8, 239u8, 150u8, 32u8, 78u8, 226u8, 88u8, 80u8, 240u8, 12u8, 156u8, 176u8, 75u8, 231u8, 204u8, 37u8, 24u8, 204u8, @@ -30375,7 +30247,7 @@ pub mod api { pub fn validator_groups( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::validator_groups::ValidatorGroups, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -30384,7 +30256,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaScheduler", "ValidatorGroups", - vec![], + (), [ 129u8, 58u8, 65u8, 112u8, 4u8, 172u8, 167u8, 19u8, 96u8, 154u8, 159u8, 83u8, 94u8, 125u8, 60u8, 43u8, 60u8, 70u8, 1u8, 58u8, 222u8, 31u8, @@ -30403,7 +30275,7 @@ pub mod api { pub fn availability_cores( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::availability_cores::AvailabilityCores, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -30412,7 +30284,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaScheduler", "AvailabilityCores", - vec![], + (), [ 250u8, 177u8, 44u8, 237u8, 5u8, 116u8, 135u8, 99u8, 136u8, 209u8, 181u8, 145u8, 254u8, 57u8, 42u8, 92u8, 236u8, 67u8, 128u8, 171u8, @@ -30431,7 +30303,7 @@ pub mod api { pub fn session_start_block( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::session_start_block::SessionStartBlock, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -30440,7 +30312,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaScheduler", "SessionStartBlock", - vec![], + (), [ 185u8, 76u8, 120u8, 75u8, 154u8, 31u8, 33u8, 243u8, 16u8, 77u8, 100u8, 249u8, 21u8, 44u8, 199u8, 195u8, 37u8, 9u8, 218u8, 148u8, 222u8, 90u8, @@ -30456,7 +30328,7 @@ pub mod api { pub fn claim_queue( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::claim_queue::ClaimQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -30465,7 +30337,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaScheduler", "ClaimQueue", - vec![], + (), [ 192u8, 65u8, 227u8, 114u8, 125u8, 169u8, 134u8, 70u8, 201u8, 99u8, 246u8, 23u8, 0u8, 143u8, 163u8, 87u8, 216u8, 1u8, 184u8, 124u8, 23u8, @@ -31195,7 +31067,7 @@ pub mod api { pub fn pvf_active_vote_map_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pvf_active_vote_map::PvfActiveVoteMap, (), (), @@ -31204,7 +31076,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PvfActiveVoteMap", - vec![], + (), [ 72u8, 55u8, 139u8, 104u8, 161u8, 63u8, 114u8, 153u8, 16u8, 221u8, 60u8, 88u8, 52u8, 207u8, 123u8, 193u8, 11u8, 30u8, 19u8, 39u8, 231u8, 39u8, @@ -31220,7 +31092,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::pvf_active_vote_map::PvfActiveVoteMap, ::subxt::storage::address::Yes, (), @@ -31229,9 +31101,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PvfActiveVoteMap", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 72u8, 55u8, 139u8, 104u8, 161u8, 63u8, 114u8, 153u8, 16u8, 221u8, 60u8, 88u8, 52u8, 207u8, 123u8, 193u8, 11u8, 30u8, 19u8, 39u8, 231u8, 39u8, @@ -31243,7 +31113,7 @@ pub mod api { pub fn pvf_active_vote_list( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pvf_active_vote_list::PvfActiveVoteList, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31252,7 +31122,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PvfActiveVoteList", - vec![], + (), [ 172u8, 215u8, 137u8, 191u8, 52u8, 104u8, 106u8, 118u8, 134u8, 82u8, 137u8, 6u8, 175u8, 158u8, 58u8, 230u8, 231u8, 152u8, 195u8, 17u8, 51u8, @@ -31267,7 +31137,7 @@ pub mod api { pub fn parachains( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::parachains::Parachains, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31276,7 +31146,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "Parachains", - vec![], + (), [ 242u8, 228u8, 175u8, 107u8, 242u8, 39u8, 52u8, 181u8, 32u8, 171u8, 21u8, 169u8, 204u8, 19u8, 21u8, 217u8, 121u8, 239u8, 218u8, 252u8, @@ -31289,7 +31159,7 @@ pub mod api { pub fn para_lifecycles_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::para_lifecycles::ParaLifecycles, (), (), @@ -31298,7 +31168,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "ParaLifecycles", - vec![], + (), [ 2u8, 203u8, 32u8, 194u8, 76u8, 227u8, 250u8, 9u8, 168u8, 201u8, 171u8, 180u8, 18u8, 169u8, 206u8, 183u8, 48u8, 189u8, 204u8, 192u8, 237u8, @@ -31312,7 +31182,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::para_lifecycles::ParaLifecycles, ::subxt::storage::address::Yes, (), @@ -31321,9 +31191,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "ParaLifecycles", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 2u8, 203u8, 32u8, 194u8, 76u8, 227u8, 250u8, 9u8, 168u8, 201u8, 171u8, 180u8, 18u8, 169u8, 206u8, 183u8, 48u8, 189u8, 204u8, 192u8, 237u8, @@ -31336,7 +31204,7 @@ pub mod api { pub fn heads_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::heads::Heads, (), (), @@ -31345,7 +31213,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "Heads", - vec![], + (), [ 222u8, 116u8, 180u8, 190u8, 172u8, 192u8, 174u8, 132u8, 225u8, 180u8, 119u8, 90u8, 5u8, 39u8, 92u8, 230u8, 116u8, 202u8, 92u8, 99u8, 135u8, @@ -31358,7 +31226,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::heads::Heads, ::subxt::storage::address::Yes, (), @@ -31367,9 +31235,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "Heads", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 222u8, 116u8, 180u8, 190u8, 172u8, 192u8, 174u8, 132u8, 225u8, 180u8, 119u8, 90u8, 5u8, 39u8, 92u8, 230u8, 116u8, 202u8, 92u8, 99u8, 135u8, @@ -31381,7 +31247,7 @@ pub mod api { pub fn most_recent_context_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::most_recent_context::MostRecentContext, (), (), @@ -31390,7 +31256,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "MostRecentContext", - vec![], + (), [ 196u8, 150u8, 125u8, 121u8, 196u8, 182u8, 2u8, 5u8, 244u8, 170u8, 75u8, 57u8, 162u8, 8u8, 104u8, 94u8, 114u8, 32u8, 192u8, 236u8, 120u8, 91u8, @@ -31403,7 +31269,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::most_recent_context::MostRecentContext, ::subxt::storage::address::Yes, (), @@ -31412,9 +31278,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "MostRecentContext", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 196u8, 150u8, 125u8, 121u8, 196u8, 182u8, 2u8, 5u8, 244u8, 170u8, 75u8, 57u8, 162u8, 8u8, 104u8, 94u8, 114u8, 32u8, 192u8, 236u8, 120u8, 91u8, @@ -31428,7 +31292,7 @@ pub mod api { pub fn current_code_hash_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::current_code_hash::CurrentCodeHash, (), (), @@ -31437,7 +31301,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CurrentCodeHash", - vec![], + (), [ 251u8, 100u8, 30u8, 46u8, 191u8, 60u8, 45u8, 221u8, 218u8, 20u8, 154u8, 233u8, 211u8, 198u8, 151u8, 195u8, 99u8, 210u8, 126u8, 165u8, 240u8, @@ -31453,7 +31317,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::current_code_hash::CurrentCodeHash, ::subxt::storage::address::Yes, (), @@ -31462,9 +31326,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CurrentCodeHash", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 251u8, 100u8, 30u8, 46u8, 191u8, 60u8, 45u8, 221u8, 218u8, 20u8, 154u8, 233u8, 211u8, 198u8, 151u8, 195u8, 99u8, 210u8, 126u8, 165u8, 240u8, @@ -31480,7 +31342,7 @@ pub mod api { pub fn past_code_hash_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::past_code_hash::PastCodeHash, (), (), @@ -31489,7 +31351,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PastCodeHash", - vec![], + (), [ 73u8, 209u8, 188u8, 36u8, 127u8, 42u8, 171u8, 136u8, 29u8, 126u8, 220u8, 209u8, 230u8, 22u8, 12u8, 63u8, 8u8, 102u8, 45u8, 158u8, 178u8, @@ -31505,7 +31367,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::past_code_hash::PastCodeHash, (), (), @@ -31514,9 +31376,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PastCodeHash", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 73u8, 209u8, 188u8, 36u8, 127u8, 42u8, 171u8, 136u8, 29u8, 126u8, 220u8, 209u8, 230u8, 22u8, 12u8, 63u8, 8u8, 102u8, 45u8, 158u8, 178u8, @@ -31533,7 +31393,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::past_code_hash::PastCodeHash, ::subxt::storage::address::Yes, (), @@ -31542,10 +31405,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PastCodeHash", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 73u8, 209u8, 188u8, 36u8, 127u8, 42u8, 171u8, 136u8, 29u8, 126u8, 220u8, 209u8, 230u8, 22u8, 12u8, 63u8, 8u8, 102u8, 45u8, 158u8, 178u8, @@ -31559,7 +31422,7 @@ pub mod api { pub fn past_code_meta_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::past_code_meta::PastCodeMeta, (), ::subxt::storage::address::Yes, @@ -31568,7 +31431,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PastCodeMeta", - vec![], + (), [ 233u8, 47u8, 137u8, 174u8, 98u8, 64u8, 11u8, 75u8, 93u8, 222u8, 78u8, 58u8, 66u8, 245u8, 151u8, 39u8, 144u8, 36u8, 84u8, 176u8, 239u8, 183u8, @@ -31583,7 +31446,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::past_code_meta::PastCodeMeta, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31592,9 +31455,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PastCodeMeta", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 233u8, 47u8, 137u8, 174u8, 98u8, 64u8, 11u8, 75u8, 93u8, 222u8, 78u8, 58u8, 66u8, 245u8, 151u8, 39u8, 144u8, 36u8, 84u8, 176u8, 239u8, 183u8, @@ -31611,7 +31472,7 @@ pub mod api { pub fn past_code_pruning( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::past_code_pruning::PastCodePruning, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31620,7 +31481,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PastCodePruning", - vec![], + (), [ 67u8, 190u8, 51u8, 133u8, 173u8, 24u8, 151u8, 111u8, 108u8, 152u8, 106u8, 18u8, 29u8, 80u8, 104u8, 120u8, 91u8, 138u8, 209u8, 49u8, 255u8, @@ -31634,7 +31495,7 @@ pub mod api { pub fn future_code_upgrades_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::future_code_upgrades::FutureCodeUpgrades, (), (), @@ -31643,7 +31504,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "FutureCodeUpgrades", - vec![], + (), [ 163u8, 168u8, 23u8, 138u8, 198u8, 70u8, 135u8, 221u8, 167u8, 187u8, 15u8, 144u8, 228u8, 8u8, 138u8, 125u8, 101u8, 154u8, 11u8, 74u8, 173u8, @@ -31658,7 +31519,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::future_code_upgrades::FutureCodeUpgrades, ::subxt::storage::address::Yes, (), @@ -31667,9 +31528,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "FutureCodeUpgrades", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 163u8, 168u8, 23u8, 138u8, 198u8, 70u8, 135u8, 221u8, 167u8, 187u8, 15u8, 144u8, 228u8, 8u8, 138u8, 125u8, 101u8, 154u8, 11u8, 74u8, 173u8, @@ -31683,7 +31542,7 @@ pub mod api { pub fn future_code_hash_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::future_code_hash::FutureCodeHash, (), (), @@ -31692,7 +31551,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "FutureCodeHash", - vec![], + (), [ 62u8, 238u8, 183u8, 12u8, 197u8, 119u8, 163u8, 239u8, 192u8, 228u8, 110u8, 58u8, 128u8, 223u8, 32u8, 137u8, 109u8, 127u8, 41u8, 83u8, 91u8, @@ -31707,7 +31566,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::future_code_hash::FutureCodeHash, ::subxt::storage::address::Yes, (), @@ -31716,9 +31575,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "FutureCodeHash", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 62u8, 238u8, 183u8, 12u8, 197u8, 119u8, 163u8, 239u8, 192u8, 228u8, 110u8, 58u8, 128u8, 223u8, 32u8, 137u8, 109u8, 127u8, 41u8, 83u8, 91u8, @@ -31739,7 +31596,7 @@ pub mod api { pub fn upgrade_go_ahead_signal_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::upgrade_go_ahead_signal::UpgradeGoAheadSignal, (), (), @@ -31748,7 +31605,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpgradeGoAheadSignal", - vec![], + (), [ 41u8, 80u8, 120u8, 6u8, 98u8, 85u8, 36u8, 37u8, 170u8, 189u8, 56u8, 127u8, 155u8, 180u8, 112u8, 195u8, 135u8, 214u8, 235u8, 87u8, 197u8, @@ -31771,7 +31628,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::upgrade_go_ahead_signal::UpgradeGoAheadSignal, ::subxt::storage::address::Yes, (), @@ -31780,9 +31637,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpgradeGoAheadSignal", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 41u8, 80u8, 120u8, 6u8, 98u8, 85u8, 36u8, 37u8, 170u8, 189u8, 56u8, 127u8, 155u8, 180u8, 112u8, 195u8, 135u8, 214u8, 235u8, 87u8, 197u8, @@ -31803,7 +31658,7 @@ pub mod api { pub fn upgrade_restriction_signal_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::upgrade_restriction_signal::UpgradeRestrictionSignal, (), (), @@ -31812,7 +31667,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpgradeRestrictionSignal", - vec![], + (), [ 158u8, 105u8, 62u8, 252u8, 149u8, 145u8, 34u8, 92u8, 119u8, 204u8, 46u8, 96u8, 117u8, 183u8, 134u8, 20u8, 172u8, 243u8, 145u8, 113u8, @@ -31834,7 +31689,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::upgrade_restriction_signal::Param0, + >, types::upgrade_restriction_signal::UpgradeRestrictionSignal, ::subxt::storage::address::Yes, (), @@ -31843,9 +31700,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpgradeRestrictionSignal", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 158u8, 105u8, 62u8, 252u8, 149u8, 145u8, 34u8, 92u8, 119u8, 204u8, 46u8, 96u8, 117u8, 183u8, 134u8, 20u8, 172u8, 243u8, 145u8, 113u8, @@ -31860,7 +31715,7 @@ pub mod api { pub fn upgrade_cooldowns( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::upgrade_cooldowns::UpgradeCooldowns, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31869,7 +31724,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpgradeCooldowns", - vec![], + (), [ 180u8, 197u8, 115u8, 209u8, 126u8, 120u8, 133u8, 54u8, 232u8, 192u8, 47u8, 17u8, 21u8, 8u8, 231u8, 67u8, 1u8, 89u8, 127u8, 38u8, 179u8, @@ -31885,7 +31740,7 @@ pub mod api { pub fn upcoming_upgrades( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::upcoming_upgrades::UpcomingUpgrades, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31894,7 +31749,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpcomingUpgrades", - vec![], + (), [ 38u8, 195u8, 15u8, 56u8, 225u8, 199u8, 105u8, 84u8, 128u8, 51u8, 44u8, 248u8, 237u8, 32u8, 36u8, 72u8, 77u8, 137u8, 124u8, 88u8, 242u8, 185u8, @@ -31906,7 +31761,7 @@ pub mod api { pub fn actions_queue_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::actions_queue::ActionsQueue, (), ::subxt::storage::address::Yes, @@ -31915,7 +31770,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "ActionsQueue", - vec![], + (), [ 13u8, 25u8, 129u8, 203u8, 95u8, 206u8, 254u8, 240u8, 170u8, 209u8, 55u8, 117u8, 70u8, 220u8, 139u8, 102u8, 9u8, 229u8, 139u8, 120u8, 67u8, @@ -31928,7 +31783,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::actions_queue::ActionsQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31937,9 +31792,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "ActionsQueue", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 13u8, 25u8, 129u8, 203u8, 95u8, 206u8, 254u8, 240u8, 170u8, 209u8, 55u8, 117u8, 70u8, 220u8, 139u8, 102u8, 9u8, 229u8, 139u8, 120u8, 67u8, @@ -31954,7 +31807,7 @@ pub mod api { pub fn upcoming_paras_genesis_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::upcoming_paras_genesis::UpcomingParasGenesis, (), (), @@ -31963,7 +31816,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpcomingParasGenesis", - vec![], + (), [ 215u8, 121u8, 106u8, 13u8, 102u8, 47u8, 129u8, 221u8, 153u8, 91u8, 23u8, 94u8, 11u8, 39u8, 19u8, 180u8, 136u8, 136u8, 254u8, 152u8, 250u8, @@ -31980,7 +31833,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::upcoming_paras_genesis::UpcomingParasGenesis, ::subxt::storage::address::Yes, (), @@ -31989,9 +31842,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpcomingParasGenesis", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 215u8, 121u8, 106u8, 13u8, 102u8, 47u8, 129u8, 221u8, 153u8, 91u8, 23u8, 94u8, 11u8, 39u8, 19u8, 180u8, 136u8, 136u8, 254u8, 152u8, 250u8, @@ -32004,7 +31855,7 @@ pub mod api { pub fn code_by_hash_refs_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::code_by_hash_refs::CodeByHashRefs, (), ::subxt::storage::address::Yes, @@ -32013,7 +31864,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CodeByHashRefs", - vec![], + (), [ 47u8, 50u8, 103u8, 161u8, 130u8, 252u8, 157u8, 35u8, 174u8, 37u8, 102u8, 60u8, 195u8, 30u8, 164u8, 203u8, 67u8, 129u8, 107u8, 181u8, @@ -32027,7 +31878,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::code_by_hash_refs::CodeByHashRefs, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -32036,9 +31887,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CodeByHashRefs", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 47u8, 50u8, 103u8, 161u8, 130u8, 252u8, 157u8, 35u8, 174u8, 37u8, 102u8, 60u8, 195u8, 30u8, 164u8, 203u8, 67u8, 129u8, 107u8, 181u8, @@ -32054,7 +31903,7 @@ pub mod api { pub fn code_by_hash_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::code_by_hash::CodeByHash, (), (), @@ -32063,7 +31912,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CodeByHash", - vec![], + (), [ 155u8, 102u8, 73u8, 180u8, 127u8, 211u8, 181u8, 44u8, 56u8, 235u8, 49u8, 4u8, 25u8, 213u8, 116u8, 200u8, 232u8, 203u8, 190u8, 90u8, 93u8, @@ -32079,7 +31928,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::code_by_hash::CodeByHash, ::subxt::storage::address::Yes, (), @@ -32088,9 +31937,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CodeByHash", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 155u8, 102u8, 73u8, 180u8, 127u8, 211u8, 181u8, 44u8, 56u8, 235u8, 49u8, 4u8, 25u8, 213u8, 116u8, 200u8, 232u8, 203u8, 190u8, 90u8, 93u8, @@ -32202,7 +32049,7 @@ pub mod api { pub fn has_initialized( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::has_initialized::HasInitialized, ::subxt::storage::address::Yes, (), @@ -32211,7 +32058,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Initializer", "HasInitialized", - vec![], + (), [ 156u8, 208u8, 212u8, 86u8, 105u8, 148u8, 252u8, 11u8, 140u8, 67u8, 231u8, 86u8, 1u8, 147u8, 178u8, 79u8, 27u8, 249u8, 137u8, 103u8, 178u8, @@ -32229,7 +32076,7 @@ pub mod api { pub fn buffered_session_changes( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::buffered_session_changes::BufferedSessionChanges, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -32238,7 +32085,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Initializer", "BufferedSessionChanges", - vec![], + (), [ 99u8, 153u8, 100u8, 11u8, 28u8, 62u8, 163u8, 239u8, 177u8, 55u8, 151u8, 242u8, 227u8, 59u8, 176u8, 10u8, 227u8, 51u8, 252u8, 191u8, 233u8, @@ -32283,7 +32130,7 @@ pub mod api { pub fn downward_message_queues_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::downward_message_queues::DownwardMessageQueues, (), ::subxt::storage::address::Yes, @@ -32292,7 +32139,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DownwardMessageQueues", - vec![], + (), [ 38u8, 183u8, 133u8, 200u8, 199u8, 135u8, 68u8, 232u8, 189u8, 168u8, 3u8, 219u8, 201u8, 180u8, 156u8, 79u8, 134u8, 164u8, 94u8, 114u8, @@ -32306,7 +32153,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::downward_message_queues::DownwardMessageQueues, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -32315,9 +32162,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DownwardMessageQueues", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 38u8, 183u8, 133u8, 200u8, 199u8, 135u8, 68u8, 232u8, 189u8, 168u8, 3u8, 219u8, 201u8, 180u8, 156u8, 79u8, 134u8, 164u8, 94u8, 114u8, @@ -32336,7 +32181,7 @@ pub mod api { pub fn downward_message_queue_heads_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::downward_message_queue_heads::DownwardMessageQueueHeads, (), ::subxt::storage::address::Yes, @@ -32345,7 +32190,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DownwardMessageQueueHeads", - vec![], + (), [ 135u8, 165u8, 240u8, 0u8, 25u8, 110u8, 9u8, 108u8, 251u8, 225u8, 109u8, 184u8, 90u8, 132u8, 9u8, 151u8, 12u8, 118u8, 153u8, 212u8, 140u8, @@ -32364,7 +32209,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::downward_message_queue_heads::Param0, + >, types::downward_message_queue_heads::DownwardMessageQueueHeads, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -32373,9 +32220,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DownwardMessageQueueHeads", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 135u8, 165u8, 240u8, 0u8, 25u8, 110u8, 9u8, 108u8, 251u8, 225u8, 109u8, 184u8, 90u8, 132u8, 9u8, 151u8, 12u8, 118u8, 153u8, 212u8, 140u8, @@ -32387,7 +32232,7 @@ pub mod api { pub fn delivery_fee_factor_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::delivery_fee_factor::DeliveryFeeFactor, (), ::subxt::storage::address::Yes, @@ -32396,7 +32241,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DeliveryFeeFactor", - vec![], + (), [ 43u8, 5u8, 63u8, 235u8, 115u8, 155u8, 130u8, 27u8, 75u8, 216u8, 177u8, 135u8, 203u8, 147u8, 167u8, 95u8, 208u8, 188u8, 25u8, 14u8, 84u8, 63u8, @@ -32409,7 +32254,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::delivery_fee_factor::DeliveryFeeFactor, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -32418,9 +32263,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DeliveryFeeFactor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 43u8, 5u8, 63u8, 235u8, 115u8, 155u8, 130u8, 27u8, 75u8, 216u8, 177u8, 135u8, 203u8, 147u8, 167u8, 95u8, 208u8, 188u8, 25u8, 14u8, 84u8, 63u8, @@ -33169,7 +33012,7 @@ pub mod api { pub fn hrmp_open_channel_requests_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_open_channel_requests::HrmpOpenChannelRequests, (), (), @@ -33178,7 +33021,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpOpenChannelRequests", - vec![], + (), [ 164u8, 97u8, 52u8, 242u8, 255u8, 67u8, 248u8, 170u8, 204u8, 92u8, 81u8, 144u8, 11u8, 63u8, 145u8, 167u8, 8u8, 174u8, 221u8, 147u8, 125u8, @@ -33197,7 +33040,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::hrmp_open_channel_requests::Param0, + >, types::hrmp_open_channel_requests::HrmpOpenChannelRequests, ::subxt::storage::address::Yes, (), @@ -33206,9 +33051,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpOpenChannelRequests", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 164u8, 97u8, 52u8, 242u8, 255u8, 67u8, 248u8, 170u8, 204u8, 92u8, 81u8, 144u8, 11u8, 63u8, 145u8, 167u8, 8u8, 174u8, 221u8, 147u8, 125u8, @@ -33220,7 +33063,7 @@ pub mod api { pub fn hrmp_open_channel_requests_list( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_open_channel_requests_list::HrmpOpenChannelRequestsList, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33229,7 +33072,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpOpenChannelRequestsList", - vec![], + (), [ 45u8, 190u8, 124u8, 26u8, 37u8, 249u8, 140u8, 254u8, 101u8, 249u8, 27u8, 117u8, 218u8, 3u8, 126u8, 114u8, 143u8, 65u8, 122u8, 246u8, @@ -33244,7 +33087,7 @@ pub mod api { pub fn hrmp_open_channel_request_count_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_open_channel_request_count::HrmpOpenChannelRequestCount, (), ::subxt::storage::address::Yes, @@ -33253,7 +33096,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpOpenChannelRequestCount", - vec![], + (), [ 136u8, 72u8, 56u8, 31u8, 229u8, 99u8, 241u8, 14u8, 159u8, 243u8, 179u8, 222u8, 252u8, 56u8, 63u8, 24u8, 204u8, 130u8, 47u8, 161u8, 133u8, @@ -33269,7 +33112,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::hrmp_open_channel_request_count::Param0, + >, types::hrmp_open_channel_request_count::HrmpOpenChannelRequestCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33278,9 +33123,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpOpenChannelRequestCount", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 136u8, 72u8, 56u8, 31u8, 229u8, 99u8, 241u8, 14u8, 159u8, 243u8, 179u8, 222u8, 252u8, 56u8, 63u8, 24u8, 204u8, 130u8, 47u8, 161u8, 133u8, @@ -33295,7 +33138,7 @@ pub mod api { pub fn hrmp_accepted_channel_request_count_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_accepted_channel_request_count::HrmpAcceptedChannelRequestCount, (), ::subxt::storage::address::Yes, @@ -33304,7 +33147,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpAcceptedChannelRequestCount", - vec![], + (), [ 29u8, 100u8, 52u8, 28u8, 180u8, 84u8, 132u8, 120u8, 117u8, 172u8, 169u8, 40u8, 237u8, 92u8, 89u8, 87u8, 230u8, 148u8, 140u8, 226u8, 60u8, @@ -33320,7 +33163,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::hrmp_accepted_channel_request_count::Param0, + >, types::hrmp_accepted_channel_request_count::HrmpAcceptedChannelRequestCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33329,9 +33174,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpAcceptedChannelRequestCount", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 29u8, 100u8, 52u8, 28u8, 180u8, 84u8, 132u8, 120u8, 117u8, 172u8, 169u8, 40u8, 237u8, 92u8, 89u8, 87u8, 230u8, 148u8, 140u8, 226u8, 60u8, @@ -33350,7 +33193,7 @@ pub mod api { pub fn hrmp_close_channel_requests_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_close_channel_requests::HrmpCloseChannelRequests, (), (), @@ -33359,7 +33202,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpCloseChannelRequests", - vec![], + (), [ 155u8, 13u8, 73u8, 166u8, 58u8, 67u8, 138u8, 58u8, 215u8, 172u8, 241u8, 168u8, 57u8, 4u8, 230u8, 248u8, 31u8, 183u8, 227u8, 224u8, 139u8, @@ -33379,7 +33222,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::hrmp_close_channel_requests::Param0, + >, types::hrmp_close_channel_requests::HrmpCloseChannelRequests, ::subxt::storage::address::Yes, (), @@ -33388,9 +33233,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpCloseChannelRequests", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 155u8, 13u8, 73u8, 166u8, 58u8, 67u8, 138u8, 58u8, 215u8, 172u8, 241u8, 168u8, 57u8, 4u8, 230u8, 248u8, 31u8, 183u8, 227u8, 224u8, 139u8, @@ -33402,7 +33245,7 @@ pub mod api { pub fn hrmp_close_channel_requests_list( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_close_channel_requests_list::HrmpCloseChannelRequestsList, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33411,7 +33254,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpCloseChannelRequestsList", - vec![], + (), [ 78u8, 194u8, 214u8, 232u8, 91u8, 72u8, 109u8, 113u8, 88u8, 86u8, 136u8, 26u8, 226u8, 30u8, 11u8, 188u8, 57u8, 77u8, 169u8, 64u8, 14u8, 187u8, @@ -33426,7 +33269,7 @@ pub mod api { pub fn hrmp_watermarks_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_watermarks::HrmpWatermarks, (), (), @@ -33435,7 +33278,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpWatermarks", - vec![], + (), [ 245u8, 104u8, 137u8, 120u8, 131u8, 7u8, 178u8, 85u8, 96u8, 124u8, 241u8, 2u8, 86u8, 63u8, 116u8, 77u8, 217u8, 235u8, 162u8, 38u8, 104u8, @@ -33451,7 +33294,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::hrmp_watermarks::HrmpWatermarks, ::subxt::storage::address::Yes, (), @@ -33460,9 +33303,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpWatermarks", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 245u8, 104u8, 137u8, 120u8, 131u8, 7u8, 178u8, 85u8, 96u8, 124u8, 241u8, 2u8, 86u8, 63u8, 116u8, 77u8, 217u8, 235u8, 162u8, 38u8, 104u8, @@ -33476,7 +33317,7 @@ pub mod api { pub fn hrmp_channels_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_channels::HrmpChannels, (), (), @@ -33485,7 +33326,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannels", - vec![], + (), [ 174u8, 90u8, 72u8, 93u8, 43u8, 140u8, 181u8, 170u8, 138u8, 171u8, 179u8, 156u8, 33u8, 87u8, 63u8, 1u8, 131u8, 59u8, 230u8, 14u8, 40u8, @@ -33501,7 +33342,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::hrmp_channels::HrmpChannels, ::subxt::storage::address::Yes, (), @@ -33510,9 +33351,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannels", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 174u8, 90u8, 72u8, 93u8, 43u8, 140u8, 181u8, 170u8, 138u8, 171u8, 179u8, 156u8, 33u8, 87u8, 63u8, 1u8, 131u8, 59u8, 230u8, 14u8, 40u8, @@ -33537,7 +33376,7 @@ pub mod api { pub fn hrmp_ingress_channels_index_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_ingress_channels_index::HrmpIngressChannelsIndex, (), ::subxt::storage::address::Yes, @@ -33546,7 +33385,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpIngressChannelsIndex", - vec![], + (), [ 125u8, 229u8, 102u8, 230u8, 74u8, 109u8, 173u8, 67u8, 176u8, 169u8, 57u8, 24u8, 75u8, 129u8, 246u8, 198u8, 63u8, 49u8, 56u8, 102u8, 149u8, @@ -33572,7 +33411,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::hrmp_ingress_channels_index::Param0, + >, types::hrmp_ingress_channels_index::HrmpIngressChannelsIndex, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33581,9 +33422,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpIngressChannelsIndex", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 125u8, 229u8, 102u8, 230u8, 74u8, 109u8, 173u8, 67u8, 176u8, 169u8, 57u8, 24u8, 75u8, 129u8, 246u8, 198u8, 63u8, 49u8, 56u8, 102u8, 149u8, @@ -33595,7 +33434,7 @@ pub mod api { pub fn hrmp_egress_channels_index_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_egress_channels_index::HrmpEgressChannelsIndex, (), ::subxt::storage::address::Yes, @@ -33604,7 +33443,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpEgressChannelsIndex", - vec![], + (), [ 237u8, 183u8, 188u8, 57u8, 20u8, 238u8, 166u8, 7u8, 94u8, 155u8, 22u8, 9u8, 173u8, 209u8, 210u8, 17u8, 160u8, 79u8, 243u8, 4u8, 245u8, 240u8, @@ -33616,7 +33455,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey< + types::hrmp_egress_channels_index::Param0, + >, types::hrmp_egress_channels_index::HrmpEgressChannelsIndex, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33625,9 +33466,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpEgressChannelsIndex", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 237u8, 183u8, 188u8, 57u8, 20u8, 238u8, 166u8, 7u8, 94u8, 155u8, 22u8, 9u8, 173u8, 209u8, 210u8, 17u8, 160u8, 79u8, 243u8, 4u8, 245u8, 240u8, @@ -33640,7 +33479,7 @@ pub mod api { pub fn hrmp_channel_contents_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_channel_contents::HrmpChannelContents, (), ::subxt::storage::address::Yes, @@ -33649,7 +33488,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannelContents", - vec![], + (), [ 55u8, 16u8, 135u8, 69u8, 54u8, 180u8, 246u8, 124u8, 104u8, 92u8, 45u8, 18u8, 223u8, 145u8, 43u8, 190u8, 121u8, 59u8, 35u8, 195u8, 234u8, @@ -33664,7 +33503,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::hrmp_channel_contents::HrmpChannelContents, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33673,9 +33512,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannelContents", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 55u8, 16u8, 135u8, 69u8, 54u8, 180u8, 246u8, 124u8, 104u8, 92u8, 45u8, 18u8, 223u8, 145u8, 43u8, 190u8, 121u8, 59u8, 35u8, 195u8, 234u8, @@ -33693,7 +33530,7 @@ pub mod api { pub fn hrmp_channel_digests_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::hrmp_channel_digests::HrmpChannelDigests, (), ::subxt::storage::address::Yes, @@ -33702,7 +33539,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannelDigests", - vec![], + (), [ 90u8, 90u8, 139u8, 78u8, 47u8, 2u8, 104u8, 211u8, 42u8, 246u8, 193u8, 210u8, 142u8, 223u8, 17u8, 136u8, 3u8, 182u8, 25u8, 56u8, 72u8, 72u8, @@ -33720,7 +33557,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::hrmp_channel_digests::HrmpChannelDigests, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33729,9 +33566,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannelDigests", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 90u8, 90u8, 139u8, 78u8, 47u8, 2u8, 104u8, 211u8, 42u8, 246u8, 193u8, 210u8, 142u8, 223u8, 17u8, 136u8, 3u8, 182u8, 25u8, 56u8, 72u8, 72u8, @@ -33784,7 +33619,7 @@ pub mod api { pub fn assignment_keys_unsafe( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::assignment_keys_unsafe::AssignmentKeysUnsafe, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33793,7 +33628,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "AssignmentKeysUnsafe", - vec![], + (), [ 51u8, 155u8, 91u8, 101u8, 118u8, 243u8, 134u8, 138u8, 147u8, 59u8, 195u8, 186u8, 54u8, 187u8, 36u8, 14u8, 91u8, 141u8, 60u8, 139u8, 28u8, @@ -33805,7 +33640,7 @@ pub mod api { pub fn earliest_stored_session( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::earliest_stored_session::EarliestStoredSession, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33814,7 +33649,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "EarliestStoredSession", - vec![], + (), [ 139u8, 176u8, 46u8, 139u8, 217u8, 35u8, 62u8, 91u8, 183u8, 7u8, 114u8, 226u8, 60u8, 237u8, 105u8, 73u8, 20u8, 216u8, 194u8, 205u8, 178u8, @@ -33828,7 +33663,7 @@ pub mod api { pub fn sessions_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::sessions::Sessions, (), (), @@ -33837,7 +33672,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "Sessions", - vec![], + (), [ 254u8, 40u8, 169u8, 18u8, 252u8, 203u8, 49u8, 182u8, 123u8, 19u8, 241u8, 150u8, 227u8, 153u8, 108u8, 109u8, 66u8, 129u8, 157u8, 27u8, @@ -33853,7 +33688,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::sessions::Sessions, ::subxt::storage::address::Yes, (), @@ -33862,9 +33697,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "Sessions", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 254u8, 40u8, 169u8, 18u8, 252u8, 203u8, 49u8, 182u8, 123u8, 19u8, 241u8, 150u8, 227u8, 153u8, 108u8, 109u8, 66u8, 129u8, 157u8, 27u8, @@ -33877,7 +33710,7 @@ pub mod api { pub fn account_keys_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::account_keys::AccountKeys, (), (), @@ -33886,7 +33719,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "AccountKeys", - vec![], + (), [ 30u8, 98u8, 58u8, 140u8, 96u8, 231u8, 205u8, 111u8, 194u8, 100u8, 185u8, 242u8, 210u8, 143u8, 110u8, 144u8, 170u8, 187u8, 62u8, 196u8, @@ -33900,7 +33733,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::account_keys::AccountKeys, ::subxt::storage::address::Yes, (), @@ -33909,9 +33742,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "AccountKeys", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 30u8, 98u8, 58u8, 140u8, 96u8, 231u8, 205u8, 111u8, 194u8, 100u8, 185u8, 242u8, 210u8, 143u8, 110u8, 144u8, 170u8, 187u8, 62u8, 196u8, @@ -33924,7 +33755,7 @@ pub mod api { pub fn session_executor_params_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::session_executor_params::SessionExecutorParams, (), (), @@ -33933,7 +33764,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "SessionExecutorParams", - vec![], + (), [ 38u8, 80u8, 118u8, 112u8, 189u8, 55u8, 95u8, 184u8, 19u8, 8u8, 114u8, 6u8, 173u8, 80u8, 254u8, 98u8, 107u8, 202u8, 215u8, 107u8, 149u8, @@ -33946,7 +33777,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::session_executor_params::SessionExecutorParams, ::subxt::storage::address::Yes, (), @@ -33955,9 +33786,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "SessionExecutorParams", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 38u8, 80u8, 118u8, 112u8, 189u8, 55u8, 95u8, 184u8, 19u8, 8u8, 114u8, 6u8, 173u8, 80u8, 254u8, 98u8, 107u8, 202u8, 215u8, 107u8, 149u8, @@ -34135,7 +33964,7 @@ pub mod api { pub fn last_pruned_session( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::last_pruned_session::LastPrunedSession, ::subxt::storage::address::Yes, (), @@ -34144,7 +33973,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "LastPrunedSession", - vec![], + (), [ 98u8, 107u8, 200u8, 158u8, 182u8, 120u8, 24u8, 242u8, 24u8, 163u8, 237u8, 72u8, 153u8, 19u8, 38u8, 85u8, 239u8, 208u8, 194u8, 22u8, 173u8, @@ -34157,7 +33986,7 @@ pub mod api { pub fn disputes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::disputes::Disputes, (), (), @@ -34166,7 +33995,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Disputes", - vec![], + (), [ 38u8, 237u8, 141u8, 222u8, 135u8, 82u8, 210u8, 166u8, 192u8, 122u8, 175u8, 96u8, 91u8, 1u8, 225u8, 182u8, 128u8, 4u8, 159u8, 56u8, 180u8, @@ -34180,7 +34009,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::disputes::Disputes, (), (), @@ -34189,9 +34018,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Disputes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 38u8, 237u8, 141u8, 222u8, 135u8, 82u8, 210u8, 166u8, 192u8, 122u8, 175u8, 96u8, 91u8, 1u8, 225u8, 182u8, 128u8, 4u8, 159u8, 56u8, 180u8, @@ -34206,7 +34033,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::disputes::Disputes, ::subxt::storage::address::Yes, (), @@ -34215,10 +34045,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Disputes", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 38u8, 237u8, 141u8, 222u8, 135u8, 82u8, 210u8, 166u8, 192u8, 122u8, 175u8, 96u8, 91u8, 1u8, 225u8, 182u8, 128u8, 4u8, 159u8, 56u8, 180u8, @@ -34232,7 +34062,7 @@ pub mod api { pub fn backers_on_disputes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::backers_on_disputes::BackersOnDisputes, (), (), @@ -34241,7 +34071,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "BackersOnDisputes", - vec![], + (), [ 136u8, 171u8, 20u8, 204u8, 135u8, 153u8, 144u8, 241u8, 46u8, 193u8, 65u8, 22u8, 116u8, 161u8, 144u8, 186u8, 31u8, 194u8, 202u8, 225u8, @@ -34256,7 +34086,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::backers_on_disputes::BackersOnDisputes, (), (), @@ -34265,9 +34095,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "BackersOnDisputes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 136u8, 171u8, 20u8, 204u8, 135u8, 153u8, 144u8, 241u8, 46u8, 193u8, 65u8, 22u8, 116u8, 161u8, 144u8, 186u8, 31u8, 194u8, 202u8, 225u8, @@ -34283,7 +34111,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::backers_on_disputes::BackersOnDisputes, ::subxt::storage::address::Yes, (), @@ -34292,10 +34123,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "BackersOnDisputes", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 136u8, 171u8, 20u8, 204u8, 135u8, 153u8, 144u8, 241u8, 46u8, 193u8, 65u8, 22u8, 116u8, 161u8, 144u8, 186u8, 31u8, 194u8, 202u8, 225u8, @@ -34309,7 +34140,7 @@ pub mod api { pub fn included_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::included::Included, (), (), @@ -34318,7 +34149,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Included", - vec![], + (), [ 47u8, 105u8, 189u8, 233u8, 206u8, 153u8, 162u8, 217u8, 141u8, 118u8, 31u8, 85u8, 87u8, 53u8, 100u8, 187u8, 31u8, 245u8, 50u8, 171u8, 4u8, @@ -34333,7 +34164,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::included::Included, (), (), @@ -34342,9 +34173,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Included", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 47u8, 105u8, 189u8, 233u8, 206u8, 153u8, 162u8, 217u8, 141u8, 118u8, 31u8, 85u8, 87u8, 53u8, 100u8, 187u8, 31u8, 245u8, 50u8, 171u8, 4u8, @@ -34360,7 +34189,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::included::Included, ::subxt::storage::address::Yes, (), @@ -34369,10 +34201,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Included", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 47u8, 105u8, 189u8, 233u8, 206u8, 153u8, 162u8, 217u8, 141u8, 118u8, 31u8, 85u8, 87u8, 53u8, 100u8, 187u8, 31u8, 245u8, 50u8, 171u8, 4u8, @@ -34388,7 +34220,7 @@ pub mod api { pub fn frozen( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::frozen::Frozen, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -34397,7 +34229,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Frozen", - vec![], + (), [ 245u8, 136u8, 43u8, 156u8, 7u8, 74u8, 31u8, 190u8, 184u8, 119u8, 182u8, 66u8, 18u8, 136u8, 30u8, 248u8, 24u8, 121u8, 26u8, 177u8, 169u8, 208u8, @@ -34498,7 +34330,7 @@ pub mod api { pub fn unapplied_slashes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::unapplied_slashes::UnappliedSlashes, (), (), @@ -34507,7 +34339,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasSlashing", "UnappliedSlashes", - vec![], + (), [ 114u8, 171u8, 137u8, 142u8, 180u8, 125u8, 226u8, 240u8, 99u8, 181u8, 68u8, 221u8, 91u8, 124u8, 172u8, 93u8, 103u8, 12u8, 95u8, 43u8, 67u8, @@ -34521,7 +34353,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::unapplied_slashes::UnappliedSlashes, (), (), @@ -34530,9 +34362,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasSlashing", "UnappliedSlashes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 114u8, 171u8, 137u8, 142u8, 180u8, 125u8, 226u8, 240u8, 99u8, 181u8, 68u8, 221u8, 91u8, 124u8, 172u8, 93u8, 103u8, 12u8, 95u8, 43u8, 67u8, @@ -34547,7 +34377,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::unapplied_slashes::UnappliedSlashes, ::subxt::storage::address::Yes, (), @@ -34556,10 +34389,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasSlashing", "UnappliedSlashes", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 114u8, 171u8, 137u8, 142u8, 180u8, 125u8, 226u8, 240u8, 99u8, 181u8, 68u8, 221u8, 91u8, 124u8, 172u8, 93u8, 103u8, 12u8, 95u8, 43u8, 67u8, @@ -34572,7 +34405,7 @@ pub mod api { pub fn validator_set_counts_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::validator_set_counts::ValidatorSetCounts, (), (), @@ -34581,7 +34414,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasSlashing", "ValidatorSetCounts", - vec![], + (), [ 195u8, 220u8, 79u8, 140u8, 114u8, 80u8, 241u8, 103u8, 4u8, 7u8, 53u8, 100u8, 16u8, 78u8, 104u8, 171u8, 134u8, 110u8, 158u8, 191u8, 37u8, @@ -34594,7 +34427,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::validator_set_counts::ValidatorSetCounts, ::subxt::storage::address::Yes, (), @@ -34603,9 +34436,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasSlashing", "ValidatorSetCounts", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 195u8, 220u8, 79u8, 140u8, 114u8, 80u8, 241u8, 103u8, 4u8, 7u8, 53u8, 100u8, 16u8, 78u8, 104u8, 171u8, 134u8, 110u8, 158u8, 191u8, 37u8, @@ -34874,7 +34705,7 @@ pub mod api { pub fn book_state_for_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::book_state_for::BookStateFor, (), ::subxt::storage::address::Yes, @@ -34883,7 +34714,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MessageQueue", "BookStateFor", - vec![], + (), [ 32u8, 61u8, 161u8, 81u8, 134u8, 136u8, 252u8, 113u8, 204u8, 115u8, 206u8, 180u8, 33u8, 185u8, 137u8, 155u8, 178u8, 189u8, 234u8, 201u8, @@ -34897,7 +34728,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::book_state_for::BookStateFor, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -34906,9 +34737,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MessageQueue", "BookStateFor", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 32u8, 61u8, 161u8, 81u8, 134u8, 136u8, 252u8, 113u8, 204u8, 115u8, 206u8, 180u8, 33u8, 185u8, 137u8, 155u8, 178u8, 189u8, 234u8, 201u8, @@ -34921,7 +34750,7 @@ pub mod api { pub fn service_head( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::service_head::ServiceHead, ::subxt::storage::address::Yes, (), @@ -34930,7 +34759,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MessageQueue", "ServiceHead", - vec![], + (), [ 17u8, 130u8, 229u8, 193u8, 127u8, 237u8, 60u8, 232u8, 99u8, 109u8, 102u8, 228u8, 124u8, 103u8, 24u8, 188u8, 151u8, 121u8, 55u8, 97u8, @@ -34943,7 +34772,7 @@ pub mod api { pub fn pages_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pages::Pages, (), (), @@ -34952,7 +34781,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MessageQueue", "Pages", - vec![], + (), [ 56u8, 181u8, 157u8, 16u8, 157u8, 123u8, 106u8, 93u8, 199u8, 208u8, 153u8, 53u8, 168u8, 188u8, 124u8, 77u8, 140u8, 163u8, 113u8, 16u8, @@ -34966,7 +34795,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::pages::Pages, (), (), @@ -34975,9 +34804,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MessageQueue", "Pages", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 56u8, 181u8, 157u8, 16u8, 157u8, 123u8, 106u8, 93u8, 199u8, 208u8, 153u8, 53u8, 168u8, 188u8, 124u8, 77u8, 140u8, 163u8, 113u8, 16u8, @@ -34992,7 +34819,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::pages::Pages, ::subxt::storage::address::Yes, (), @@ -35001,10 +34831,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MessageQueue", "Pages", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 56u8, 181u8, 157u8, 16u8, 157u8, 123u8, 106u8, 93u8, 199u8, 208u8, 153u8, 53u8, 168u8, 188u8, 124u8, 77u8, 140u8, 163u8, 113u8, 16u8, @@ -35260,7 +35090,7 @@ pub mod api { pub fn spot_traffic( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::spot_traffic::SpotTraffic, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -35269,7 +35099,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "OnDemandAssignmentProvider", "SpotTraffic", - vec![], + (), [ 8u8, 236u8, 233u8, 156u8, 211u8, 45u8, 192u8, 58u8, 108u8, 247u8, 47u8, 97u8, 229u8, 26u8, 188u8, 67u8, 98u8, 43u8, 11u8, 11u8, 1u8, 127u8, @@ -35282,7 +35112,7 @@ pub mod api { pub fn on_demand_queue( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::on_demand_queue::OnDemandQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -35291,7 +35121,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "OnDemandAssignmentProvider", "OnDemandQueue", - vec![], + (), [ 241u8, 10u8, 89u8, 240u8, 227u8, 90u8, 218u8, 35u8, 80u8, 244u8, 219u8, 112u8, 177u8, 143u8, 43u8, 228u8, 224u8, 165u8, 217u8, 65u8, 17u8, @@ -35306,7 +35136,7 @@ pub mod api { pub fn para_id_affinity_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::para_id_affinity::ParaIdAffinity, (), (), @@ -35315,7 +35145,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "OnDemandAssignmentProvider", "ParaIdAffinity", - vec![], + (), [ 145u8, 117u8, 2u8, 170u8, 99u8, 68u8, 166u8, 236u8, 247u8, 80u8, 202u8, 87u8, 116u8, 244u8, 218u8, 172u8, 41u8, 187u8, 170u8, 163u8, 187u8, @@ -35330,7 +35160,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::para_id_affinity::ParaIdAffinity, ::subxt::storage::address::Yes, (), @@ -35339,9 +35169,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "OnDemandAssignmentProvider", "ParaIdAffinity", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 145u8, 117u8, 2u8, 170u8, 99u8, 68u8, 166u8, 236u8, 247u8, 80u8, 202u8, 87u8, 116u8, 244u8, 218u8, 172u8, 41u8, 187u8, 170u8, 163u8, 187u8, @@ -35412,7 +35240,7 @@ pub mod api { pub fn core_schedules_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::core_schedules::CoreSchedules, (), (), @@ -35421,7 +35249,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreSchedules", - vec![], + (), [ 34u8, 85u8, 91u8, 158u8, 28u8, 200u8, 76u8, 188u8, 253u8, 91u8, 153u8, 42u8, 42u8, 227u8, 119u8, 181u8, 247u8, 44u8, 29u8, 24u8, 128u8, 49u8, @@ -35437,7 +35265,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::core_schedules::CoreSchedules, (), (), @@ -35446,9 +35274,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreSchedules", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 34u8, 85u8, 91u8, 158u8, 28u8, 200u8, 76u8, 188u8, 253u8, 91u8, 153u8, 42u8, 42u8, 227u8, 119u8, 181u8, 247u8, 44u8, 29u8, 24u8, 128u8, 49u8, @@ -35465,7 +35291,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::core_schedules::CoreSchedules, ::subxt::storage::address::Yes, (), @@ -35474,10 +35303,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreSchedules", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 34u8, 85u8, 91u8, 158u8, 28u8, 200u8, 76u8, 188u8, 253u8, 91u8, 153u8, 42u8, 42u8, 227u8, 119u8, 181u8, 247u8, 44u8, 29u8, 24u8, 128u8, 49u8, @@ -35492,7 +35321,7 @@ pub mod api { pub fn core_descriptors_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::core_descriptors::CoreDescriptors, (), ::subxt::storage::address::Yes, @@ -35501,7 +35330,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreDescriptors", - vec![], + (), [ 1u8, 90u8, 208u8, 119u8, 150u8, 241u8, 133u8, 74u8, 22u8, 166u8, 13u8, 7u8, 73u8, 136u8, 105u8, 61u8, 251u8, 245u8, 164u8, 7u8, 45u8, 68u8, @@ -35517,7 +35346,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::core_descriptors::CoreDescriptors, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -35526,9 +35355,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreDescriptors", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 1u8, 90u8, 208u8, 119u8, 150u8, 241u8, 133u8, 74u8, 22u8, 166u8, 13u8, 7u8, 73u8, 136u8, 105u8, 61u8, 251u8, 245u8, 164u8, 7u8, 45u8, 68u8, @@ -36063,7 +35890,7 @@ pub mod api { pub fn pending_swap_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::pending_swap::PendingSwap, (), (), @@ -36072,7 +35899,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Registrar", "PendingSwap", - vec![], + (), [ 75u8, 6u8, 68u8, 43u8, 108u8, 147u8, 220u8, 90u8, 190u8, 86u8, 209u8, 141u8, 9u8, 254u8, 103u8, 10u8, 94u8, 187u8, 155u8, 249u8, 140u8, @@ -36086,7 +35913,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::pending_swap::PendingSwap, ::subxt::storage::address::Yes, (), @@ -36095,9 +35922,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Registrar", "PendingSwap", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 75u8, 6u8, 68u8, 43u8, 108u8, 147u8, 220u8, 90u8, 190u8, 86u8, 209u8, 141u8, 9u8, 254u8, 103u8, 10u8, 94u8, 187u8, 155u8, 249u8, 140u8, @@ -36113,7 +35938,7 @@ pub mod api { pub fn paras_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::paras::Paras, (), (), @@ -36122,7 +35947,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Registrar", "Paras", - vec![], + (), [ 125u8, 62u8, 50u8, 209u8, 40u8, 170u8, 61u8, 62u8, 61u8, 246u8, 103u8, 229u8, 213u8, 94u8, 249u8, 49u8, 18u8, 90u8, 138u8, 14u8, 101u8, 133u8, @@ -36138,7 +35963,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::paras::Paras, ::subxt::storage::address::Yes, (), @@ -36147,9 +35972,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Registrar", "Paras", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 125u8, 62u8, 50u8, 209u8, 40u8, 170u8, 61u8, 62u8, 61u8, 246u8, 103u8, 229u8, 213u8, 94u8, 249u8, 49u8, 18u8, 90u8, 138u8, 14u8, 101u8, 133u8, @@ -36161,7 +35984,7 @@ pub mod api { pub fn next_free_para_id( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_free_para_id::NextFreeParaId, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -36170,7 +35993,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Registrar", "NextFreeParaId", - vec![], + (), [ 52u8, 14u8, 56u8, 196u8, 79u8, 221u8, 32u8, 14u8, 154u8, 247u8, 94u8, 219u8, 11u8, 11u8, 104u8, 137u8, 167u8, 195u8, 180u8, 101u8, 35u8, @@ -36463,7 +36286,7 @@ pub mod api { pub fn leases_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::leases::Leases, (), ::subxt::storage::address::Yes, @@ -36472,7 +36295,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Slots", "Leases", - vec![], + (), [ 233u8, 226u8, 181u8, 160u8, 216u8, 86u8, 238u8, 229u8, 31u8, 67u8, 200u8, 188u8, 134u8, 22u8, 88u8, 147u8, 204u8, 11u8, 34u8, 244u8, @@ -36501,7 +36324,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::leases::Leases, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -36510,9 +36333,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Slots", "Leases", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 233u8, 226u8, 181u8, 160u8, 216u8, 86u8, 238u8, 229u8, 31u8, 67u8, 200u8, 188u8, 134u8, 22u8, 88u8, 147u8, 204u8, 11u8, 34u8, 244u8, @@ -36932,7 +36753,7 @@ pub mod api { pub fn auction_counter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::auction_counter::AuctionCounter, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -36941,7 +36762,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "AuctionCounter", - vec![], + (), [ 110u8, 243u8, 85u8, 4u8, 127u8, 111u8, 101u8, 167u8, 72u8, 129u8, 201u8, 250u8, 88u8, 9u8, 79u8, 14u8, 152u8, 132u8, 0u8, 204u8, 112u8, @@ -36957,7 +36778,7 @@ pub mod api { pub fn auction_info( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::auction_info::AuctionInfo, ::subxt::storage::address::Yes, (), @@ -36966,7 +36787,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "AuctionInfo", - vec![], + (), [ 116u8, 81u8, 223u8, 26u8, 151u8, 103u8, 209u8, 182u8, 169u8, 173u8, 220u8, 234u8, 88u8, 191u8, 255u8, 75u8, 148u8, 75u8, 167u8, 37u8, 6u8, @@ -36979,7 +36800,7 @@ pub mod api { pub fn reserved_amounts_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::reserved_amounts::ReservedAmounts, (), (), @@ -36988,7 +36809,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "ReservedAmounts", - vec![], + (), [ 77u8, 44u8, 116u8, 36u8, 189u8, 213u8, 126u8, 32u8, 42u8, 131u8, 108u8, 41u8, 147u8, 40u8, 247u8, 245u8, 161u8, 42u8, 152u8, 195u8, 28u8, @@ -37003,7 +36824,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::reserved_amounts::ReservedAmounts, (), (), @@ -37012,9 +36833,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "ReservedAmounts", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 77u8, 44u8, 116u8, 36u8, 189u8, 213u8, 126u8, 32u8, 42u8, 131u8, 108u8, 41u8, 147u8, 40u8, 247u8, 245u8, 161u8, 42u8, 152u8, 195u8, 28u8, @@ -37030,7 +36849,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::reserved_amounts::ReservedAmounts, ::subxt::storage::address::Yes, (), @@ -37039,10 +36861,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "ReservedAmounts", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 77u8, 44u8, 116u8, 36u8, 189u8, 213u8, 126u8, 32u8, 42u8, 131u8, 108u8, 41u8, 147u8, 40u8, 247u8, 245u8, 161u8, 42u8, 152u8, 195u8, 28u8, @@ -37057,7 +36879,7 @@ pub mod api { pub fn winning_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::winning::Winning, (), (), @@ -37066,7 +36888,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "Winning", - vec![], + (), [ 8u8, 136u8, 174u8, 152u8, 223u8, 1u8, 143u8, 45u8, 213u8, 5u8, 239u8, 163u8, 152u8, 99u8, 197u8, 109u8, 194u8, 140u8, 246u8, 10u8, 40u8, @@ -37081,7 +36903,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::winning::Winning, ::subxt::storage::address::Yes, (), @@ -37090,9 +36912,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "Winning", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 8u8, 136u8, 174u8, 152u8, 223u8, 1u8, 143u8, 45u8, 213u8, 5u8, 239u8, 163u8, 152u8, 99u8, 197u8, 109u8, 194u8, 140u8, 246u8, 10u8, 40u8, @@ -37887,7 +37707,7 @@ pub mod api { pub fn funds_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::funds::Funds, (), (), @@ -37896,7 +37716,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Crowdloan", "Funds", - vec![], + (), [ 191u8, 255u8, 37u8, 49u8, 246u8, 246u8, 168u8, 178u8, 73u8, 238u8, 49u8, 76u8, 66u8, 246u8, 207u8, 12u8, 76u8, 233u8, 31u8, 218u8, 132u8, @@ -37910,7 +37730,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::funds::Funds, ::subxt::storage::address::Yes, (), @@ -37919,9 +37739,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Crowdloan", "Funds", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 191u8, 255u8, 37u8, 49u8, 246u8, 246u8, 168u8, 178u8, 73u8, 238u8, 49u8, 76u8, 66u8, 246u8, 207u8, 12u8, 76u8, 233u8, 31u8, 218u8, 132u8, @@ -37935,7 +37753,7 @@ pub mod api { pub fn new_raise( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::new_raise::NewRaise, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -37944,7 +37762,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Crowdloan", "NewRaise", - vec![], + (), [ 251u8, 31u8, 237u8, 22u8, 90u8, 248u8, 39u8, 66u8, 93u8, 81u8, 209u8, 209u8, 194u8, 42u8, 109u8, 208u8, 56u8, 75u8, 45u8, 247u8, 253u8, @@ -37957,7 +37775,7 @@ pub mod api { pub fn endings_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::endings_count::EndingsCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -37966,7 +37784,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Crowdloan", "EndingsCount", - vec![], + (), [ 106u8, 22u8, 229u8, 157u8, 118u8, 195u8, 11u8, 42u8, 5u8, 50u8, 44u8, 183u8, 72u8, 167u8, 95u8, 243u8, 234u8, 5u8, 200u8, 253u8, 127u8, @@ -37978,7 +37796,7 @@ pub mod api { pub fn next_fund_index( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_fund_index::NextFundIndex, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -37987,7 +37805,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Crowdloan", "NextFundIndex", - vec![], + (), [ 192u8, 21u8, 229u8, 234u8, 152u8, 224u8, 149u8, 44u8, 41u8, 9u8, 191u8, 128u8, 118u8, 11u8, 117u8, 245u8, 170u8, 116u8, 77u8, 216u8, 175u8, @@ -39528,7 +39346,7 @@ pub mod api { pub fn query_counter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::query_counter::QueryCounter, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -39537,7 +39355,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "QueryCounter", - vec![], + (), [ 216u8, 73u8, 160u8, 232u8, 60u8, 245u8, 218u8, 219u8, 152u8, 68u8, 146u8, 219u8, 255u8, 7u8, 86u8, 112u8, 83u8, 49u8, 94u8, 173u8, 64u8, @@ -39550,7 +39368,7 @@ pub mod api { pub fn queries_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::queries::Queries, (), (), @@ -39559,7 +39377,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "Queries", - vec![], + (), [ 246u8, 75u8, 240u8, 129u8, 106u8, 114u8, 99u8, 154u8, 176u8, 188u8, 146u8, 125u8, 244u8, 103u8, 187u8, 171u8, 60u8, 119u8, 4u8, 90u8, 58u8, @@ -39573,7 +39391,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::queries::Queries, ::subxt::storage::address::Yes, (), @@ -39582,9 +39400,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "Queries", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 246u8, 75u8, 240u8, 129u8, 106u8, 114u8, 99u8, 154u8, 176u8, 188u8, 146u8, 125u8, 244u8, 103u8, 187u8, 171u8, 60u8, 119u8, 4u8, 90u8, 58u8, @@ -39600,7 +39416,7 @@ pub mod api { pub fn asset_traps_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::asset_traps::AssetTraps, (), ::subxt::storage::address::Yes, @@ -39609,7 +39425,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "AssetTraps", - vec![], + (), [ 148u8, 41u8, 254u8, 134u8, 61u8, 172u8, 126u8, 146u8, 78u8, 178u8, 50u8, 77u8, 226u8, 8u8, 200u8, 78u8, 77u8, 91u8, 26u8, 133u8, 104u8, @@ -39625,7 +39441,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::asset_traps::AssetTraps, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -39634,9 +39450,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "AssetTraps", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 148u8, 41u8, 254u8, 134u8, 61u8, 172u8, 126u8, 146u8, 78u8, 178u8, 50u8, 77u8, 226u8, 8u8, 200u8, 78u8, 77u8, 91u8, 26u8, 133u8, 104u8, @@ -39649,7 +39463,7 @@ pub mod api { pub fn safe_xcm_version( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::safe_xcm_version::SafeXcmVersion, ::subxt::storage::address::Yes, (), @@ -39658,7 +39472,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "SafeXcmVersion", - vec![], + (), [ 187u8, 8u8, 74u8, 126u8, 80u8, 215u8, 177u8, 60u8, 223u8, 123u8, 196u8, 155u8, 166u8, 66u8, 25u8, 164u8, 191u8, 66u8, 116u8, 131u8, 116u8, @@ -39671,7 +39485,7 @@ pub mod api { pub fn supported_version_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::supported_version::SupportedVersion, (), (), @@ -39680,7 +39494,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "SupportedVersion", - vec![], + (), [ 144u8, 218u8, 177u8, 254u8, 210u8, 8u8, 84u8, 149u8, 163u8, 162u8, 238u8, 37u8, 157u8, 28u8, 140u8, 121u8, 201u8, 173u8, 204u8, 92u8, @@ -39694,7 +39508,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::supported_version::SupportedVersion, (), (), @@ -39703,9 +39517,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "SupportedVersion", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 144u8, 218u8, 177u8, 254u8, 210u8, 8u8, 84u8, 149u8, 163u8, 162u8, 238u8, 37u8, 157u8, 28u8, 140u8, 121u8, 201u8, 173u8, 204u8, 92u8, @@ -39720,7 +39532,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::supported_version::SupportedVersion, ::subxt::storage::address::Yes, (), @@ -39729,10 +39544,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "SupportedVersion", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 144u8, 218u8, 177u8, 254u8, 210u8, 8u8, 84u8, 149u8, 163u8, 162u8, 238u8, 37u8, 157u8, 28u8, 140u8, 121u8, 201u8, 173u8, 204u8, 92u8, @@ -39745,7 +39560,7 @@ pub mod api { pub fn version_notifiers_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::version_notifiers::VersionNotifiers, (), (), @@ -39754,7 +39569,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionNotifiers", - vec![], + (), [ 175u8, 206u8, 29u8, 14u8, 111u8, 123u8, 211u8, 109u8, 159u8, 131u8, 80u8, 149u8, 216u8, 196u8, 181u8, 105u8, 117u8, 138u8, 80u8, 69u8, @@ -39768,7 +39583,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::version_notifiers::VersionNotifiers, (), (), @@ -39777,9 +39592,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionNotifiers", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 175u8, 206u8, 29u8, 14u8, 111u8, 123u8, 211u8, 109u8, 159u8, 131u8, 80u8, 149u8, 216u8, 196u8, 181u8, 105u8, 117u8, 138u8, 80u8, 69u8, @@ -39794,7 +39607,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StorageKey, + ), types::version_notifiers::VersionNotifiers, ::subxt::storage::address::Yes, (), @@ -39803,10 +39619,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionNotifiers", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 175u8, 206u8, 29u8, 14u8, 111u8, 123u8, 211u8, 109u8, 159u8, 131u8, 80u8, 149u8, 216u8, 196u8, 181u8, 105u8, 117u8, 138u8, 80u8, 69u8, @@ -39820,7 +39636,7 @@ pub mod api { pub fn version_notify_targets_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::version_notify_targets::VersionNotifyTargets, (), (), @@ -39829,7 +39645,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionNotifyTargets", - vec![], + (), [ 113u8, 77u8, 150u8, 42u8, 82u8, 49u8, 195u8, 120u8, 96u8, 80u8, 152u8, 67u8, 27u8, 142u8, 10u8, 74u8, 66u8, 134u8, 35u8, 202u8, 77u8, 187u8, @@ -39843,7 +39659,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::version_notify_targets::VersionNotifyTargets, (), (), @@ -39852,9 +39668,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionNotifyTargets", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 113u8, 77u8, 150u8, 42u8, 82u8, 49u8, 195u8, 120u8, 96u8, 80u8, 152u8, 67u8, 27u8, 142u8, 10u8, 74u8, 66u8, 134u8, 35u8, 202u8, 77u8, 187u8, @@ -39869,7 +39683,14 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey< + types::version_notify_targets::Param0, + >, + ::subxt::storage::address::StorageKey< + types::version_notify_targets::Param1, + >, + ), types::version_notify_targets::VersionNotifyTargets, ::subxt::storage::address::Yes, (), @@ -39878,10 +39699,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionNotifyTargets", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 113u8, 77u8, 150u8, 42u8, 82u8, 49u8, 195u8, 120u8, 96u8, 80u8, 152u8, 67u8, 27u8, 142u8, 10u8, 74u8, 66u8, 134u8, 35u8, 202u8, 77u8, 187u8, @@ -39895,7 +39716,7 @@ pub mod api { pub fn version_discovery_queue( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::version_discovery_queue::VersionDiscoveryQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -39904,7 +39725,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionDiscoveryQueue", - vec![], + (), [ 95u8, 74u8, 97u8, 94u8, 40u8, 140u8, 175u8, 176u8, 224u8, 222u8, 83u8, 199u8, 170u8, 102u8, 3u8, 77u8, 127u8, 208u8, 155u8, 122u8, 176u8, @@ -39917,7 +39738,7 @@ pub mod api { pub fn current_migration( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::current_migration::CurrentMigration, ::subxt::storage::address::Yes, (), @@ -39926,7 +39747,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "CurrentMigration", - vec![], + (), [ 74u8, 138u8, 181u8, 162u8, 59u8, 251u8, 37u8, 28u8, 232u8, 51u8, 30u8, 152u8, 252u8, 133u8, 95u8, 195u8, 47u8, 127u8, 21u8, 44u8, 62u8, 143u8, @@ -39938,7 +39759,7 @@ pub mod api { pub fn remote_locked_fungibles_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::remote_locked_fungibles::RemoteLockedFungibles, (), (), @@ -39947,7 +39768,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "RemoteLockedFungibles", - vec![], + (), [ 247u8, 124u8, 77u8, 42u8, 208u8, 183u8, 99u8, 196u8, 50u8, 113u8, 250u8, 221u8, 222u8, 170u8, 10u8, 60u8, 143u8, 172u8, 149u8, 198u8, @@ -39961,7 +39782,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::remote_locked_fungibles::RemoteLockedFungibles, (), (), @@ -39970,9 +39791,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "RemoteLockedFungibles", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 247u8, 124u8, 77u8, 42u8, 208u8, 183u8, 99u8, 196u8, 50u8, 113u8, 250u8, 221u8, 222u8, 170u8, 10u8, 60u8, 143u8, 172u8, 149u8, 198u8, @@ -39987,7 +39806,14 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey< + types::remote_locked_fungibles::Param0, + >, + ::subxt::storage::address::StorageKey< + types::remote_locked_fungibles::Param1, + >, + ), types::remote_locked_fungibles::RemoteLockedFungibles, (), (), @@ -39996,10 +39822,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "RemoteLockedFungibles", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ), [ 247u8, 124u8, 77u8, 42u8, 208u8, 183u8, 99u8, 196u8, 50u8, 113u8, 250u8, 221u8, 222u8, 170u8, 10u8, 60u8, 143u8, 172u8, 149u8, 198u8, @@ -40015,7 +39841,17 @@ pub mod api { _1: impl ::std::borrow::Borrow, _2: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StorageKey< + types::remote_locked_fungibles::Param0, + >, + ::subxt::storage::address::StorageKey< + types::remote_locked_fungibles::Param1, + >, + ::subxt::storage::address::StorageKey< + types::remote_locked_fungibles::Param2, + >, + ), types::remote_locked_fungibles::RemoteLockedFungibles, ::subxt::storage::address::Yes, (), @@ -40024,11 +39860,11 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "RemoteLockedFungibles", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_2.borrow()), - ], + ( + ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StorageKey::new(_2.borrow()), + ), [ 247u8, 124u8, 77u8, 42u8, 208u8, 183u8, 99u8, 196u8, 50u8, 113u8, 250u8, 221u8, 222u8, 170u8, 10u8, 60u8, 143u8, 172u8, 149u8, 198u8, @@ -40041,7 +39877,7 @@ pub mod api { pub fn locked_fungibles_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::locked_fungibles::LockedFungibles, (), (), @@ -40050,7 +39886,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "LockedFungibles", - vec![], + (), [ 254u8, 234u8, 1u8, 27u8, 27u8, 32u8, 217u8, 24u8, 47u8, 30u8, 62u8, 80u8, 86u8, 125u8, 120u8, 24u8, 143u8, 229u8, 161u8, 153u8, 240u8, @@ -40063,7 +39899,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::locked_fungibles::LockedFungibles, ::subxt::storage::address::Yes, (), @@ -40072,9 +39908,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "LockedFungibles", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 254u8, 234u8, 1u8, 27u8, 27u8, 32u8, 217u8, 24u8, 47u8, 30u8, 62u8, 80u8, 86u8, 125u8, 120u8, 24u8, 143u8, 229u8, 161u8, 153u8, 240u8, @@ -40086,7 +39920,7 @@ pub mod api { pub fn xcm_execution_suspended( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::xcm_execution_suspended::XcmExecutionSuspended, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40095,7 +39929,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "XcmExecutionSuspended", - vec![], + (), [ 182u8, 54u8, 69u8, 68u8, 78u8, 76u8, 103u8, 79u8, 47u8, 136u8, 99u8, 104u8, 128u8, 129u8, 249u8, 54u8, 214u8, 136u8, 97u8, 48u8, 178u8, @@ -40876,7 +40710,7 @@ pub mod api { pub fn permanent_slots_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::permanent_slots::PermanentSlots, (), (), @@ -40885,7 +40719,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "PermanentSlots", - vec![], + (), [ 133u8, 179u8, 221u8, 222u8, 50u8, 75u8, 158u8, 137u8, 167u8, 190u8, 19u8, 237u8, 201u8, 44u8, 86u8, 64u8, 57u8, 61u8, 96u8, 112u8, 218u8, @@ -40899,7 +40733,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::permanent_slots::PermanentSlots, ::subxt::storage::address::Yes, (), @@ -40908,9 +40742,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "PermanentSlots", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 133u8, 179u8, 221u8, 222u8, 50u8, 75u8, 158u8, 137u8, 167u8, 190u8, 19u8, 237u8, 201u8, 44u8, 86u8, 64u8, 57u8, 61u8, 96u8, 112u8, 218u8, @@ -40923,7 +40755,7 @@ pub mod api { pub fn permanent_slot_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::permanent_slot_count::PermanentSlotCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40932,7 +40764,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "PermanentSlotCount", - vec![], + (), [ 57u8, 211u8, 19u8, 233u8, 105u8, 201u8, 166u8, 99u8, 53u8, 217u8, 23u8, 64u8, 216u8, 129u8, 21u8, 36u8, 234u8, 24u8, 57u8, 99u8, 13u8, 205u8, @@ -40944,7 +40776,7 @@ pub mod api { pub fn temporary_slots_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::temporary_slots::TemporarySlots, (), (), @@ -40953,7 +40785,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "TemporarySlots", - vec![], + (), [ 184u8, 245u8, 181u8, 90u8, 169u8, 232u8, 108u8, 3u8, 153u8, 4u8, 176u8, 170u8, 230u8, 163u8, 236u8, 111u8, 196u8, 218u8, 154u8, 125u8, 102u8, @@ -40967,7 +40799,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StorageKey, types::temporary_slots::TemporarySlots, ::subxt::storage::address::Yes, (), @@ -40976,9 +40808,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "TemporarySlots", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StorageKey::new(_0.borrow()), [ 184u8, 245u8, 181u8, 90u8, 169u8, 232u8, 108u8, 3u8, 153u8, 4u8, 176u8, 170u8, 230u8, 163u8, 236u8, 111u8, 196u8, 218u8, 154u8, 125u8, 102u8, @@ -40991,7 +40821,7 @@ pub mod api { pub fn temporary_slot_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::temporary_slot_count::TemporarySlotCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -41000,7 +40830,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "TemporarySlotCount", - vec![], + (), [ 218u8, 236u8, 69u8, 75u8, 224u8, 60u8, 9u8, 197u8, 217u8, 4u8, 210u8, 55u8, 125u8, 106u8, 239u8, 208u8, 115u8, 105u8, 94u8, 223u8, 219u8, @@ -41012,7 +40842,7 @@ pub mod api { pub fn active_temporary_slot_count( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::active_temporary_slot_count::ActiveTemporarySlotCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -41021,7 +40851,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "ActiveTemporarySlotCount", - vec![], + (), [ 153u8, 99u8, 232u8, 164u8, 137u8, 10u8, 232u8, 172u8, 78u8, 4u8, 69u8, 178u8, 245u8, 220u8, 56u8, 251u8, 60u8, 238u8, 127u8, 246u8, 60u8, @@ -41034,7 +40864,7 @@ pub mod api { pub fn max_temporary_slots( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::max_temporary_slots::MaxTemporarySlots, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -41043,7 +40873,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "MaxTemporarySlots", - vec![], + (), [ 129u8, 130u8, 136u8, 77u8, 149u8, 130u8, 130u8, 195u8, 150u8, 114u8, 199u8, 133u8, 86u8, 252u8, 149u8, 149u8, 131u8, 248u8, 70u8, 39u8, @@ -41056,7 +40886,7 @@ pub mod api { pub fn max_permanent_slots( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::max_permanent_slots::MaxPermanentSlots, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -41065,7 +40895,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "MaxPermanentSlots", - vec![], + (), [ 20u8, 72u8, 203u8, 62u8, 120u8, 21u8, 97u8, 9u8, 138u8, 135u8, 67u8, 152u8, 131u8, 197u8, 59u8, 80u8, 226u8, 148u8, 159u8, 122u8, 34u8, @@ -41286,7 +41116,7 @@ pub mod api { pub fn validators_to_retire( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::validators_to_retire::ValidatorsToRetire, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -41295,7 +41125,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ValidatorManager", "ValidatorsToRetire", - vec![], + (), [ 137u8, 92u8, 99u8, 157u8, 254u8, 166u8, 190u8, 64u8, 111u8, 212u8, 37u8, 90u8, 164u8, 0u8, 31u8, 15u8, 83u8, 21u8, 225u8, 7u8, 57u8, @@ -41307,7 +41137,7 @@ pub mod api { pub fn validators_to_add( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::validators_to_add::ValidatorsToAdd, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -41316,7 +41146,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ValidatorManager", "ValidatorsToAdd", - vec![], + (), [ 168u8, 209u8, 123u8, 225u8, 168u8, 62u8, 18u8, 174u8, 164u8, 161u8, 228u8, 179u8, 251u8, 112u8, 210u8, 173u8, 24u8, 177u8, 111u8, 129u8, @@ -41737,7 +41567,7 @@ pub mod api { pub fn migration_process( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::migration_process::MigrationProcess, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -41746,7 +41576,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "StateTrieMigration", "MigrationProcess", - vec![], + (), [ 119u8, 172u8, 143u8, 118u8, 90u8, 3u8, 154u8, 185u8, 165u8, 165u8, 249u8, 230u8, 77u8, 14u8, 221u8, 146u8, 75u8, 243u8, 69u8, 209u8, 79u8, @@ -41760,7 +41590,7 @@ pub mod api { pub fn auto_limits( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::auto_limits::AutoLimits, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -41769,7 +41599,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "StateTrieMigration", "AutoLimits", - vec![], + (), [ 225u8, 29u8, 94u8, 66u8, 169u8, 230u8, 106u8, 20u8, 238u8, 81u8, 238u8, 183u8, 185u8, 74u8, 94u8, 58u8, 107u8, 174u8, 228u8, 10u8, 156u8, @@ -41783,7 +41613,7 @@ pub mod api { pub fn signed_migration_max_limits( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::signed_migration_max_limits::SignedMigrationMaxLimits, ::subxt::storage::address::Yes, (), @@ -41792,7 +41622,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "StateTrieMigration", "SignedMigrationMaxLimits", - vec![], + (), [ 121u8, 97u8, 145u8, 237u8, 10u8, 145u8, 206u8, 119u8, 15u8, 12u8, 200u8, 24u8, 231u8, 140u8, 248u8, 227u8, 202u8, 78u8, 93u8, 134u8, @@ -42267,7 +42097,7 @@ pub mod api { pub fn key( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::key::Key, ::subxt::storage::address::Yes, (), @@ -42276,7 +42106,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Sudo", "Key", - vec![], + (), [ 72u8, 14u8, 225u8, 162u8, 205u8, 247u8, 227u8, 105u8, 116u8, 57u8, 4u8, 31u8, 84u8, 137u8, 227u8, 228u8, 133u8, 245u8, 206u8, 227u8, 117u8, From 28e1b776adcd02a7688ad7d44b0fc1ee0ed846c2 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Tue, 13 Feb 2024 15:16:51 +0100 Subject: [PATCH 05/39] trait bounds don't match scale value... --- subxt/src/error/mod.rs | 3 + subxt/src/storage/storage_address.rs | 154 ++++++++++++++++++++++++++- subxt/src/storage/utils.rs | 51 ++++++--- 3 files changed, 192 insertions(+), 16 deletions(-) diff --git a/subxt/src/error/mod.rs b/subxt/src/error/mod.rs index 41dbc11d31..73a4be23a1 100644 --- a/subxt/src/error/mod.rs +++ b/subxt/src/error/mod.rs @@ -206,6 +206,9 @@ pub enum StorageAddressError { /// The number of fields in the metadata for this storage entry. fields: usize, }, + /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. + #[error("Storage address bytes are not the expected format")] + UnexpectedAddressBytes, } /// Something went wrong trying to access details in the metadata. diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 709c2230e2..abff891f57 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -6,9 +6,11 @@ use crate::{ dynamic::DecodedValueThunk, error::{Error, MetadataError, StorageAddressError}, metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, + storage::utils::{decode_from_hash, strip_concat_hash_bytes, strip_storage_addess_root_bytes}, utils::{Encoded, Static}, }; use derivative::Derivative; +use scale_decode::DecodeAsType; use scale_encode::EncodeAsType; use scale_info::TypeDef; use std::borrow::Cow; @@ -90,6 +92,22 @@ pub trait StorageMultiKey { /// Iterator over the storage keys, each key implements EncodeAsType to /// give the corresponding bytes to a `StorageHasher`. fn keys_iter(&self) -> impl ExactSizeIterator; + + /// Attempts to decode the StorageMultiKey from a whole storage address. + /// The key/keys can only be recovered if all hashers are concat-style hashers. + /// Example: Imagine The `StorageMultiKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. + /// Then the memory layout of the storage key is: + /// ```txt + /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | + /// ``` + /// Returns None, if any of the hashers is not a concat-style hasher. + fn decode_from_address_bytes( + address_bytes: &[u8], + hashers_and_ty_ids: &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Option> + where + Self: Sized + 'static; } /// Implement `StorageMultiKey` for `()` which can be used for keyless storage entries @@ -99,23 +117,117 @@ impl StorageMultiKey for () { // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. std::iter::empty() } + + fn decode_from_address_bytes( + address_bytes: &[u8], + _hashers_and_ty_ids: &[(StorageHasher, u32)], + _metadata: &Metadata, + ) -> Option> { + if address_bytes.len() < 16 { + return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); + } + Some(Ok(())) + } } // Note: The ?Sized bound is necessary to support e.g. `StorageKey<[u8]>`. -impl StorageMultiKey for StorageKey { +impl StorageMultiKey for StorageKey { fn keys_iter(&self) -> impl ExactSizeIterator { // Note: this returns the storage root address of the storage entry. // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. std::iter::once(&self.bytes as &dyn EncodeAsType) } + + fn decode_from_address_bytes( + address_bytes: &[u8], + hashers_and_ty_ids: &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Option> + where + Self: Sized + 'static, + { + let cursor = &mut &*address_bytes; + if let Err(err) = strip_storage_addess_root_bytes(cursor) { + return Some(Err(err.into())); + } + + let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { + return Some(Err(StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into())); + }; + decode_storage_key_from_hash(address_bytes, cursor, hasher, *ty_id, metadata) + } +} + +pub fn decode_storage_key_from_hash( + address_bytes: &[u8], + cursor: &mut &[u8], + hasher: &StorageHasher, + ty_id: u32, + metadata: &Metadata, +) -> Option, Error>> { + if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { + return Some(Err(err.into())); + } + let start_idx = address_bytes.len() - cursor.len(); + if let Err(err) = scale_decode::visitor::decode_with_visitor( + cursor, + ty_id, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) { + return Some(Err(scale_decode::Error::from(err).into())); + } + let end_idx = address_bytes.len() - cursor.len(); + let key_bytes = address_bytes[start_idx..end_idx].to_vec(); + let key = StorageKey { + bytes: Static(Encoded(key_bytes)), + _marker: std::marker::PhantomData::, + }; + Some(Ok(key)) } -impl StorageMultiKey for Vec { +/// Note: This implementation is useful to use e.g. Vec as a MultiStorageKey. +impl StorageMultiKey for Vec { fn keys_iter(&self) -> impl ExactSizeIterator { // Note: this returns the storage root address of the storage entry. // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. self.iter().map(|e| e as &dyn EncodeAsType) } + + fn decode_from_address_bytes( + address_bytes: &[u8], + hashers_and_ty_ids: &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Option> + where + Self: Sized + 'static, + { + let cursor = &mut &*address_bytes; + if let Err(err) = strip_storage_addess_root_bytes(cursor) { + return Some(Err(err.into())); + } + let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); + + let mut result: Vec = vec![]; + while cursor.len() > 0 { + let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { + // Still bytes left, but no hashers and type ids anymore to pull from: this is an unexpected error. + return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); + }; + if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { + return Some(Err(err.into())); + } + match ::decode_with_metadata(cursor, *ty_id, metadata) { + Ok(element) => result.push(element), + Err(err) => return Some(Err(err.into())), + } + } + Some(Ok(result)) + } } /// Generates StorageMultiKey implementations for tuples, e.g. @@ -136,6 +248,44 @@ macro_rules! impl_tuples { ),+]; arr.into_iter() } + + fn decode_from_address_bytes( + address_bytes: &[u8], + hashers_and_ty_ids: &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Option> + where + Self: Sized + 'static, + { + let cursor = &mut &*address_bytes; + if let Err(err) = strip_storage_addess_root_bytes(cursor) { + return Some(Err(err.into())); + } + + // The number of elements in this tuple. + const LEN: usize = $((0*$n + 1)+)+0; + + // It is an error to not provide a hasher and type id for each element in this tuple. + if hashers_and_ty_ids.len() < LEN { + return Some(Err(StorageAddressError::WrongNumberOfKeys{actual: hashers_and_ty_ids.len(), expected: LEN}.into())) + } + + // Construct the tuple as a series of expressions. + let tuple : Self = ( $( + { + // index is available, because of bounds check above; qed + let (hasher, ty_id) = &hashers_and_ty_ids[$n]; + let key = match decode_storage_key_from_hash::<$ty>(address_bytes, cursor, hasher, *ty_id, metadata)? { + Ok(key) => key, + Err(err) => { + return Some(Err(err)); + } + }; + key + }, + )+); + return Some(Ok(tuple)) + } } }}; } diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index a78c75002a..82067eb5e8 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -9,7 +9,10 @@ use subxt_metadata::StorageHasher; use super::StorageAddress; -use crate::{error::Error, metadata::Metadata}; +use crate::{ + error::{Error, StorageAddressError}, + metadata::Metadata, +}; /// Return the root of a given [`StorageAddress`]: hash the pallet name and entry name /// and append those bytes to the output. @@ -41,34 +44,54 @@ pub(crate) fn storage_address_root_bytes(addr: &Address } /// Tries to recover an encoded value from a concat-style hash. -pub fn recover_value_from_hash( - hash: &[u8], +pub fn decode_from_hash( + hash: &mut &[u8], hasher: &StorageHasher, ) -> Option> { - let value_bytes = value_bytes_from_hash_bytes(hash, hasher)?; - let value = match V::decode(&mut &value_bytes[..]) { + if let Err(err) = strip_concat_hash_bytes(hash, hasher)? { + return Some(Err(err.into())); + }; + let value = match V::decode(hash) { Ok(value) => value, Err(err) => return Some(Err(err.into())), }; Some(Ok(value)) } -/// Tries to recover from the hash, the bytes of the value that was originially hashed. -/// Note: this only returns `Some(..)` for concat-style hashers. -fn value_bytes_from_hash_bytes<'a>(hash: &'a [u8], hasher: &StorageHasher) -> Option<&'a [u8]> { +pub fn strip_storage_addess_root_bytes( + address_bytes: &mut &[u8], +) -> Result<(), StorageAddressError> { + if address_bytes.len() >= 16 { + *address_bytes = &mut &address_bytes[16..]; + Ok(()) + } else { + Err(StorageAddressError::UnexpectedAddressBytes) + } +} + +/// Strips the first few bytes of a concat hasher. +/// Returns None(..) if the hasher is not a concat hasher. +/// Returns Some(Err(..)) if there are not enough bytes. +/// Returns Some(Ok(..)) if the stripping was successful. +pub fn strip_concat_hash_bytes<'a>( + hash: &'a mut &[u8], + hasher: &StorageHasher, +) -> Option> { match hasher { StorageHasher::Blake2_128Concat => { - if hash.len() > 16 { - Some(&hash[16..]) + if hash.len() >= 16 { + *hash = &mut &hash[16..]; + Some(Ok(())) } else { - None + Some(Err(StorageAddressError::UnexpectedAddressBytes)) } } StorageHasher::Twox64Concat => { - if hash.len() > 8 { - Some(&hash[8..]) + if hash.len() >= 8 { + *hash = &mut &hash[8..]; + Some(Ok(())) } else { - None + Some(Err(StorageAddressError::UnexpectedAddressBytes)) } } StorageHasher::Blake2_128 From 489ccdc4fb7b011ae397d8986cf12006a47fd87b Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Tue, 13 Feb 2024 15:37:02 +0100 Subject: [PATCH 06/39] fix trait bounds and examples --- subxt/examples/storage_iterating_dynamic.rs | 4 ++-- subxt/src/storage/storage_address.rs | 17 ++++++++++------- subxt/src/storage/utils.rs | 20 +++----------------- 3 files changed, 15 insertions(+), 26 deletions(-) diff --git a/subxt/examples/storage_iterating_dynamic.rs b/subxt/examples/storage_iterating_dynamic.rs index 391ce60cd7..eafbdb18b9 100644 --- a/subxt/examples/storage_iterating_dynamic.rs +++ b/subxt/examples/storage_iterating_dynamic.rs @@ -7,8 +7,8 @@ async fn main() -> Result<(), Box> { let api = OnlineClient::::new().await?; // Build a dynamic storage query to iterate account information. - // With a dynamic query, we can just provide an empty Vec as the keys to iterate over all entries. - let keys = Vec::<()>::new(); + // With a dynamic query, we can just provide a unit type as the keys to iterate over all entries. + let keys = (); let storage_query = subxt::dynamic::storage("System", "Account", keys); // Use that query to return an iterator over the results. diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index abff891f57..e6fff9746a 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -6,11 +6,10 @@ use crate::{ dynamic::DecodedValueThunk, error::{Error, MetadataError, StorageAddressError}, metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, - storage::utils::{decode_from_hash, strip_concat_hash_bytes, strip_storage_addess_root_bytes}, + storage::utils::{strip_concat_hash_bytes, strip_storage_addess_root_bytes}, utils::{Encoded, Static}, }; use derivative::Derivative; -use scale_decode::DecodeAsType; use scale_encode::EncodeAsType; use scale_info::TypeDef; use std::borrow::Cow; @@ -190,8 +189,7 @@ pub fn decode_storage_key_from_hash( Some(Ok(key)) } -/// Note: This implementation is useful to use e.g. Vec as a MultiStorageKey. -impl StorageMultiKey for Vec { +impl StorageMultiKey for Vec { fn keys_iter(&self) -> impl ExactSizeIterator { // Note: this returns the storage root address of the storage entry. // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. @@ -212,7 +210,7 @@ impl StorageMultiKey for Vec { } let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); - let mut result: Vec = vec![]; + let mut result: Vec = vec![]; while cursor.len() > 0 { let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { // Still bytes left, but no hashers and type ids anymore to pull from: this is an unexpected error. @@ -221,8 +219,13 @@ impl StorageMultiKey for Vec { if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { return Some(Err(err.into())); } - match ::decode_with_metadata(cursor, *ty_id, metadata) { - Ok(element) => result.push(element), + match DecodedValueThunk::decode_with_metadata(cursor, *ty_id, metadata) { + Ok(decoded) => { + match decoded.to_value() { + Ok(value) => result.push(value.remove_context()), + Err(err) => return Some(Err(err.into())), + }; + } Err(err) => return Some(Err(err.into())), } } diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index 82067eb5e8..27ab0a475c 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -43,21 +43,7 @@ pub(crate) fn storage_address_root_bytes(addr: &Address bytes } -/// Tries to recover an encoded value from a concat-style hash. -pub fn decode_from_hash( - hash: &mut &[u8], - hasher: &StorageHasher, -) -> Option> { - if let Err(err) = strip_concat_hash_bytes(hash, hasher)? { - return Some(Err(err.into())); - }; - let value = match V::decode(hash) { - Ok(value) => value, - Err(err) => return Some(Err(err.into())), - }; - Some(Ok(value)) -} - +/// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. pub fn strip_storage_addess_root_bytes( address_bytes: &mut &[u8], ) -> Result<(), StorageAddressError> { @@ -69,8 +55,8 @@ pub fn strip_storage_addess_root_bytes( } } -/// Strips the first few bytes of a concat hasher. -/// Returns None(..) if the hasher is not a concat hasher. +/// Strips the first few bytes off a hash produced byt a concat hasher. +/// Returns None(..) if the hasher provided is not a concat hasher. /// Returns Some(Err(..)) if there are not enough bytes. /// Returns Some(Ok(..)) if the stripping was successful. pub fn strip_concat_hash_bytes<'a>( From 23203da3f34697d51d693f34f44420d27ea1e5bf Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Tue, 13 Feb 2024 16:18:02 +0100 Subject: [PATCH 07/39] reconstruct storage keys in iterations --- subxt/examples/storage_iterating.rs | 7 +- subxt/examples/storage_iterating_dynamic.rs | 11 +-- subxt/examples/storage_iterating_partial.rs | 8 +- subxt/src/storage/mod.rs | 2 +- subxt/src/storage/storage_address.rs | 5 ++ subxt/src/storage/storage_type.rs | 88 +++++++++++++++++++-- 6 files changed, 102 insertions(+), 19 deletions(-) diff --git a/subxt/examples/storage_iterating.rs b/subxt/examples/storage_iterating.rs index e99bb884b3..f64fad6c8d 100644 --- a/subxt/examples/storage_iterating.rs +++ b/subxt/examples/storage_iterating.rs @@ -16,9 +16,10 @@ async fn main() -> Result<(), Box> { // a time from the node, but we always iterate over one at a time). let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - while let Some(Ok((key, value))) = results.next().await { - println!("Key: 0x{}", hex::encode(&key)); - println!("Value: {:?}", value); + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value); } Ok(()) diff --git a/subxt/examples/storage_iterating_dynamic.rs b/subxt/examples/storage_iterating_dynamic.rs index eafbdb18b9..a768e6768e 100644 --- a/subxt/examples/storage_iterating_dynamic.rs +++ b/subxt/examples/storage_iterating_dynamic.rs @@ -7,16 +7,17 @@ async fn main() -> Result<(), Box> { let api = OnlineClient::::new().await?; // Build a dynamic storage query to iterate account information. - // With a dynamic query, we can just provide a unit type as the keys to iterate over all entries. - let keys = (); + // With a dynamic query, we can just provide an empty vector as the keys to iterate over all entries. + let keys: Vec = vec![]; let storage_query = subxt::dynamic::storage("System", "Account", keys); // Use that query to return an iterator over the results. let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - while let Some(Ok((key, value))) = results.next().await { - println!("Key: 0x{}", hex::encode(&key)); - println!("Value: {:?}", value.to_value()?); + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value.to_value()?); } Ok(()) diff --git a/subxt/examples/storage_iterating_partial.rs b/subxt/examples/storage_iterating_partial.rs index eb89dd2e15..d8d800faf4 100644 --- a/subxt/examples/storage_iterating_partial.rs +++ b/subxt/examples/storage_iterating_partial.rs @@ -38,11 +38,11 @@ async fn main() -> Result<(), Box> { // Get back an iterator of results. let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - while let Some(Ok((key, value))) = results.next().await { - println!("Key: 0x{}", hex::encode(&key)); - println!("Value: {:?}", value); + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value); } - Ok(()) } diff --git a/subxt/src/storage/mod.rs b/subxt/src/storage/mod.rs index 6307e88c06..267b335575 100644 --- a/subxt/src/storage/mod.rs +++ b/subxt/src/storage/mod.rs @@ -12,7 +12,7 @@ pub mod utils; pub use storage_client::StorageClient; -pub use storage_type::Storage; +pub use storage_type::{Storage, StorageKeyValuePair}; /// Types representing an address which describes where a storage /// entry lives and how to properly decode it. diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index e6fff9746a..c0dfa74dc7 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -20,6 +20,8 @@ use subxt_metadata::{StorageEntryType, StorageHasher}; pub trait StorageAddress { /// The target type of the value that lives at this address. type Target: DecodeWithMetadata; + /// The keys type used to construc this address. + type Keys: StorageMultiKey; /// Can an entry be fetched from this address? /// Set this type to [`Yes`] to enable the corresponding calls to be made. type IsFetchable; @@ -66,6 +68,8 @@ pub struct Address { bytes: Static, _marker: std::marker::PhantomData, @@ -378,6 +382,7 @@ where ReturnTy: DecodeWithMetadata, { type Target = ReturnTy; + type Keys = Keys; type IsFetchable = Fetchable; type IsDefaultable = Defaultable; type IsIterable = Iterable; diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index 2669c1abce..1c46df55b3 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -2,19 +2,21 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. -use super::storage_address::{StorageAddress, Yes}; +use super::storage_address::{StorageAddress, StorageMultiKey, Yes}; use crate::{ backend::{BackendExt, BlockRef}, client::OnlineClientT, - error::{Error, MetadataError}, + error::{Error, MetadataError, StorageAddressError}, metadata::{DecodeWithMetadata, Metadata}, Config, }; use codec::Decode; use derivative::Derivative; use futures::StreamExt; +use scale_info::TypeDef; use std::{future::Future, marker::PhantomData}; +use subxt_metadata::StorageHasher; use subxt_metadata::{PalletMetadata, StorageEntryMetadata, StorageEntryType}; /// This is returned from a couple of storage functions. @@ -206,9 +208,10 @@ where pub fn iter
( &self, address: Address, - ) -> impl Future, Address::Target)>, Error>> + 'static + ) -> impl Future>, Error>> + 'static where Address: StorageAddress + 'static, + Address::Keys: 'static + Sized, { let client = self.client.clone(); let block_ref = self.block_ref.clone(); @@ -226,7 +229,10 @@ where // Look up the return type for flexible decoding. Do this once here to avoid // potentially doing it every iteration if we used `decode_storage_with_metadata` // in the iterator. - let return_type_id = return_type_from_storage_entry_type(entry.entry_type()); + let entry = entry.entry_type(); + + let return_type_id = entry.value_ty(); + let hasher_type_id_pairs = storage_hasher_type_id_pairs(entry, &metadata)?; // The address bytes of this entry: let address_bytes = super::utils::storage_address_bytes(&address, &metadata)?; @@ -240,12 +246,24 @@ where Ok(kv) => kv, Err(e) => return Err(e), }; - let val = Address::Target::decode_with_metadata( + let value = Address::Target::decode_with_metadata( &mut &*kv.value, return_type_id, &metadata, )?; - Ok((kv.key, val)) + + let key_bytes = kv.key; + let keys = ::decode_from_address_bytes( + &key_bytes, + &hasher_type_id_pairs, + &metadata, + ) + .transpose()?; + Ok(StorageKeyValuePair::
{ + keys, + key_bytes, + value, + }) }); let s = StreamOfResults::new(Box::pin(s)); @@ -290,6 +308,64 @@ where } } +pub(crate) fn storage_hasher_type_id_pairs( + entry: &StorageEntryType, + metadata: &Metadata, +) -> Result, Error> { + match entry { + StorageEntryType::Plain(_) => Ok(vec![]), + StorageEntryType::Map { + hashers, key_ty, .. + } => { + let ty = metadata + .types() + .resolve(*key_ty) + .ok_or(MetadataError::TypeNotFound(*key_ty))?; + match &ty.type_def { + TypeDef::Tuple(tuple) => { + if hashers.len() < tuple.fields.len() { + return Err(StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: tuple.fields.len(), + } + .into()); + } + let pairs: Vec<(StorageHasher, u32)> = tuple + .fields + .iter() + .zip(hashers.iter()) + .map(|(e, h)| (*h, e.id)) + .collect(); + + Ok(pairs) + } + _other => { + if hashers.is_empty() { + return Err(StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into()); + } + Ok(vec![(hashers[0], *key_ty)]) + } + } + } + } +} + +/// A pair of keys and values together with all the bytes that make up the storage address. +/// `keys` is `None` if non-concat hashers are used. In this case the keys could not be extracted back from the key_bytes. +#[derive(Clone, Debug)] +pub struct StorageKeyValuePair { + /// The keys that can be used to construct the address of this storage entry. + pub keys: Option, + /// The bytes that make up the address of the storage entry. + pub key_bytes: Vec, + /// The value of the storage entry. + pub value: T::Target, +} + /// Validate a storage address against the metadata. pub(crate) fn validate_storage_address( address: &Address, From 7a36ce3b544f2c9b4c96f4300721179a1d42ba52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 11:11:51 +0200 Subject: [PATCH 08/39] build(deps): bump js-sys from 0.3.67 to 0.3.68 (#1428) Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.67 to 0.3.68. - [Release notes](https://github.com/rustwasm/wasm-bindgen/releases) - [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustwasm/wasm-bindgen/commits) --- updated-dependencies: - dependency-name: js-sys dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c17152bc6..24fa08b271 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2289,9 +2289,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -5356,9 +5356,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5366,9 +5366,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", @@ -5393,9 +5393,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5403,9 +5403,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", @@ -5416,9 +5416,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "wasmi" diff --git a/Cargo.toml b/Cargo.toml index 6b92bf697d..1052322006 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ pin-project = "1.1.4" web-sys = { version = "0.3.67", features = ["BinaryType", "CloseEvent", "MessageEvent", "WebSocket"] } wasm-bindgen = "0.2.90" send_wrapper = "0.6.0" -js-sys = "0.3.67" +js-sys = "0.3.68" wasm-bindgen-futures = "0.4.38" futures-timer = "3" instant = { version = "0.1.12", default-features = false } From d7c658dba4edb558ff4b676ceee8b58d87ba344d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 11:12:04 +0200 Subject: [PATCH 09/39] build(deps): bump clap from 4.4.18 to 4.5.0 (#1427) Bumps [clap](https://github.com/clap-rs/clap) from 4.4.18 to 4.5.0. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.4.18...clap_complete-v4.5.0) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 32 +++++++++++++++++++------------- Cargo.toml | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24fa08b271..0972c7342b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -854,9 +854,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" dependencies = [ "clap_builder", "clap_derive", @@ -864,21 +864,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" dependencies = [ "anstream", "anstyle", - "clap_lex 0.6.0", - "strsim", + "clap_lex 0.7.0", + "strsim 0.11.0", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -897,9 +897,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "cmake" @@ -1231,7 +1231,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -1245,7 +1245,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 2.0.48", ] @@ -4488,6 +4488,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "strum" version = "0.24.1" @@ -4582,7 +4588,7 @@ dependencies = [ name = "subxt-cli" version = "0.34.0" dependencies = [ - "clap 4.4.18", + "clap 4.5.0", "color-eyre", "frame-metadata 16.0.0", "heck", diff --git a/Cargo.toml b/Cargo.toml index 1052322006..83b6cd9e2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,7 @@ assert_matches = "1.5.0" base58 = { version = "0.2.0" } bitvec = { version = "1", default-features = false } blake2 = { version = "0.10.6", default-features = false } -clap = { version = "4.4.18", features = ["derive", "cargo"] } +clap = { version = "4.5.0", features = ["derive", "cargo"] } criterion = "0.4" codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } color-eyre = "0.6.1" From b21e94d5e818e49d59ae4a7a30b5b0d2e4087b21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 11:12:24 +0200 Subject: [PATCH 10/39] build(deps): bump either from 1.9.0 to 1.10.0 (#1425) Bumps [either](https://github.com/rayon-rs/either) from 1.9.0 to 1.10.0. - [Commits](https://github.com/rayon-rs/either/compare/1.9.0...1.10.0) --- updated-dependencies: - dependency-name: either dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0972c7342b..b20b521cfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1466,9 +1466,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "environmental" diff --git a/Cargo.toml b/Cargo.toml index 83b6cd9e2a..41b89f26bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ color-eyre = "0.6.1" console_error_panic_hook = "0.1.7" darling = "0.20.5" derivative = "2.2.0" -either = "1.9.0" +either = "1.10.0" frame-metadata = { version = "16.0.0", default-features = false, features = ["current", "std"] } futures = { version = "0.3.30", default-features = false, features = ["std"] } getrandom = { version = "0.2", default-features = false } From 252e31e31eceb422c8cfcf1b4ea9f0e66621725d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 11:12:37 +0200 Subject: [PATCH 11/39] build(deps): bump thiserror from 1.0.56 to 1.0.57 (#1424) Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.56 to 1.0.57. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.56...1.0.57) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b20b521cfc..f86662aff7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4776,18 +4776,18 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 41b89f26bb..1eb24c2437 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,7 +86,7 @@ scale-encode = "0.5.0" serde = { version = "1.0.196" } serde_json = { version = "1.0.113" } syn = { version = "2.0.15", features = ["full", "extra-traits"] } -thiserror = "1.0.53" +thiserror = "1.0.57" tokio = { version = "1.36", default-features = false } tracing = "0.1.40" tracing-wasm = "0.2.1" From db12bd74d5c180a1764abf951f1931a93e503acf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 16:30:47 +0100 Subject: [PATCH 12/39] build(deps): bump jsonrpsee from 0.21.0 to 0.22.0 (#1426) * build(deps): bump jsonrpsee from 0.21.0 to 0.22.0 Bumps [jsonrpsee](https://github.com/paritytech/jsonrpsee) from 0.21.0 to 0.22.0. - [Release notes](https://github.com/paritytech/jsonrpsee/releases) - [Changelog](https://github.com/paritytech/jsonrpsee/blob/master/CHANGELOG.md) - [Commits](https://github.com/paritytech/jsonrpsee/compare/v0.21.0...v0.22.0) --- updated-dependencies: - dependency-name: jsonrpsee dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update Cargo.lock --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: James Wilson Co-authored-by: Niklas Adolfsson --- Cargo.lock | 111 +++++++++++------------------------------------------ Cargo.toml | 2 +- 2 files changed, 23 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f86662aff7..f082ecbe3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2296,61 +2296,30 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonrpsee" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9579d0ca9fb30da026bac2f0f7d9576ec93489aeb7cd4971dd5b4617d82c79b2" -dependencies = [ - "jsonrpsee-client-transport 0.21.0", - "jsonrpsee-core 0.21.0", - "jsonrpsee-http-client", - "jsonrpsee-types 0.21.0", -] - [[package]] name = "jsonrpsee" version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a95f7cc23d5fab0cdeeaf6bad8c8f5e7a3aa7f0d211957ea78232b327ab27b0" dependencies = [ - "jsonrpsee-core 0.22.0", - "jsonrpsee-types 0.22.0", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-types", "jsonrpsee-ws-client", ] -[[package]] -name = "jsonrpsee-client-transport" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9f9ed46590a8d5681975f126e22531698211b926129a40a2db47cbca429220" -dependencies = [ - "futures-channel", - "futures-util", - "gloo-net", - "http", - "jsonrpsee-core 0.21.0", - "pin-project", - "rustls-native-certs 0.7.0", - "rustls-pki-types", - "soketto", - "thiserror", - "tokio", - "tokio-rustls 0.25.0", - "tokio-util", - "tracing", - "url", -] - [[package]] name = "jsonrpsee-client-transport" version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1736cfa3845fd9f8f43751f2b8e0e83f7b6081e754502f7d63b6587692cc83" dependencies = [ + "futures-channel", "futures-util", + "gloo-net", "http", - "jsonrpsee-core 0.22.0", + "jsonrpsee-core", "pin-project", "rustls-native-certs 0.7.0", "rustls-pki-types", @@ -2363,31 +2332,6 @@ dependencies = [ "url", ] -[[package]] -name = "jsonrpsee-core" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "776d009e2f591b78c038e0d053a796f94575d66ca4e77dd84bfc5e81419e436c" -dependencies = [ - "anyhow", - "async-lock 3.3.0", - "async-trait", - "beef", - "futures-timer", - "futures-util", - "hyper", - "jsonrpsee-types 0.21.0", - "pin-project", - "rustc-hash", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-stream", - "tracing", - "wasm-bindgen-futures", -] - [[package]] name = "jsonrpsee-core" version = "0.22.0" @@ -2400,7 +2344,8 @@ dependencies = [ "beef", "futures-timer", "futures-util", - "jsonrpsee-types 0.22.0", + "hyper", + "jsonrpsee-types", "pin-project", "rustc-hash", "serde", @@ -2409,19 +2354,20 @@ dependencies = [ "tokio", "tokio-stream", "tracing", + "wasm-bindgen-futures", ] [[package]] name = "jsonrpsee-http-client" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b7de9f3219d95985eb77fd03194d7c1b56c19bce1abfcc9d07462574b15572" +checksum = "36a06ef0de060005fddf772d54597bb6a8b0413da47dcffd304b0306147b9678" dependencies = [ "async-trait", "hyper", "hyper-rustls", - "jsonrpsee-core 0.21.0", - "jsonrpsee-types 0.21.0", + "jsonrpsee-core", + "jsonrpsee-types", "serde", "serde_json", "thiserror", @@ -2431,19 +2377,6 @@ dependencies = [ "url", ] -[[package]] -name = "jsonrpsee-types" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3266dfb045c9174b24c77c2dfe0084914bb23a6b2597d70c9dc6018392e1cd1b" -dependencies = [ - "anyhow", - "beef", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "jsonrpsee-types" version = "0.22.0" @@ -2464,9 +2397,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5ce25d70a8e4d3cc574bbc3cad0137c326ad64b194793d5e7bbdd3fa4504181" dependencies = [ "http", - "jsonrpsee-client-transport 0.22.0", - "jsonrpsee-core 0.22.0", - "jsonrpsee-types 0.22.0", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", "url", ] @@ -3233,7 +3166,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ea5cf7b021db88f1af45a9b2ecdbe5bc1c5cbebc146632269d572cdd435f5cf" dependencies = [ "futures", - "jsonrpsee 0.22.0", + "jsonrpsee", "serde_json", "thiserror", "tokio", @@ -4556,7 +4489,7 @@ dependencies = [ "hex", "impl-serde", "instant", - "jsonrpsee 0.21.0", + "jsonrpsee", "parity-scale-codec", "primitive-types", "reconnecting-jsonrpsee-ws-client", @@ -4594,7 +4527,7 @@ dependencies = [ "heck", "hex", "indoc", - "jsonrpsee 0.21.0", + "jsonrpsee", "parity-scale-codec", "pretty_assertions", "quote", @@ -4621,7 +4554,7 @@ dependencies = [ "getrandom", "heck", "hex", - "jsonrpsee 0.21.0", + "jsonrpsee", "parity-scale-codec", "proc-macro2", "quote", @@ -4758,7 +4691,7 @@ version = "0.34.0" dependencies = [ "hex", "impl-serde", - "jsonrpsee 0.21.0", + "jsonrpsee", "parity-scale-codec", "serde", "substrate-runner", diff --git a/Cargo.toml b/Cargo.toml index 1eb24c2437..1bc484aca6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,7 +71,7 @@ hex = "0.4.3" heck = "0.4.1" impl-serde = { version = "0.4.0" } indoc = "2" -jsonrpsee = { version = "0.21" } +jsonrpsee = { version = "0.22" } pretty_assertions = "1.4.0" primitive-types = { version = "0.12.2", default-features = false, features = ["codec", "scale-info", "serde"] } proc-macro-error = "1.0.4" From 5313f6a2f4c06a5c3b971c8eb01373beb0ddd72b Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Tue, 13 Feb 2024 12:06:28 +0200 Subject: [PATCH 13/39] subxt: Derive `std::cmp` traits for subxt payloads and addresses (#1429) * subxt/tx: Derive std::cmp traits Signed-off-by: Alexandru Vasile * subxt/runtime_api: Derive std::cmp traits Signed-off-by: Alexandru Vasile * subxt/constants: Derive std::cmp traits Signed-off-by: Alexandru Vasile * subxt/custom_values: Derive std::cmp traits Signed-off-by: Alexandru Vasile * subxt/storage: Derive std::cmp traits Signed-off-by: Alexandru Vasile * subxt: Fix non_canonical_partial_ord_impl clippy introduced in 1.73 Signed-off-by: Alexandru Vasile * subxt: Add comment wrt derivative issue that triggers clippy warning Signed-off-by: Alexandru Vasile * Update subxt/src/backend/mod.rs * Update subxt/src/constants/constant_address.rs --------- Signed-off-by: Alexandru Vasile Co-authored-by: Niklas Adolfsson --- subxt/src/backend/mod.rs | 1 + subxt/src/constants/constant_address.rs | 15 ++++++++++++++- subxt/src/custom_values/custom_value_address.rs | 14 +++++++++++++- subxt/src/runtime_api/runtime_payload.rs | 6 +++++- subxt/src/storage/storage_address.rs | 9 ++++++++- subxt/src/tx/tx_payload.rs | 11 ++++++++++- 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/subxt/src/backend/mod.rs b/subxt/src/backend/mod.rs index 3db06818b3..e816bc904c 100644 --- a/subxt/src/backend/mod.rs +++ b/subxt/src/backend/mod.rs @@ -184,6 +184,7 @@ impl PartialEq for BlockRef { } impl Eq for BlockRef {} +// Manual implementation to work around https://github.com/mcarton/rust-derivative/issues/115. impl PartialOrd for BlockRef { fn partial_cmp(&self, other: &Self) -> Option { self.hash.partial_cmp(&other.hash) diff --git a/subxt/src/constants/constant_address.rs b/subxt/src/constants/constant_address.rs index e9a0eb37b0..3765d4c84b 100644 --- a/subxt/src/constants/constant_address.rs +++ b/subxt/src/constants/constant_address.rs @@ -28,7 +28,13 @@ pub trait ConstantAddress { /// This represents the address of a constant. #[derive(Derivative)] -#[derivative(Clone(bound = ""), Debug(bound = ""))] +#[derivative( + Clone(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + Ord(bound = ""), + PartialEq(bound = "") +)] pub struct Address { pallet_name: Cow<'static, str>, constant_name: Cow<'static, str>, @@ -36,6 +42,13 @@ pub struct Address { _marker: std::marker::PhantomData, } +// Manual implementation to work around https://github.com/mcarton/rust-derivative/issues/115. +impl PartialOrd for Address { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + /// The type of address typically used to return dynamic constant values. pub type DynamicAddress = Address; diff --git a/subxt/src/custom_values/custom_value_address.rs b/subxt/src/custom_values/custom_value_address.rs index f8034a161b..6e2f7f77ea 100644 --- a/subxt/src/custom_values/custom_value_address.rs +++ b/subxt/src/custom_values/custom_value_address.rs @@ -38,13 +38,25 @@ pub struct Yes; /// A static address to a custom value. #[derive(Derivative)] -#[derivative(Clone(bound = ""), Debug(bound = ""))] +#[derivative( + Clone(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + Ord(bound = ""), + PartialEq(bound = "") +)] pub struct StaticAddress { name: &'static str, hash: Option<[u8; 32]>, phantom: PhantomData<(ReturnTy, IsDecodable)>, } +impl PartialOrd for StaticAddress { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + impl StaticAddress { #[doc(hidden)] /// Creates a new StaticAddress. diff --git a/subxt/src/runtime_api/runtime_payload.rs b/subxt/src/runtime_api/runtime_payload.rs index cd5a3355b8..ff776eb14f 100644 --- a/subxt/src/runtime_api/runtime_payload.rs +++ b/subxt/src/runtime_api/runtime_payload.rs @@ -69,7 +69,11 @@ pub trait RuntimeApiPayload { #[derive(Derivative)] #[derivative( Clone(bound = "ArgsData: Clone"), - Debug(bound = "ArgsData: std::fmt::Debug") + Debug(bound = "ArgsData: std::fmt::Debug"), + Eq(bound = "ArgsData: std::cmp::Eq"), + Ord(bound = "ArgsData: std::cmp::Ord"), + PartialEq(bound = "ArgsData: std::cmp::PartialEq"), + PartialOrd(bound = "ArgsData: std::cmp::PartialOrd") )] pub struct Payload { trait_name: Cow<'static, str>, diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index c0dfa74dc7..a094ae1159 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -57,7 +57,14 @@ pub struct Yes; /// A concrete storage address. This can be created from static values (ie those generated /// via the `subxt` macro) or dynamic values via [`dynamic`]. #[derive(Derivative)] -#[derivative(Clone(bound = "Keys: Clone"), Debug(bound = "Keys: std::fmt::Debug"))] +#[derivative( + Clone(bound = "Keys: Clone"), + Debug(bound = "Keys: std::fmt::Debug"), + Eq(bound = "Keys: std::cmp::Eq"), + Ord(bound = "Keys: std::cmp::Ord"), + PartialEq(bound = "Keys: std::cmp::PartialEq"), + PartialOrd(bound = "Keys: std::cmp::PartialOrd") +)] pub struct Address { pallet_name: Cow<'static, str>, entry_name: Cow<'static, str>, diff --git a/subxt/src/tx/tx_payload.rs b/subxt/src/tx/tx_payload.rs index 508a6a99e6..ff9c71fd21 100644 --- a/subxt/src/tx/tx_payload.rs +++ b/subxt/src/tx/tx_payload.rs @@ -11,6 +11,7 @@ use crate::{ metadata::Metadata, }; use codec::Encode; +use derivative::Derivative; use scale_encode::EncodeAsFields; use scale_value::{Composite, ValueDef, Variant}; use std::{borrow::Cow, sync::Arc}; @@ -48,7 +49,15 @@ pub struct ValidationDetails<'a> { } /// A transaction payload containing some generic `CallData`. -#[derive(Clone, Debug)] +#[derive(Derivative)] +#[derivative( + Clone(bound = "CallData: Clone"), + Debug(bound = "CallData: std::fmt::Debug"), + Eq(bound = "CallData: std::cmp::Eq"), + Ord(bound = "CallData: std::cmp::Ord"), + PartialEq(bound = "CallData: std::cmp::PartialEq"), + PartialOrd(bound = "CallData: std::cmp::PartialOrd") +)] pub struct Payload { pallet_name: Cow<'static, str>, call_name: Cow<'static, str>, From cef1f6b5a4565a6afb895f4692ed14c8f4fb6005 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Thu, 15 Feb 2024 10:51:30 +0100 Subject: [PATCH 14/39] fix clippy --- subxt/src/storage/storage_address.rs | 6 +++--- subxt/src/storage/utils.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index a094ae1159..aca6d696c8 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -222,7 +222,7 @@ impl StorageMultiKey for Vec { let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); let mut result: Vec = vec![]; - while cursor.len() > 0 { + while !cursor.is_empty() { let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { // Still bytes left, but no hashers and type ids anymore to pull from: this is an unexpected error. return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); @@ -234,10 +234,10 @@ impl StorageMultiKey for Vec { Ok(decoded) => { match decoded.to_value() { Ok(value) => result.push(value.remove_context()), - Err(err) => return Some(Err(err.into())), + Err(err) => return Some(Err(err)), }; } - Err(err) => return Some(Err(err.into())), + Err(err) => return Some(Err(err)), } } Some(Ok(result)) diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index 27ab0a475c..c9dc5267d7 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -59,8 +59,8 @@ pub fn strip_storage_addess_root_bytes( /// Returns None(..) if the hasher provided is not a concat hasher. /// Returns Some(Err(..)) if there are not enough bytes. /// Returns Some(Ok(..)) if the stripping was successful. -pub fn strip_concat_hash_bytes<'a>( - hash: &'a mut &[u8], +pub fn strip_concat_hash_bytes( + hash: &mut &[u8], hasher: &StorageHasher, ) -> Option> { match hasher { From 62fd01f4d30cc961ad92a5fdfc1abee34efca532 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Thu, 15 Feb 2024 18:22:43 +0100 Subject: [PATCH 15/39] add integration tests --- subxt/src/storage/storage_type.rs | 6 +++--- .../src/full_client/storage/mod.rs | 16 ++++++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index 1c46df55b3..dba3a10c7c 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -356,12 +356,12 @@ pub(crate) fn storage_hasher_type_id_pairs( /// A pair of keys and values together with all the bytes that make up the storage address. /// `keys` is `None` if non-concat hashers are used. In this case the keys could not be extracted back from the key_bytes. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct StorageKeyValuePair { - /// The keys that can be used to construct the address of this storage entry. - pub keys: Option, /// The bytes that make up the address of the storage entry. pub key_bytes: Vec, + /// The keys that can be used to construct the address of this storage entry. + pub keys: Option, /// The value of the storage entry. pub value: T::Target, } diff --git a/testing/integration-tests/src/full_client/storage/mod.rs b/testing/integration-tests/src/full_client/storage/mod.rs index e1cec5f939..bb2585ef1b 100644 --- a/testing/integration-tests/src/full_client/storage/mod.rs +++ b/testing/integration-tests/src/full_client/storage/mod.rs @@ -167,9 +167,11 @@ async fn storage_partial_lookup() -> Result<(), subxt::Error> { let addr_bytes = api.storage().address_bytes(&addr)?; let mut results = api.storage().at_latest().await?.iter(addr).await?; let mut approvals = Vec::new(); - while let Some(Ok((key, value))) = results.next().await { - assert!(key.starts_with(&addr_bytes)); - approvals.push(value); + while let Some(Ok(kv)) = results.next().await { + assert!(kv.key_bytes.starts_with(&addr_bytes)); + kv.keys + .expect("concat hasher used for approvals, so should be Some(..)"); + approvals.push(kv.value); } assert_eq!(approvals.len(), assets.len()); let mut amounts = approvals.iter().map(|a| a.amount).collect::>(); @@ -188,9 +190,11 @@ async fn storage_partial_lookup() -> Result<(), subxt::Error> { let mut results = api.storage().at_latest().await?.iter(addr).await?; let mut approvals = Vec::new(); - while let Some(Ok((key, value))) = results.next().await { - assert!(key.starts_with(&addr_bytes)); - approvals.push(value); + while let Some(Ok(kv)) = results.next().await { + assert!(kv.key_bytes.starts_with(&addr_bytes)); + kv.keys + .expect("concat hasher used for approvals, so should be Some(..)"); + approvals.push(kv.value); } assert_eq!(approvals.len(), 1); assert_eq!(approvals[0].amount, amount); From b131b0fee47c610a3863b7208dba3a596878e900 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Fri, 16 Feb 2024 09:34:21 +0100 Subject: [PATCH 16/39] fix doc tests --- subxt/src/book/usage/storage.rs | 2 +- subxt/src/storage/storage_type.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/subxt/src/book/usage/storage.rs b/subxt/src/book/usage/storage.rs index 6d636c6bc3..f1c9ede5ef 100644 --- a/subxt/src/book/usage/storage.rs +++ b/subxt/src/book/usage/storage.rs @@ -49,7 +49,7 @@ //! // A static query capable of iterating over accounts: //! let storage_query = polkadot::storage().system().account_iter(); //! // A dynamic query to do the same: -//! let storage_query = subxt::dynamic::storage("System", "Account", Vec::::new()); +//! let storage_query = subxt::dynamic::storage("System", "Account", ()); //! ``` //! //! Some storage entries are maps with multiple keys. As an example, we might end up with diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index dba3a10c7c..75176f77da 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -199,9 +199,9 @@ where /// .await /// .unwrap(); /// - /// while let Some(Ok((key, value))) = iter.next().await { - /// println!("Key: 0x{}", hex::encode(&key)); - /// println!("Value: {}", value); + /// while let Some(Ok(kv)) = iter.next().await { + /// println!("Key bytes: 0x{}", hex::encode(&kv.key_bytes)); + /// println!("Value: {}", kv.value); /// } /// # } /// ``` From 1b856bca8d059a2f11843248ec86a34ee09f360b Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Fri, 16 Feb 2024 10:33:10 +0100 Subject: [PATCH 17/39] change hashing logic for hashers=1 --- subxt/src/storage/storage_address.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index aca6d696c8..2b391af662 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -442,15 +442,6 @@ where _other => either::Either::Right(std::iter::once(*key_ty)), }; - // Provided more fields than hashers: This is unacceptable (on the contrary, providing more hashers than keys is ok) - if hashers.len() < type_ids.len() { - return Err(StorageAddressError::WrongNumberOfHashers { - hashers: hashers.len(), - fields: type_ids.len(), - } - .into()); - } - if hashers.len() == 1 { // One hasher; hash a tuple of all SCALE encoded bytes with the one hash function. let mut input = Vec::new(); @@ -459,7 +450,7 @@ where key.encode_with_metadata(type_id, metadata, &mut input)?; } hash_bytes(&input, &hashers[0], bytes); - } else { + } else if hashers.len() >= type_ids.len() { // A hasher per field; encode and hash each field independently. let iter = keys_iter.zip(type_ids).zip(hashers); for ((key, type_id), hasher) in iter { @@ -467,6 +458,13 @@ where key.encode_with_metadata(type_id, metadata, &mut input)?; hash_bytes(&input, hasher, bytes); } + } else { + // Provided more fields than hashers. + return Err(StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: type_ids.len(), + } + .into()); } Ok(()) From b0ddafa9c531b95e97d18568b547a9d9a2278c73 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Fri, 16 Feb 2024 18:33:30 +0100 Subject: [PATCH 18/39] refactor --- codegen/src/api/storage.rs | 8 +- subxt/src/error/mod.rs | 2 +- subxt/src/storage/mod.rs | 5 +- subxt/src/storage/storage_address.rs | 256 +----- subxt/src/storage/storage_key.rs | 236 +++++ subxt/src/storage/storage_type.rs | 5 +- subxt/src/storage/utils.rs | 4 +- .../src/full_client/codegen/polkadot.rs | 828 ++++++++++-------- 8 files changed, 712 insertions(+), 632 deletions(-) create mode 100644 subxt/src/storage/storage_key.rs diff --git a/codegen/src/api/storage.rs b/codegen/src/api/storage.rs index 41ebb4fd3e..60860a8cb8 100644 --- a/codegen/src/api/storage.rs +++ b/codegen/src/api/storage.rs @@ -152,15 +152,15 @@ fn generate_storage_entry_fns( 0 => (quote!( () ), quote!( () )), 1 => { let field_name = &keys_slice[0].0; - let keys = quote!( #crate_path::storage::address::StorageKey::new(#field_name.borrow()) ); + let keys = quote!( #crate_path::storage::address::StaticStorageKey::new(#field_name.borrow()) ); let path = &keys_slice[0].2; - let path = quote!( #crate_path::storage::address::StorageKey<#path> ); + let path = quote!( #crate_path::storage::address::StaticStorageKey<#path> ); (keys, path) } _ => { - let keys_iter = keys_slice.iter().map(|(field_name, _, _)| quote!( #crate_path::storage::address::StorageKey::new(#field_name.borrow()) )); + let keys_iter = keys_slice.iter().map(|(field_name, _, _)| quote!( #crate_path::storage::address::StaticStorageKey::new(#field_name.borrow()) )); let keys = quote!( (#(#keys_iter,)*) ); - let paths_iter = keys_slice.iter().map(|(_, _, path_to_alias)| quote!( #crate_path::storage::address::StorageKey<#path_to_alias> ) ); + let paths_iter = keys_slice.iter().map(|(_, _, path_to_alias)| quote!( #crate_path::storage::address::StaticStorageKey<#path_to_alias> ) ); let paths = quote!( (#(#paths_iter,)*) ); (keys, paths) } diff --git a/subxt/src/error/mod.rs b/subxt/src/error/mod.rs index 73a4be23a1..a0bafaff8a 100644 --- a/subxt/src/error/mod.rs +++ b/subxt/src/error/mod.rs @@ -207,7 +207,7 @@ pub enum StorageAddressError { fields: usize, }, /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. - #[error("Storage address bytes are not the expected format")] + #[error("Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata.")] UnexpectedAddressBytes, } diff --git a/subxt/src/storage/mod.rs b/subxt/src/storage/mod.rs index 267b335575..f1e3b706f9 100644 --- a/subxt/src/storage/mod.rs +++ b/subxt/src/storage/mod.rs @@ -6,6 +6,7 @@ mod storage_address; mod storage_client; +mod storage_key; mod storage_type; pub mod utils; @@ -18,10 +19,12 @@ pub use storage_type::{Storage, StorageKeyValuePair}; /// entry lives and how to properly decode it. pub mod address { pub use super::storage_address::{ - dynamic, Address, DynamicAddress, StorageAddress, StorageKey, Yes, + dynamic, Address, DynamicAddress, StaticStorageKey, StorageAddress, Yes, }; } +pub use storage_key::StorageKey; + // For consistency with other modules, also expose // the basic address stuff at the root of the module. pub use storage_address::{dynamic, Address, DynamicAddress, StorageAddress}; diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 2b391af662..6a924dc2d7 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -6,22 +6,23 @@ use crate::{ dynamic::DecodedValueThunk, error::{Error, MetadataError, StorageAddressError}, metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, - storage::utils::{strip_concat_hash_bytes, strip_storage_addess_root_bytes}, utils::{Encoded, Static}, }; use derivative::Derivative; -use scale_encode::EncodeAsType; + use scale_info::TypeDef; use std::borrow::Cow; use subxt_metadata::{StorageEntryType, StorageHasher}; +use super::StorageKey; + /// This represents a storage address. Anything implementing this trait /// can be used to fetch and iterate over storage entries. pub trait StorageAddress { /// The target type of the value that lives at this address. type Target: DecodeWithMetadata; - /// The keys type used to construc this address. - type Keys: StorageMultiKey; + /// The keys type used to construct this address. + type Keys: StorageKey; /// Can an entry be fetched from this address? /// Set this type to [`Yes`] to enable the corresponding calls to be made. type IsFetchable; @@ -65,7 +66,7 @@ pub struct Yes; PartialEq(bound = "Keys: std::cmp::PartialEq"), PartialOrd(bound = "Keys: std::cmp::PartialOrd") )] -pub struct Address { +pub struct Address { pallet_name: Cow<'static, str>, entry_name: Cow<'static, str>, keys: Keys, @@ -73,19 +74,19 @@ pub struct Address, } -/// A storage key, mostly used for static encoded values. -/// The original value is only given during construction, but can be +/// A storage key for static encoded values. +/// The original value is only present at construction, but can be decoded from the contained bytes. #[derive(Derivative)] #[derivative(Clone(bound = ""), Debug(bound = ""))] -pub struct StorageKey { - bytes: Static, - _marker: std::marker::PhantomData, +pub struct StaticStorageKey { + pub(super) bytes: Static, + pub(super) _marker: std::marker::PhantomData, } -impl StorageKey { +impl StaticStorageKey { /// Creates a new static storage key pub fn new(key: &K) -> Self { - StorageKey { + StaticStorageKey { bytes: Static(Encoded(key.encode())), _marker: std::marker::PhantomData, } @@ -97,232 +98,11 @@ impl StorageKey { } } -/// This trait should be implemented by anything that can be used as one or multiple storage keys. -pub trait StorageMultiKey { - /// Iterator over the storage keys, each key implements EncodeAsType to - /// give the corresponding bytes to a `StorageHasher`. - fn keys_iter(&self) -> impl ExactSizeIterator; - - /// Attempts to decode the StorageMultiKey from a whole storage address. - /// The key/keys can only be recovered if all hashers are concat-style hashers. - /// Example: Imagine The `StorageMultiKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. - /// Then the memory layout of the storage key is: - /// ```txt - /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | - /// ``` - /// Returns None, if any of the hashers is not a concat-style hasher. - fn decode_from_address_bytes( - address_bytes: &[u8], - hashers_and_ty_ids: &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Option> - where - Self: Sized + 'static; -} - -/// Implement `StorageMultiKey` for `()` which can be used for keyless storage entries -impl StorageMultiKey for () { - fn keys_iter(&self) -> impl ExactSizeIterator { - // Note: this returns the storage root address of the storage entry. - // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. - std::iter::empty() - } - - fn decode_from_address_bytes( - address_bytes: &[u8], - _hashers_and_ty_ids: &[(StorageHasher, u32)], - _metadata: &Metadata, - ) -> Option> { - if address_bytes.len() < 16 { - return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); - } - Some(Ok(())) - } -} - -// Note: The ?Sized bound is necessary to support e.g. `StorageKey<[u8]>`. -impl StorageMultiKey for StorageKey { - fn keys_iter(&self) -> impl ExactSizeIterator { - // Note: this returns the storage root address of the storage entry. - // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. - std::iter::once(&self.bytes as &dyn EncodeAsType) - } - - fn decode_from_address_bytes( - address_bytes: &[u8], - hashers_and_ty_ids: &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Option> - where - Self: Sized + 'static, - { - let cursor = &mut &*address_bytes; - if let Err(err) = strip_storage_addess_root_bytes(cursor) { - return Some(Err(err.into())); - } - - let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { - return Some(Err(StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into())); - }; - decode_storage_key_from_hash(address_bytes, cursor, hasher, *ty_id, metadata) - } -} - -pub fn decode_storage_key_from_hash( - address_bytes: &[u8], - cursor: &mut &[u8], - hasher: &StorageHasher, - ty_id: u32, - metadata: &Metadata, -) -> Option, Error>> { - if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { - return Some(Err(err.into())); - } - let start_idx = address_bytes.len() - cursor.len(); - if let Err(err) = scale_decode::visitor::decode_with_visitor( - cursor, - ty_id, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) { - return Some(Err(scale_decode::Error::from(err).into())); - } - let end_idx = address_bytes.len() - cursor.len(); - let key_bytes = address_bytes[start_idx..end_idx].to_vec(); - let key = StorageKey { - bytes: Static(Encoded(key_bytes)), - _marker: std::marker::PhantomData::, - }; - Some(Ok(key)) -} - -impl StorageMultiKey for Vec { - fn keys_iter(&self) -> impl ExactSizeIterator { - // Note: this returns the storage root address of the storage entry. - // It gives the same result as if you were to use `vec![]` as a `StorageMultiKey`. - self.iter().map(|e| e as &dyn EncodeAsType) - } - - fn decode_from_address_bytes( - address_bytes: &[u8], - hashers_and_ty_ids: &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Option> - where - Self: Sized + 'static, - { - let cursor = &mut &*address_bytes; - if let Err(err) = strip_storage_addess_root_bytes(cursor) { - return Some(Err(err.into())); - } - let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); - - let mut result: Vec = vec![]; - while !cursor.is_empty() { - let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { - // Still bytes left, but no hashers and type ids anymore to pull from: this is an unexpected error. - return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); - }; - if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { - return Some(Err(err.into())); - } - match DecodedValueThunk::decode_with_metadata(cursor, *ty_id, metadata) { - Ok(decoded) => { - match decoded.to_value() { - Ok(value) => result.push(value.remove_context()), - Err(err) => return Some(Err(err)), - }; - } - Err(err) => return Some(Err(err)), - } - } - Some(Ok(result)) - } -} - -/// Generates StorageMultiKey implementations for tuples, e.g. -/// ```rs,norun -/// impl StorageMultiKey for (StorageKey, StorageKey) { -/// fn keys_iter(&self) -> impl ExactSizeIterator { -/// let arr = [&self.0 as &dyn EncodeAsType, &self.1 as &dyn EncodeAsType]; -/// arr.into_iter() -/// } -/// } -/// ``` -macro_rules! impl_tuples { - ($($ty:ident $n:tt),+) => {{ - impl<$($ty: EncodeAsType + ?Sized),+> StorageMultiKey for ($( StorageKey<$ty >),+) { - fn keys_iter(&self) -> impl ExactSizeIterator { - let arr = [$( - &self.$n.bytes as &dyn EncodeAsType - ),+]; - arr.into_iter() - } - - fn decode_from_address_bytes( - address_bytes: &[u8], - hashers_and_ty_ids: &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Option> - where - Self: Sized + 'static, - { - let cursor = &mut &*address_bytes; - if let Err(err) = strip_storage_addess_root_bytes(cursor) { - return Some(Err(err.into())); - } - - // The number of elements in this tuple. - const LEN: usize = $((0*$n + 1)+)+0; - - // It is an error to not provide a hasher and type id for each element in this tuple. - if hashers_and_ty_ids.len() < LEN { - return Some(Err(StorageAddressError::WrongNumberOfKeys{actual: hashers_and_ty_ids.len(), expected: LEN}.into())) - } - - // Construct the tuple as a series of expressions. - let tuple : Self = ( $( - { - // index is available, because of bounds check above; qed - let (hasher, ty_id) = &hashers_and_ty_ids[$n]; - let key = match decode_storage_key_from_hash::<$ty>(address_bytes, cursor, hasher, *ty_id, metadata)? { - Ok(key) => key, - Err(err) => { - return Some(Err(err)); - } - }; - key - }, - )+); - return Some(Ok(tuple)) - } - } - }}; -} - -#[rustfmt::skip] -const _: () = { - impl_tuples!(A 0, B 1); - impl_tuples!(A 0, B 1, C 2); - impl_tuples!(A 0, B 1, C 2, D 3); - impl_tuples!(A 0, B 1, C 2, D 3, E 4); - impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5); - impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6); - impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7); -}; - -// todo! impl MultiStorageKey for Vec> and for (StorageKey, StorageKey), ... -// impl MultiStorageKey - /// A typical storage address constructed at runtime rather than via the `subxt` macro; this /// has no restriction on what it can be used for (since we don't statically know). pub type DynamicAddress = Address; -impl DynamicAddress { +impl DynamicAddress { /// Creates a new dynamic address. As `Keys` you can use a `Vec` pub fn new(pallet_name: impl Into, entry_name: impl Into, keys: Keys) -> Self { Self { @@ -338,7 +118,7 @@ impl DynamicAddress { impl Address where - Keys: StorageMultiKey, + Keys: StorageKey, ReturnTy: DecodeWithMetadata, { /// Create a new [`Address`] using static strings for the pallet and call name. @@ -363,7 +143,7 @@ where impl Address where - Keys: StorageMultiKey, + Keys: StorageKey, ReturnTy: DecodeWithMetadata, { /// Do not validate this storage entry prior to accessing it. @@ -385,7 +165,7 @@ where impl StorageAddress for Address where - Keys: StorageMultiKey, + Keys: StorageKey, ReturnTy: DecodeWithMetadata, { type Target = ReturnTy; @@ -476,7 +256,7 @@ where } /// Construct a new dynamic storage lookup. -pub fn dynamic( +pub fn dynamic( pallet_name: impl Into, entry_name: impl Into, storage_entry_keys: Keys, diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs new file mode 100644 index 0000000000..1db4de8295 --- /dev/null +++ b/subxt/src/storage/storage_key.rs @@ -0,0 +1,236 @@ +use super::{ + storage_address::StaticStorageKey, + utils::{strip_concat_hash_bytes, strip_storage_addess_root_bytes}, +}; + +use crate::{ + dynamic::DecodedValueThunk, + error::{Error, StorageAddressError}, + metadata::{DecodeWithMetadata, Metadata}, + utils::{Encoded, Static}, +}; + +use futures::StreamExt; +use scale_encode::EncodeAsType; + +use subxt_metadata::StorageHasher; + +/// This trait should be implemented by anything that can be used as one or multiple storage keys. +pub trait StorageKey { + /// Iterator over the storage keys, each key implements EncodeAsType to + /// give the corresponding bytes to a `StorageHasher`. + fn keys_iter(&self) -> impl ExactSizeIterator; + + /// Attempts to decode the StorageKey from a whole storage address. + /// The key/keys can only be recovered if all hashers are concat-style hashers. + /// Example: Imagine The `StorageKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. + /// Then the memory layout of the storage key is: + /// ```txt + /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | + /// ``` + /// Returns None, if any of the hashers is not a concat-style hasher. + fn decode_from_address_bytes( + address_bytes: &[u8], + hashers_and_ty_ids: &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Option> + where + Self: Sized + 'static; +} + +/// Implement `StorageKey` for `()` which can be used for keyless storage entries +impl StorageKey for () { + fn keys_iter(&self) -> impl ExactSizeIterator { + // Note: this returns the storage root address of the storage entry. + // It gives the same result as if you were to use `vec![]` as a `StorageKey`. + std::iter::empty() + } + + fn decode_from_address_bytes( + address_bytes: &[u8], + _hashers_and_ty_ids: &[(StorageHasher, u32)], + _metadata: &Metadata, + ) -> Option> { + // We need at least 16 bytes, becauase there are 8 bytes for the pallet hash and + // another 8 bytes for the entry hash at the beginning of each storage address. + if address_bytes.len() < 16 { + return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); + } + Some(Ok(())) + } +} + +// Note: The ?Sized bound is necessary to support e.g. `StorageKey<[u8]>`. +impl StorageKey for StaticStorageKey { + fn keys_iter(&self) -> impl ExactSizeIterator { + // Note: this returns the storage root address of the storage entry. + // It gives the same result as if you were to use `vec![]` as a `StorageKey`. + std::iter::once(&self.bytes as &dyn EncodeAsType) + } + + fn decode_from_address_bytes( + address_bytes: &[u8], + hashers_and_ty_ids: &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Option> + where + Self: Sized + 'static, + { + let cursor = &mut &*address_bytes; + if let Err(err) = strip_storage_addess_root_bytes(cursor) { + return Some(Err(err.into())); + } + + let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { + return Some(Err(StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into())); + }; + decode_storage_key_from_hash(address_bytes, cursor, hasher, *ty_id, metadata) + } +} + +pub fn decode_storage_key_from_hash( + address_bytes: &[u8], + cursor: &mut &[u8], + hasher: &StorageHasher, + ty_id: u32, + metadata: &Metadata, +) -> Option, Error>> { + if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { + return Some(Err(err.into())); + } + let start_idx = address_bytes.len() - cursor.len(); + if let Err(err) = scale_decode::visitor::decode_with_visitor( + cursor, + ty_id, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) { + return Some(Err(scale_decode::Error::from(err).into())); + } + let end_idx = address_bytes.len() - cursor.len(); + let key_bytes = address_bytes[start_idx..end_idx].to_vec(); + let key = StaticStorageKey { + bytes: Static(Encoded(key_bytes)), + _marker: std::marker::PhantomData::, + }; + Some(Ok(key)) +} + +impl StorageKey for Vec { + fn keys_iter(&self) -> impl ExactSizeIterator { + // Note: this returns the storage root address of the storage entry. + // It gives the same result as if you were to use `vec![]` as a `StorageKey`. + self.iter().map(|e| e as &dyn EncodeAsType) + } + + fn decode_from_address_bytes( + address_bytes: &[u8], + hashers_and_ty_ids: &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Option> + where + Self: Sized + 'static, + { + let cursor = &mut &*address_bytes; + if let Err(err) = strip_storage_addess_root_bytes(cursor) { + return Some(Err(err.into())); + } + let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); + + let mut result: Vec = vec![]; + while !cursor.is_empty() { + let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { + // Still bytes left, but no hashers and type ids anymore to pull from: this is an unexpected error. + return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); + }; + if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { + return Some(Err(err.into())); + } + match DecodedValueThunk::decode_with_metadata(cursor, *ty_id, metadata) { + Ok(decoded) => { + match decoded.to_value() { + Ok(value) => result.push(value.remove_context()), + Err(err) => return Some(Err(err)), + }; + } + Err(err) => return Some(Err(err)), + } + } + Some(Ok(result)) + } +} + +/// Generates StorageKey implementations for tuples, e.g. +/// ```rs,norun +/// impl StorageKey for (StorageKey, StorageKey) { +/// fn keys_iter(&self) -> impl ExactSizeIterator { +/// let arr = [&self.0 as &dyn EncodeAsType, &self.1 as &dyn EncodeAsType]; +/// arr.into_iter() +/// } +/// } +/// ``` +macro_rules! impl_tuples { + ($($ty:ident $n:tt),+) => {{ + impl<$($ty: EncodeAsType + ?Sized),+> StorageKey for ($( StaticStorageKey<$ty >),+) { + fn keys_iter(&self) -> impl ExactSizeIterator { + let arr = [$( + &self.$n.bytes as &dyn EncodeAsType + ),+]; + arr.into_iter() + } + + fn decode_from_address_bytes( + address_bytes: &[u8], + hashers_and_ty_ids: &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Option> + where + Self: Sized + 'static, + { + let cursor = &mut &*address_bytes; + if let Err(err) = strip_storage_addess_root_bytes(cursor) { + return Some(Err(err.into())); + } + + // The number of elements in this tuple. + const LEN: usize = $((0*$n + 1)+)+0; + + // It is an error to not provide a hasher and type id for each element in this tuple. + if hashers_and_ty_ids.len() < LEN { + return Some(Err(StorageAddressError::WrongNumberOfKeys{actual: hashers_and_ty_ids.len(), expected: LEN}.into())) + } + + // Construct the tuple as a series of expressions. + let tuple : Self = ( $( + { + // index is available, because of bounds check above; qed + let (hasher, ty_id) = &hashers_and_ty_ids[$n]; + let key = match decode_storage_key_from_hash::<$ty>(address_bytes, cursor, hasher, *ty_id, metadata)? { + Ok(key) => key, + Err(err) => { + return Some(Err(err)); + } + }; + key + }, + )+); + return Some(Ok(tuple)) + } + } + }}; +} + +#[rustfmt::skip] +const _: () = { + impl_tuples!(A 0, B 1); + impl_tuples!(A 0, B 1, C 2); + impl_tuples!(A 0, B 1, C 2, D 3); + impl_tuples!(A 0, B 1, C 2, D 3, E 4); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7); +}; diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index 75176f77da..eeed7e4d34 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -2,7 +2,8 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. -use super::storage_address::{StorageAddress, StorageMultiKey, Yes}; +use super::storage_address::{StorageAddress, Yes}; +use super::StorageKey; use crate::{ backend::{BackendExt, BlockRef}, @@ -253,7 +254,7 @@ where )?; let key_bytes = kv.key; - let keys = ::decode_from_address_bytes( + let keys = ::decode_from_address_bytes( &key_bytes, &hasher_type_id_pairs, &metadata, diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index c9dc5267d7..9af9a32fa5 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -44,7 +44,7 @@ pub(crate) fn storage_address_root_bytes(addr: &Address } /// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. -pub fn strip_storage_addess_root_bytes( +pub(crate) fn strip_storage_addess_root_bytes( address_bytes: &mut &[u8], ) -> Result<(), StorageAddressError> { if address_bytes.len() >= 16 { @@ -55,7 +55,7 @@ pub fn strip_storage_addess_root_bytes( } } -/// Strips the first few bytes off a hash produced byt a concat hasher. +/// Strips the first few bytes off a hash produced by a concat hasher. /// Returns None(..) if the hasher provided is not a concat hasher. /// Returns Some(Err(..)) if there are not enough bytes. /// Returns Some(Ok(..)) if the stripping was successful. diff --git a/testing/integration-tests/src/full_client/codegen/polkadot.rs b/testing/integration-tests/src/full_client/codegen/polkadot.rs index 8a85d5fcab..0a04efcc4f 100644 --- a/testing/integration-tests/src/full_client/codegen/polkadot.rs +++ b/testing/integration-tests/src/full_client/codegen/polkadot.rs @@ -4741,7 +4741,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::account::Account, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4750,7 +4750,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "Account", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 14u8, 233u8, 115u8, 214u8, 0u8, 109u8, 222u8, 121u8, 162u8, 65u8, 60u8, 175u8, 209u8, 79u8, 222u8, 124u8, 22u8, 235u8, 138u8, 176u8, 133u8, @@ -4850,7 +4850,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::block_hash::BlockHash, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4859,7 +4859,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "BlockHash", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 217u8, 32u8, 215u8, 253u8, 24u8, 182u8, 207u8, 178u8, 157u8, 24u8, 103u8, 100u8, 195u8, 165u8, 69u8, 152u8, 112u8, 181u8, 56u8, 192u8, @@ -4894,7 +4894,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::extrinsic_data::ExtrinsicData, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4903,7 +4903,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "ExtrinsicData", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 160u8, 180u8, 122u8, 18u8, 196u8, 26u8, 2u8, 37u8, 115u8, 232u8, 133u8, 220u8, 106u8, 245u8, 4u8, 129u8, 42u8, 84u8, 241u8, 45u8, 199u8, 179u8, @@ -5068,7 +5068,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::event_topics::EventTopics, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5077,7 +5077,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "EventTopics", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 40u8, 225u8, 14u8, 75u8, 44u8, 176u8, 76u8, 34u8, 143u8, 107u8, 69u8, 133u8, 114u8, 13u8, 172u8, 250u8, 141u8, 73u8, 12u8, 65u8, 217u8, 63u8, @@ -5791,7 +5791,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::under_construction::UnderConstruction, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -5800,7 +5800,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Babe", "UnderConstruction", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 120u8, 120u8, 59u8, 247u8, 50u8, 6u8, 220u8, 14u8, 2u8, 76u8, 203u8, 244u8, 232u8, 144u8, 253u8, 191u8, 101u8, 35u8, 99u8, 85u8, 111u8, @@ -6535,7 +6535,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::accounts::Accounts, ::subxt::storage::address::Yes, (), @@ -6544,7 +6544,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Indices", "Accounts", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 48u8, 189u8, 43u8, 119u8, 32u8, 168u8, 28u8, 12u8, 245u8, 81u8, 119u8, 182u8, 23u8, 201u8, 33u8, 147u8, 128u8, 171u8, 155u8, 134u8, 71u8, @@ -7577,7 +7577,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::account::Account, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7586,7 +7586,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Account", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 213u8, 38u8, 200u8, 69u8, 218u8, 0u8, 112u8, 181u8, 160u8, 23u8, 96u8, 90u8, 3u8, 88u8, 126u8, 22u8, 103u8, 74u8, 64u8, 69u8, 29u8, 247u8, @@ -7622,7 +7622,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::locks::Locks, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7631,7 +7631,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Locks", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 10u8, 223u8, 55u8, 0u8, 249u8, 69u8, 168u8, 41u8, 75u8, 35u8, 120u8, 167u8, 18u8, 132u8, 9u8, 20u8, 91u8, 51u8, 27u8, 69u8, 136u8, 187u8, @@ -7665,7 +7665,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::reserves::Reserves, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7674,7 +7674,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Reserves", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 112u8, 10u8, 241u8, 77u8, 64u8, 187u8, 106u8, 159u8, 13u8, 153u8, 140u8, 178u8, 182u8, 50u8, 1u8, 55u8, 149u8, 92u8, 196u8, 229u8, 170u8, @@ -7709,7 +7709,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::holds::Holds, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7718,7 +7718,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Holds", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 181u8, 39u8, 29u8, 45u8, 45u8, 198u8, 129u8, 210u8, 189u8, 183u8, 121u8, 125u8, 57u8, 90u8, 95u8, 107u8, 51u8, 13u8, 22u8, 105u8, 191u8, @@ -7753,7 +7753,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::freezes::Freezes, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -7762,7 +7762,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Balances", "Freezes", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 69u8, 49u8, 165u8, 76u8, 135u8, 142u8, 179u8, 118u8, 50u8, 109u8, 53u8, 112u8, 110u8, 94u8, 30u8, 93u8, 173u8, 38u8, 27u8, 142u8, 19u8, 5u8, @@ -8111,7 +8111,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::reports::Reports, ::subxt::storage::address::Yes, (), @@ -8120,7 +8120,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Offences", "Reports", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 255u8, 234u8, 162u8, 48u8, 243u8, 210u8, 198u8, 231u8, 218u8, 142u8, 167u8, 10u8, 232u8, 223u8, 239u8, 55u8, 74u8, 23u8, 14u8, 236u8, 88u8, @@ -8156,7 +8156,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::concurrent_reports_index::Param0, + >, types::concurrent_reports_index::ConcurrentReportsIndex, (), ::subxt::storage::address::Yes, @@ -8165,7 +8167,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Offences", "ConcurrentReportsIndex", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 170u8, 186u8, 72u8, 29u8, 251u8, 38u8, 193u8, 195u8, 109u8, 86u8, 0u8, 241u8, 20u8, 235u8, 108u8, 126u8, 215u8, 82u8, 73u8, 113u8, 199u8, @@ -8181,10 +8183,10 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::concurrent_reports_index::Param0, >, - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::concurrent_reports_index::Param1, >, ), @@ -8197,8 +8199,8 @@ pub mod api { "Offences", "ConcurrentReportsIndex", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 170u8, 186u8, 72u8, 29u8, 251u8, 38u8, 193u8, 195u8, 109u8, 86u8, 0u8, @@ -8257,7 +8259,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::historical_sessions::HistoricalSessions, ::subxt::storage::address::Yes, (), @@ -8266,7 +8268,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Historical", "HistoricalSessions", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 9u8, 138u8, 247u8, 141u8, 178u8, 146u8, 124u8, 81u8, 162u8, 211u8, 205u8, 149u8, 222u8, 254u8, 253u8, 188u8, 170u8, 242u8, 218u8, 41u8, @@ -8599,7 +8601,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::set_id_session::SetIdSession, ::subxt::storage::address::Yes, (), @@ -8608,7 +8610,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "SetIdSession", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 47u8, 0u8, 239u8, 121u8, 187u8, 213u8, 254u8, 50u8, 238u8, 10u8, 162u8, 65u8, 189u8, 166u8, 37u8, 74u8, 82u8, 81u8, 160u8, 20u8, 180u8, 253u8, @@ -8795,7 +8797,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::nodes::Nodes, ::subxt::storage::address::Yes, (), @@ -8804,7 +8806,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "Nodes", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 27u8, 84u8, 41u8, 195u8, 146u8, 81u8, 211u8, 189u8, 63u8, 125u8, 173u8, 206u8, 69u8, 198u8, 202u8, 213u8, 89u8, 31u8, 89u8, 177u8, 76u8, 154u8, @@ -9188,7 +9190,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::next_keys::NextKeys, ::subxt::storage::address::Yes, (), @@ -9197,7 +9199,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "NextKeys", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 13u8, 219u8, 184u8, 220u8, 199u8, 150u8, 34u8, 166u8, 125u8, 46u8, 26u8, 160u8, 113u8, 243u8, 227u8, 6u8, 121u8, 176u8, 222u8, 250u8, @@ -9233,7 +9235,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::key_owner::KeyOwner, (), (), @@ -9242,7 +9244,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Session", "KeyOwner", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 217u8, 204u8, 21u8, 114u8, 247u8, 129u8, 32u8, 242u8, 93u8, 91u8, 253u8, 253u8, 248u8, 90u8, 12u8, 202u8, 195u8, 25u8, 18u8, 100u8, @@ -9258,8 +9260,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::key_owner::KeyOwner, ::subxt::storage::address::Yes, @@ -9270,8 +9272,8 @@ pub mod api { "Session", "KeyOwner", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 217u8, 204u8, 21u8, 114u8, 247u8, 129u8, 32u8, 242u8, 93u8, 91u8, @@ -9700,7 +9702,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::set_id_session::SetIdSession, ::subxt::storage::address::Yes, (), @@ -9709,7 +9711,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Grandpa", "SetIdSession", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 47u8, 0u8, 239u8, 121u8, 187u8, 213u8, 254u8, 50u8, 238u8, 10u8, 162u8, 65u8, 189u8, 166u8, 37u8, 74u8, 82u8, 81u8, 160u8, 20u8, 180u8, 253u8, @@ -10696,7 +10698,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::proposals::Proposals, ::subxt::storage::address::Yes, (), @@ -10705,7 +10707,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "Proposals", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 207u8, 135u8, 145u8, 146u8, 48u8, 10u8, 252u8, 40u8, 20u8, 115u8, 205u8, 41u8, 173u8, 83u8, 115u8, 46u8, 106u8, 40u8, 130u8, 157u8, @@ -10806,7 +10808,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::spends::Spends, ::subxt::storage::address::Yes, (), @@ -10815,7 +10817,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Treasury", "Spends", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 207u8, 104u8, 63u8, 103u8, 177u8, 66u8, 236u8, 100u8, 122u8, 213u8, 125u8, 153u8, 180u8, 219u8, 124u8, 22u8, 88u8, 161u8, 188u8, 197u8, @@ -11338,7 +11340,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::voting_for::VotingFor, (), ::subxt::storage::address::Yes, @@ -11347,7 +11349,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ConvictionVoting", "VotingFor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 76u8, 63u8, 153u8, 193u8, 39u8, 137u8, 186u8, 29u8, 202u8, 56u8, 169u8, 56u8, 103u8, 138u8, 192u8, 18u8, 179u8, 114u8, 56u8, 121u8, 197u8, @@ -11363,8 +11365,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::voting_for::VotingFor, ::subxt::storage::address::Yes, @@ -11375,8 +11377,8 @@ pub mod api { "ConvictionVoting", "VotingFor", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 76u8, 63u8, 153u8, 193u8, 39u8, 137u8, 186u8, 29u8, 202u8, 56u8, 169u8, @@ -11415,7 +11417,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::class_locks_for::ClassLocksFor, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -11424,7 +11426,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ConvictionVoting", "ClassLocksFor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 74u8, 74u8, 8u8, 82u8, 215u8, 61u8, 13u8, 9u8, 44u8, 222u8, 33u8, 245u8, 195u8, 124u8, 6u8, 174u8, 65u8, 245u8, 71u8, 42u8, 47u8, 46u8, @@ -12360,7 +12362,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::referendum_info_for::ReferendumInfoFor, ::subxt::storage::address::Yes, (), @@ -12369,7 +12371,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "ReferendumInfoFor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 244u8, 215u8, 156u8, 181u8, 105u8, 12u8, 138u8, 249u8, 173u8, 158u8, 171u8, 67u8, 107u8, 228u8, 45u8, 180u8, 252u8, 244u8, 186u8, 78u8, @@ -12410,7 +12412,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::track_queue::TrackQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -12419,7 +12421,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "TrackQueue", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 125u8, 59u8, 111u8, 68u8, 27u8, 236u8, 82u8, 55u8, 83u8, 159u8, 105u8, 20u8, 241u8, 118u8, 58u8, 141u8, 103u8, 60u8, 246u8, 49u8, 121u8, @@ -12454,7 +12456,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::deciding_count::DecidingCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -12463,7 +12465,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "DecidingCount", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 203u8, 89u8, 158u8, 179u8, 194u8, 82u8, 248u8, 162u8, 93u8, 140u8, 146u8, 51u8, 110u8, 232u8, 51u8, 1u8, 128u8, 212u8, 199u8, 14u8, 182u8, @@ -12509,7 +12511,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::metadata_of::MetadataOf, ::subxt::storage::address::Yes, (), @@ -12518,7 +12520,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Referenda", "MetadataOf", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 159u8, 250u8, 56u8, 189u8, 247u8, 165u8, 206u8, 166u8, 91u8, 139u8, 124u8, 164u8, 25u8, 246u8, 199u8, 36u8, 159u8, 56u8, 227u8, 136u8, 4u8, @@ -13053,7 +13055,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::member_count::MemberCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -13062,7 +13064,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "MemberCount", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 0u8, 141u8, 66u8, 91u8, 155u8, 74u8, 17u8, 191u8, 143u8, 41u8, 231u8, 56u8, 123u8, 219u8, 145u8, 27u8, 197u8, 62u8, 118u8, 237u8, 30u8, 7u8, @@ -13097,7 +13099,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::members::Members, ::subxt::storage::address::Yes, (), @@ -13106,7 +13108,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "Members", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 101u8, 183u8, 36u8, 241u8, 67u8, 8u8, 252u8, 116u8, 110u8, 153u8, 117u8, 210u8, 128u8, 80u8, 130u8, 163u8, 38u8, 76u8, 230u8, 107u8, @@ -13141,7 +13143,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::id_to_index::IdToIndex, (), (), @@ -13150,7 +13152,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "IdToIndex", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 121u8, 225u8, 69u8, 131u8, 194u8, 3u8, 82u8, 27u8, 129u8, 152u8, 157u8, 45u8, 39u8, 47u8, 166u8, 28u8, 42u8, 92u8, 217u8, 189u8, 160u8, 102u8, @@ -13165,8 +13167,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::id_to_index::IdToIndex, ::subxt::storage::address::Yes, @@ -13177,8 +13179,8 @@ pub mod api { "FellowshipCollective", "IdToIndex", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 121u8, 225u8, 69u8, 131u8, 194u8, 3u8, 82u8, 27u8, 129u8, 152u8, 157u8, @@ -13216,7 +13218,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::index_to_id::IndexToId, (), (), @@ -13225,7 +13227,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "IndexToId", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 110u8, 48u8, 214u8, 224u8, 56u8, 195u8, 186u8, 24u8, 111u8, 37u8, 15u8, 153u8, 245u8, 101u8, 229u8, 149u8, 216u8, 185u8, 7u8, 242u8, 196u8, @@ -13242,8 +13244,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::index_to_id::IndexToId, ::subxt::storage::address::Yes, @@ -13254,8 +13256,8 @@ pub mod api { "FellowshipCollective", "IndexToId", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 110u8, 48u8, 214u8, 224u8, 56u8, 195u8, 186u8, 24u8, 111u8, 37u8, 15u8, @@ -13292,7 +13294,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::voting::Voting, (), (), @@ -13301,7 +13303,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "Voting", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 180u8, 146u8, 236u8, 178u8, 30u8, 50u8, 161u8, 50u8, 140u8, 110u8, 220u8, 1u8, 109u8, 209u8, 17u8, 94u8, 234u8, 223u8, 222u8, 177u8, @@ -13317,8 +13319,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::voting::Voting, ::subxt::storage::address::Yes, @@ -13329,8 +13331,8 @@ pub mod api { "FellowshipCollective", "Voting", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 180u8, 146u8, 236u8, 178u8, 30u8, 50u8, 161u8, 50u8, 140u8, 110u8, @@ -13364,7 +13366,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::voting_cleanup::VotingCleanup, ::subxt::storage::address::Yes, (), @@ -13373,7 +13375,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipCollective", "VotingCleanup", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 223u8, 130u8, 79u8, 104u8, 94u8, 221u8, 222u8, 72u8, 187u8, 95u8, 231u8, 59u8, 28u8, 119u8, 191u8, 63u8, 40u8, 186u8, 58u8, 254u8, 14u8, @@ -14261,7 +14263,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::referendum_info_for::ReferendumInfoFor, ::subxt::storage::address::Yes, (), @@ -14270,7 +14272,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "ReferendumInfoFor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 64u8, 146u8, 31u8, 207u8, 209u8, 86u8, 44u8, 53u8, 78u8, 240u8, 222u8, 131u8, 225u8, 83u8, 114u8, 205u8, 225u8, 20u8, 128u8, 183u8, 19u8, @@ -14312,7 +14314,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::track_queue::TrackQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -14321,7 +14323,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "TrackQueue", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 187u8, 113u8, 225u8, 99u8, 159u8, 207u8, 182u8, 41u8, 116u8, 136u8, 119u8, 196u8, 152u8, 50u8, 192u8, 22u8, 171u8, 182u8, 237u8, 228u8, @@ -14357,7 +14359,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::deciding_count::DecidingCount, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -14366,7 +14368,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "DecidingCount", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 203u8, 89u8, 158u8, 179u8, 194u8, 82u8, 248u8, 162u8, 93u8, 140u8, 146u8, 51u8, 110u8, 232u8, 51u8, 1u8, 128u8, 212u8, 199u8, 14u8, 182u8, @@ -14412,7 +14414,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::metadata_of::MetadataOf, ::subxt::storage::address::Yes, (), @@ -14421,7 +14423,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "FellowshipReferenda", "MetadataOf", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 159u8, 250u8, 56u8, 189u8, 247u8, 165u8, 206u8, 166u8, 91u8, 139u8, 124u8, 164u8, 25u8, 246u8, 199u8, 36u8, 159u8, 56u8, 227u8, 136u8, 4u8, @@ -14824,7 +14826,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::whitelisted_call::WhitelistedCall, ::subxt::storage::address::Yes, (), @@ -14833,7 +14835,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Whitelist", "WhitelistedCall", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 82u8, 208u8, 214u8, 72u8, 225u8, 35u8, 51u8, 212u8, 25u8, 138u8, 30u8, 87u8, 54u8, 232u8, 72u8, 132u8, 4u8, 9u8, 28u8, 143u8, 251u8, 106u8, @@ -15200,7 +15202,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::claims::Claims, ::subxt::storage::address::Yes, (), @@ -15209,7 +15211,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Claims", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 148u8, 115u8, 159u8, 169u8, 36u8, 116u8, 15u8, 108u8, 57u8, 195u8, 226u8, 180u8, 187u8, 112u8, 114u8, 63u8, 3u8, 205u8, 113u8, 141u8, @@ -15272,7 +15274,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::vesting::Vesting, ::subxt::storage::address::Yes, (), @@ -15281,7 +15283,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Vesting", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 206u8, 106u8, 195u8, 101u8, 55u8, 137u8, 50u8, 105u8, 137u8, 87u8, 230u8, 34u8, 255u8, 94u8, 210u8, 186u8, 179u8, 72u8, 24u8, 194u8, @@ -15316,7 +15318,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::signing::Signing, ::subxt::storage::address::Yes, (), @@ -15325,7 +15327,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Signing", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 111u8, 90u8, 178u8, 121u8, 241u8, 28u8, 169u8, 231u8, 61u8, 189u8, 113u8, 207u8, 26u8, 153u8, 189u8, 15u8, 192u8, 25u8, 22u8, 22u8, 124u8, @@ -15360,7 +15362,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::preclaims::Preclaims, ::subxt::storage::address::Yes, (), @@ -15369,7 +15371,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Claims", "Preclaims", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 197u8, 114u8, 147u8, 235u8, 203u8, 255u8, 94u8, 113u8, 151u8, 119u8, 224u8, 147u8, 48u8, 246u8, 124u8, 38u8, 190u8, 237u8, 226u8, 65u8, @@ -17270,7 +17272,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::identity_of::IdentityOf, ::subxt::storage::address::Yes, (), @@ -17279,7 +17281,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "IdentityOf", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 0u8, 73u8, 213u8, 52u8, 49u8, 235u8, 238u8, 43u8, 119u8, 12u8, 35u8, 162u8, 230u8, 24u8, 246u8, 200u8, 44u8, 254u8, 13u8, 84u8, 10u8, 27u8, @@ -17315,7 +17317,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::super_of::SuperOf, ::subxt::storage::address::Yes, (), @@ -17324,7 +17326,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "SuperOf", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 84u8, 72u8, 64u8, 14u8, 56u8, 9u8, 143u8, 100u8, 141u8, 163u8, 36u8, 55u8, 38u8, 254u8, 164u8, 17u8, 3u8, 110u8, 88u8, 175u8, 161u8, 65u8, @@ -17367,7 +17369,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::subs_of::SubsOf, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -17376,7 +17378,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "SubsOf", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 164u8, 140u8, 52u8, 123u8, 220u8, 118u8, 147u8, 3u8, 67u8, 22u8, 191u8, 18u8, 186u8, 21u8, 154u8, 8u8, 205u8, 224u8, 163u8, 173u8, 174u8, @@ -17436,7 +17438,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::username_authorities::Param0, + >, types::username_authorities::UsernameAuthorities, ::subxt::storage::address::Yes, (), @@ -17445,7 +17449,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "UsernameAuthorities", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 89u8, 102u8, 60u8, 184u8, 127u8, 244u8, 3u8, 61u8, 209u8, 78u8, 178u8, 44u8, 159u8, 27u8, 7u8, 0u8, 22u8, 116u8, 42u8, 240u8, 130u8, 93u8, @@ -17488,7 +17492,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::account_of_username::AccountOfUsername, ::subxt::storage::address::Yes, (), @@ -17497,7 +17501,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "AccountOfUsername", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 131u8, 96u8, 207u8, 217u8, 223u8, 54u8, 51u8, 156u8, 8u8, 238u8, 134u8, 57u8, 42u8, 110u8, 180u8, 107u8, 30u8, 109u8, 162u8, 110u8, 178u8, @@ -17543,7 +17547,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::pending_usernames::PendingUsernames, ::subxt::storage::address::Yes, (), @@ -17552,7 +17556,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Identity", "PendingUsernames", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 237u8, 213u8, 92u8, 249u8, 11u8, 169u8, 104u8, 7u8, 201u8, 133u8, 164u8, 64u8, 191u8, 172u8, 169u8, 229u8, 206u8, 105u8, 190u8, 113u8, @@ -19126,7 +19130,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::members::Members, ::subxt::storage::address::Yes, (), @@ -19135,7 +19139,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Members", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 207u8, 227u8, 130u8, 247u8, 29u8, 198u8, 129u8, 83u8, 3u8, 6u8, 19u8, 37u8, 163u8, 227u8, 0u8, 94u8, 8u8, 166u8, 111u8, 70u8, 101u8, 65u8, @@ -19169,7 +19173,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::payouts::Payouts, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -19178,7 +19182,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Payouts", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 251u8, 249u8, 170u8, 219u8, 131u8, 113u8, 178u8, 165u8, 173u8, 36u8, 175u8, 199u8, 57u8, 188u8, 59u8, 226u8, 4u8, 45u8, 36u8, 173u8, 113u8, @@ -19237,7 +19241,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::member_by_index::MemberByIndex, ::subxt::storage::address::Yes, (), @@ -19246,7 +19250,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "MemberByIndex", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 13u8, 233u8, 212u8, 149u8, 220u8, 158u8, 17u8, 27u8, 201u8, 61u8, 202u8, 248u8, 192u8, 37u8, 199u8, 73u8, 32u8, 140u8, 204u8, 206u8, @@ -19282,7 +19286,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::suspended_members::SuspendedMembers, ::subxt::storage::address::Yes, (), @@ -19291,7 +19295,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "SuspendedMembers", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 156u8, 11u8, 75u8, 79u8, 74u8, 79u8, 98u8, 89u8, 63u8, 83u8, 84u8, 249u8, 177u8, 227u8, 113u8, 21u8, 26u8, 165u8, 129u8, 5u8, 129u8, @@ -19367,7 +19371,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::candidates::Candidates, ::subxt::storage::address::Yes, (), @@ -19376,7 +19380,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Candidates", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 52u8, 250u8, 201u8, 163u8, 0u8, 5u8, 156u8, 84u8, 96u8, 130u8, 228u8, 205u8, 34u8, 75u8, 121u8, 209u8, 82u8, 15u8, 247u8, 21u8, 54u8, 177u8, @@ -19433,7 +19437,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::votes::Votes, (), (), @@ -19442,7 +19446,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "Votes", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 34u8, 201u8, 151u8, 130u8, 149u8, 159u8, 32u8, 201u8, 127u8, 178u8, 77u8, 214u8, 73u8, 158u8, 11u8, 247u8, 188u8, 156u8, 146u8, 59u8, @@ -19458,8 +19462,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::votes::Votes, ::subxt::storage::address::Yes, @@ -19470,8 +19474,8 @@ pub mod api { "Society", "Votes", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 34u8, 201u8, 151u8, 130u8, 149u8, 159u8, 32u8, 201u8, 127u8, 178u8, @@ -19508,7 +19512,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::vote_clear_cursor::VoteClearCursor, ::subxt::storage::address::Yes, (), @@ -19517,7 +19521,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "VoteClearCursor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 157u8, 200u8, 216u8, 228u8, 235u8, 144u8, 13u8, 111u8, 252u8, 213u8, 209u8, 114u8, 157u8, 159u8, 47u8, 125u8, 45u8, 152u8, 27u8, 145u8, @@ -19618,7 +19622,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::defender_votes::DefenderVotes, (), (), @@ -19627,7 +19631,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Society", "DefenderVotes", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 208u8, 137u8, 138u8, 215u8, 215u8, 207u8, 236u8, 140u8, 175u8, 50u8, 110u8, 228u8, 48u8, 174u8, 16u8, 59u8, 72u8, 108u8, 7u8, 183u8, 119u8, @@ -19643,8 +19647,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::defender_votes::DefenderVotes, ::subxt::storage::address::Yes, @@ -19655,8 +19659,8 @@ pub mod api { "Society", "DefenderVotes", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 208u8, 137u8, 138u8, 215u8, 215u8, 207u8, 236u8, 140u8, 175u8, 50u8, @@ -20391,7 +20395,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::recoverable::Recoverable, ::subxt::storage::address::Yes, (), @@ -20400,7 +20404,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "Recoverable", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 112u8, 7u8, 56u8, 46u8, 138u8, 197u8, 63u8, 234u8, 140u8, 123u8, 145u8, 106u8, 189u8, 190u8, 247u8, 61u8, 250u8, 67u8, 107u8, 42u8, 170u8, @@ -20441,7 +20445,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::active_recoveries::ActiveRecoveries, (), (), @@ -20450,7 +20454,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "ActiveRecoveries", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 104u8, 252u8, 28u8, 142u8, 48u8, 26u8, 91u8, 201u8, 184u8, 163u8, 180u8, 197u8, 189u8, 71u8, 144u8, 88u8, 225u8, 13u8, 183u8, 84u8, @@ -20469,8 +20473,12 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::active_recoveries::Param0, + >, + ::subxt::storage::address::StaticStorageKey< + types::active_recoveries::Param1, + >, ), types::active_recoveries::ActiveRecoveries, ::subxt::storage::address::Yes, @@ -20481,8 +20489,8 @@ pub mod api { "Recovery", "ActiveRecoveries", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 104u8, 252u8, 28u8, 142u8, 48u8, 26u8, 91u8, 201u8, 184u8, 163u8, @@ -20522,7 +20530,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::proxy::Proxy, ::subxt::storage::address::Yes, (), @@ -20531,7 +20539,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Recovery", "Proxy", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 161u8, 242u8, 17u8, 183u8, 161u8, 47u8, 87u8, 110u8, 201u8, 177u8, 199u8, 157u8, 30u8, 131u8, 49u8, 89u8, 182u8, 86u8, 152u8, 19u8, 199u8, @@ -20991,7 +20999,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::vesting::Vesting, ::subxt::storage::address::Yes, (), @@ -21000,7 +21008,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Vesting", "Vesting", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 95u8, 168u8, 217u8, 248u8, 149u8, 86u8, 195u8, 93u8, 73u8, 206u8, 105u8, 165u8, 33u8, 173u8, 232u8, 81u8, 147u8, 254u8, 50u8, 228u8, @@ -21620,7 +21628,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::agenda::Agenda, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -21629,7 +21637,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Agenda", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 10u8, 123u8, 252u8, 106u8, 154u8, 9u8, 245u8, 203u8, 188u8, 254u8, 20u8, 41u8, 6u8, 226u8, 78u8, 188u8, 0u8, 173u8, 143u8, 44u8, 117u8, @@ -21669,7 +21677,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::lookup::Lookup, ::subxt::storage::address::Yes, (), @@ -21678,7 +21686,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Lookup", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 24u8, 87u8, 96u8, 127u8, 136u8, 205u8, 238u8, 174u8, 71u8, 110u8, 65u8, 98u8, 228u8, 167u8, 99u8, 71u8, 171u8, 186u8, 12u8, 218u8, 137u8, 70u8, @@ -22417,7 +22425,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::proxies::Proxies, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -22426,7 +22434,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Proxy", "Proxies", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 92u8, 131u8, 10u8, 14u8, 241u8, 148u8, 230u8, 81u8, 54u8, 152u8, 147u8, 180u8, 85u8, 28u8, 87u8, 215u8, 110u8, 13u8, 158u8, 207u8, 77u8, 102u8, @@ -22461,7 +22469,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::announcements::Announcements, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -22470,7 +22478,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Proxy", "Announcements", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 129u8, 228u8, 198u8, 210u8, 90u8, 69u8, 151u8, 198u8, 206u8, 174u8, 148u8, 58u8, 134u8, 14u8, 53u8, 56u8, 234u8, 71u8, 84u8, 247u8, 246u8, @@ -22978,7 +22986,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::multisigs::Multisigs, (), (), @@ -22987,7 +22995,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Multisig", "Multisigs", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 154u8, 109u8, 45u8, 18u8, 155u8, 151u8, 81u8, 28u8, 86u8, 127u8, 189u8, 151u8, 49u8, 61u8, 12u8, 149u8, 84u8, 61u8, 110u8, 197u8, 200u8, 140u8, @@ -23002,8 +23010,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::multisigs::Multisigs, ::subxt::storage::address::Yes, @@ -23014,8 +23022,8 @@ pub mod api { "Multisig", "Multisigs", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 154u8, 109u8, 45u8, 18u8, 155u8, 151u8, 81u8, 28u8, 86u8, 127u8, 189u8, @@ -23422,7 +23430,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::status_for::StatusFor, ::subxt::storage::address::Yes, (), @@ -23431,7 +23439,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "StatusFor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 187u8, 100u8, 54u8, 112u8, 96u8, 129u8, 36u8, 149u8, 127u8, 226u8, 126u8, 171u8, 72u8, 189u8, 59u8, 126u8, 204u8, 125u8, 67u8, 204u8, @@ -23466,7 +23474,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::request_status_for::RequestStatusFor, ::subxt::storage::address::Yes, (), @@ -23475,7 +23483,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "RequestStatusFor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 72u8, 59u8, 254u8, 211u8, 96u8, 223u8, 10u8, 64u8, 6u8, 139u8, 213u8, 85u8, 14u8, 29u8, 166u8, 37u8, 140u8, 124u8, 186u8, 156u8, 172u8, @@ -23508,7 +23516,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::preimage_for::PreimageFor, (), (), @@ -23517,7 +23525,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Preimage", "PreimageFor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 106u8, 5u8, 17u8, 46u8, 6u8, 184u8, 177u8, 113u8, 169u8, 34u8, 119u8, 141u8, 117u8, 40u8, 30u8, 94u8, 187u8, 35u8, 206u8, 216u8, 143u8, @@ -23532,8 +23540,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::preimage_for::PreimageFor, ::subxt::storage::address::Yes, @@ -23544,8 +23552,8 @@ pub mod api { "Preimage", "PreimageFor", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 106u8, 5u8, 17u8, 46u8, 6u8, 184u8, 177u8, 113u8, 169u8, 34u8, 119u8, @@ -23830,7 +23838,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::conversion_rate_to_native::Param0, + >, types::conversion_rate_to_native::ConversionRateToNative, ::subxt::storage::address::Yes, (), @@ -23839,7 +23849,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssetRate", "ConversionRateToNative", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 230u8, 127u8, 110u8, 126u8, 79u8, 168u8, 134u8, 97u8, 195u8, 105u8, 16u8, 57u8, 197u8, 104u8, 87u8, 144u8, 83u8, 188u8, 85u8, 253u8, 230u8, @@ -24593,7 +24603,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::bounties::Bounties, ::subxt::storage::address::Yes, (), @@ -24602,7 +24612,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Bounties", "Bounties", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 183u8, 96u8, 172u8, 86u8, 167u8, 129u8, 51u8, 179u8, 238u8, 155u8, 196u8, 77u8, 158u8, 102u8, 188u8, 19u8, 79u8, 178u8, 145u8, 189u8, @@ -24637,7 +24647,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::bounty_descriptions::BountyDescriptions, ::subxt::storage::address::Yes, (), @@ -24646,7 +24656,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Bounties", "BountyDescriptions", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 71u8, 40u8, 133u8, 84u8, 55u8, 207u8, 169u8, 189u8, 160u8, 51u8, 202u8, 144u8, 15u8, 226u8, 97u8, 114u8, 54u8, 247u8, 53u8, 26u8, 36u8, 54u8, @@ -25380,7 +25390,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::parent_child_bounties::Param0, + >, types::parent_child_bounties::ParentChildBounties, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -25389,7 +25401,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ParentChildBounties", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 52u8, 179u8, 242u8, 212u8, 91u8, 185u8, 176u8, 52u8, 100u8, 200u8, 1u8, 41u8, 184u8, 234u8, 234u8, 8u8, 123u8, 252u8, 131u8, 55u8, 109u8, @@ -25424,7 +25436,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::child_bounties::ChildBounties, (), (), @@ -25433,7 +25445,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildBounties", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 165u8, 240u8, 158u8, 204u8, 183u8, 190u8, 129u8, 65u8, 226u8, 8u8, 182u8, 103u8, 46u8, 162u8, 35u8, 155u8, 131u8, 45u8, 163u8, 64u8, @@ -25449,8 +25461,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::child_bounties::ChildBounties, ::subxt::storage::address::Yes, @@ -25461,8 +25473,8 @@ pub mod api { "ChildBounties", "ChildBounties", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 165u8, 240u8, 158u8, 204u8, 183u8, 190u8, 129u8, 65u8, 226u8, 8u8, @@ -25498,7 +25510,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::child_bounty_descriptions::Param0, + >, types::child_bounty_descriptions::ChildBountyDescriptions, ::subxt::storage::address::Yes, (), @@ -25507,7 +25521,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildBountyDescriptions", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 192u8, 0u8, 220u8, 156u8, 109u8, 65u8, 113u8, 102u8, 119u8, 0u8, 109u8, 141u8, 211u8, 128u8, 237u8, 61u8, 28u8, 56u8, 206u8, 93u8, 183u8, 74u8, @@ -25541,7 +25555,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::children_curator_fees::Param0, + >, types::children_curator_fees::ChildrenCuratorFees, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -25550,7 +25566,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ChildBounties", "ChildrenCuratorFees", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 32u8, 16u8, 190u8, 193u8, 6u8, 80u8, 163u8, 16u8, 85u8, 111u8, 39u8, 141u8, 209u8, 70u8, 213u8, 167u8, 22u8, 12u8, 93u8, 17u8, 104u8, 94u8, @@ -26180,7 +26196,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::queues::Queues, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -26189,7 +26205,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Nis", "Queues", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 144u8, 181u8, 173u8, 134u8, 6u8, 165u8, 174u8, 91u8, 75u8, 241u8, 142u8, 192u8, 246u8, 71u8, 132u8, 146u8, 181u8, 158u8, 125u8, 34u8, @@ -26246,7 +26262,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::receipts::Receipts, ::subxt::storage::address::Yes, (), @@ -26255,7 +26271,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Nis", "Receipts", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 123u8, 179u8, 0u8, 14u8, 5u8, 132u8, 165u8, 192u8, 163u8, 22u8, 174u8, 22u8, 252u8, 44u8, 167u8, 22u8, 116u8, 170u8, 186u8, 118u8, 131u8, 5u8, @@ -27437,7 +27453,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::account::Account, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27446,7 +27462,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Account", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 213u8, 38u8, 200u8, 69u8, 218u8, 0u8, 112u8, 181u8, 160u8, 23u8, 96u8, 90u8, 3u8, 88u8, 126u8, 22u8, 103u8, 74u8, 64u8, 69u8, 29u8, 247u8, @@ -27482,7 +27498,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::locks::Locks, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27491,7 +27507,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Locks", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 10u8, 223u8, 55u8, 0u8, 249u8, 69u8, 168u8, 41u8, 75u8, 35u8, 120u8, 167u8, 18u8, 132u8, 9u8, 20u8, 91u8, 51u8, 27u8, 69u8, 136u8, 187u8, @@ -27525,7 +27541,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::reserves::Reserves, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27534,7 +27550,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Reserves", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 112u8, 10u8, 241u8, 77u8, 64u8, 187u8, 106u8, 159u8, 13u8, 153u8, 140u8, 178u8, 182u8, 50u8, 1u8, 55u8, 149u8, 92u8, 196u8, 229u8, 170u8, @@ -27569,7 +27585,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::holds::Holds, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27578,7 +27594,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Holds", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 181u8, 39u8, 29u8, 45u8, 45u8, 198u8, 129u8, 210u8, 189u8, 183u8, 121u8, 125u8, 57u8, 90u8, 95u8, 107u8, 51u8, 13u8, 22u8, 105u8, 191u8, @@ -27613,7 +27629,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::freezes::Freezes, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -27622,7 +27638,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "NisCounterpartBalances", "Freezes", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 69u8, 49u8, 165u8, 76u8, 135u8, 142u8, 179u8, 118u8, 50u8, 109u8, 53u8, 112u8, 110u8, 94u8, 30u8, 93u8, 173u8, 38u8, 27u8, 142u8, 19u8, 5u8, @@ -29969,7 +29985,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::availability_bitfields::Param0, + >, types::availability_bitfields::AvailabilityBitfields, ::subxt::storage::address::Yes, (), @@ -29978,7 +29996,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "AvailabilityBitfields", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 163u8, 169u8, 217u8, 160u8, 147u8, 165u8, 186u8, 21u8, 171u8, 177u8, 74u8, 69u8, 55u8, 205u8, 46u8, 13u8, 253u8, 83u8, 55u8, 190u8, 22u8, @@ -30012,7 +30030,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::pending_availability::Param0, + >, types::pending_availability::PendingAvailability, ::subxt::storage::address::Yes, (), @@ -30021,7 +30041,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "PendingAvailability", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 164u8, 175u8, 34u8, 182u8, 190u8, 147u8, 42u8, 185u8, 162u8, 130u8, 33u8, 159u8, 234u8, 242u8, 90u8, 119u8, 2u8, 195u8, 48u8, 150u8, 135u8, @@ -30055,7 +30075,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::pending_availability_commitments::Param0, >, types::pending_availability_commitments::PendingAvailabilityCommitments, @@ -30066,7 +30086,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaInclusion", "PendingAvailabilityCommitments", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 196u8, 210u8, 210u8, 16u8, 246u8, 105u8, 121u8, 178u8, 5u8, 48u8, 40u8, 183u8, 63u8, 147u8, 48u8, 74u8, 20u8, 83u8, 76u8, 84u8, 41u8, 30u8, @@ -31092,7 +31112,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::pvf_active_vote_map::PvfActiveVoteMap, ::subxt::storage::address::Yes, (), @@ -31101,7 +31121,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PvfActiveVoteMap", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 72u8, 55u8, 139u8, 104u8, 161u8, 63u8, 114u8, 153u8, 16u8, 221u8, 60u8, 88u8, 52u8, 207u8, 123u8, 193u8, 11u8, 30u8, 19u8, 39u8, 231u8, 39u8, @@ -31182,7 +31202,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::para_lifecycles::ParaLifecycles, ::subxt::storage::address::Yes, (), @@ -31191,7 +31211,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "ParaLifecycles", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 2u8, 203u8, 32u8, 194u8, 76u8, 227u8, 250u8, 9u8, 168u8, 201u8, 171u8, 180u8, 18u8, 169u8, 206u8, 183u8, 48u8, 189u8, 204u8, 192u8, 237u8, @@ -31226,7 +31246,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::heads::Heads, ::subxt::storage::address::Yes, (), @@ -31235,7 +31255,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "Heads", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 222u8, 116u8, 180u8, 190u8, 172u8, 192u8, 174u8, 132u8, 225u8, 180u8, 119u8, 90u8, 5u8, 39u8, 92u8, 230u8, 116u8, 202u8, 92u8, 99u8, 135u8, @@ -31269,7 +31289,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::most_recent_context::MostRecentContext, ::subxt::storage::address::Yes, (), @@ -31278,7 +31298,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "MostRecentContext", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 196u8, 150u8, 125u8, 121u8, 196u8, 182u8, 2u8, 5u8, 244u8, 170u8, 75u8, 57u8, 162u8, 8u8, 104u8, 94u8, 114u8, 32u8, 192u8, 236u8, 120u8, 91u8, @@ -31317,7 +31337,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::current_code_hash::CurrentCodeHash, ::subxt::storage::address::Yes, (), @@ -31326,7 +31346,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CurrentCodeHash", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 251u8, 100u8, 30u8, 46u8, 191u8, 60u8, 45u8, 221u8, 218u8, 20u8, 154u8, 233u8, 211u8, 198u8, 151u8, 195u8, 99u8, 210u8, 126u8, 165u8, 240u8, @@ -31367,7 +31387,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::past_code_hash::PastCodeHash, (), (), @@ -31376,7 +31396,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PastCodeHash", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 73u8, 209u8, 188u8, 36u8, 127u8, 42u8, 171u8, 136u8, 29u8, 126u8, 220u8, 209u8, 230u8, 22u8, 12u8, 63u8, 8u8, 102u8, 45u8, 158u8, 178u8, @@ -31394,8 +31414,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::past_code_hash::PastCodeHash, ::subxt::storage::address::Yes, @@ -31406,8 +31426,8 @@ pub mod api { "Paras", "PastCodeHash", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 73u8, 209u8, 188u8, 36u8, 127u8, 42u8, 171u8, 136u8, 29u8, 126u8, @@ -31446,7 +31466,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::past_code_meta::PastCodeMeta, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31455,7 +31475,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "PastCodeMeta", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 233u8, 47u8, 137u8, 174u8, 98u8, 64u8, 11u8, 75u8, 93u8, 222u8, 78u8, 58u8, 66u8, 245u8, 151u8, 39u8, 144u8, 36u8, 84u8, 176u8, 239u8, 183u8, @@ -31519,7 +31539,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::future_code_upgrades::Param0, + >, types::future_code_upgrades::FutureCodeUpgrades, ::subxt::storage::address::Yes, (), @@ -31528,7 +31550,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "FutureCodeUpgrades", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 163u8, 168u8, 23u8, 138u8, 198u8, 70u8, 135u8, 221u8, 167u8, 187u8, 15u8, 144u8, 228u8, 8u8, 138u8, 125u8, 101u8, 154u8, 11u8, 74u8, 173u8, @@ -31566,7 +31588,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::future_code_hash::FutureCodeHash, ::subxt::storage::address::Yes, (), @@ -31575,7 +31597,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "FutureCodeHash", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 62u8, 238u8, 183u8, 12u8, 197u8, 119u8, 163u8, 239u8, 192u8, 228u8, 110u8, 58u8, 128u8, 223u8, 32u8, 137u8, 109u8, 127u8, 41u8, 83u8, 91u8, @@ -31628,7 +31650,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::upgrade_go_ahead_signal::Param0, + >, types::upgrade_go_ahead_signal::UpgradeGoAheadSignal, ::subxt::storage::address::Yes, (), @@ -31637,7 +31661,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpgradeGoAheadSignal", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 41u8, 80u8, 120u8, 6u8, 98u8, 85u8, 36u8, 37u8, 170u8, 189u8, 56u8, 127u8, 155u8, 180u8, 112u8, 195u8, 135u8, 214u8, 235u8, 87u8, 197u8, @@ -31689,7 +31713,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::upgrade_restriction_signal::Param0, >, types::upgrade_restriction_signal::UpgradeRestrictionSignal, @@ -31700,7 +31724,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpgradeRestrictionSignal", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 158u8, 105u8, 62u8, 252u8, 149u8, 145u8, 34u8, 92u8, 119u8, 204u8, 46u8, 96u8, 117u8, 183u8, 134u8, 20u8, 172u8, 243u8, 145u8, 113u8, @@ -31783,7 +31807,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::actions_queue::ActionsQueue, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31792,7 +31816,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "ActionsQueue", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 13u8, 25u8, 129u8, 203u8, 95u8, 206u8, 254u8, 240u8, 170u8, 209u8, 55u8, 117u8, 70u8, 220u8, 139u8, 102u8, 9u8, 229u8, 139u8, 120u8, 67u8, @@ -31833,7 +31857,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::upcoming_paras_genesis::Param0, + >, types::upcoming_paras_genesis::UpcomingParasGenesis, ::subxt::storage::address::Yes, (), @@ -31842,7 +31868,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "UpcomingParasGenesis", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 215u8, 121u8, 106u8, 13u8, 102u8, 47u8, 129u8, 221u8, 153u8, 91u8, 23u8, 94u8, 11u8, 39u8, 19u8, 180u8, 136u8, 136u8, 254u8, 152u8, 250u8, @@ -31878,7 +31904,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::code_by_hash_refs::CodeByHashRefs, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -31887,7 +31913,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CodeByHashRefs", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 47u8, 50u8, 103u8, 161u8, 130u8, 252u8, 157u8, 35u8, 174u8, 37u8, 102u8, 60u8, 195u8, 30u8, 164u8, 203u8, 67u8, 129u8, 107u8, 181u8, @@ -31928,7 +31954,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::code_by_hash::CodeByHash, ::subxt::storage::address::Yes, (), @@ -31937,7 +31963,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Paras", "CodeByHash", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 155u8, 102u8, 73u8, 180u8, 127u8, 211u8, 181u8, 44u8, 56u8, 235u8, 49u8, 4u8, 25u8, 213u8, 116u8, 200u8, 232u8, 203u8, 190u8, 90u8, 93u8, @@ -32153,7 +32179,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::downward_message_queues::Param0, + >, types::downward_message_queues::DownwardMessageQueues, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -32162,7 +32190,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DownwardMessageQueues", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 38u8, 183u8, 133u8, 200u8, 199u8, 135u8, 68u8, 232u8, 189u8, 168u8, 3u8, 219u8, 201u8, 180u8, 156u8, 79u8, 134u8, 164u8, 94u8, 114u8, @@ -32209,7 +32237,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::downward_message_queue_heads::Param0, >, types::downward_message_queue_heads::DownwardMessageQueueHeads, @@ -32220,7 +32248,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DownwardMessageQueueHeads", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 135u8, 165u8, 240u8, 0u8, 25u8, 110u8, 9u8, 108u8, 251u8, 225u8, 109u8, 184u8, 90u8, 132u8, 9u8, 151u8, 12u8, 118u8, 153u8, 212u8, 140u8, @@ -32254,7 +32282,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::delivery_fee_factor::DeliveryFeeFactor, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -32263,7 +32291,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Dmp", "DeliveryFeeFactor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 43u8, 5u8, 63u8, 235u8, 115u8, 155u8, 130u8, 27u8, 75u8, 216u8, 177u8, 135u8, 203u8, 147u8, 167u8, 95u8, 208u8, 188u8, 25u8, 14u8, 84u8, 63u8, @@ -33040,7 +33068,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::hrmp_open_channel_requests::Param0, >, types::hrmp_open_channel_requests::HrmpOpenChannelRequests, @@ -33051,7 +33079,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpOpenChannelRequests", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 164u8, 97u8, 52u8, 242u8, 255u8, 67u8, 248u8, 170u8, 204u8, 92u8, 81u8, 144u8, 11u8, 63u8, 145u8, 167u8, 8u8, 174u8, 221u8, 147u8, 125u8, @@ -33112,7 +33140,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::hrmp_open_channel_request_count::Param0, >, types::hrmp_open_channel_request_count::HrmpOpenChannelRequestCount, @@ -33123,7 +33151,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpOpenChannelRequestCount", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 136u8, 72u8, 56u8, 31u8, 229u8, 99u8, 241u8, 14u8, 159u8, 243u8, 179u8, 222u8, 252u8, 56u8, 63u8, 24u8, 204u8, 130u8, 47u8, 161u8, 133u8, @@ -33163,7 +33191,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::hrmp_accepted_channel_request_count::Param0, >, types::hrmp_accepted_channel_request_count::HrmpAcceptedChannelRequestCount, @@ -33174,7 +33202,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpAcceptedChannelRequestCount", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 29u8, 100u8, 52u8, 28u8, 180u8, 84u8, 132u8, 120u8, 117u8, 172u8, 169u8, 40u8, 237u8, 92u8, 89u8, 87u8, 230u8, 148u8, 140u8, 226u8, 60u8, @@ -33222,7 +33250,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::hrmp_close_channel_requests::Param0, >, types::hrmp_close_channel_requests::HrmpCloseChannelRequests, @@ -33233,7 +33261,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpCloseChannelRequests", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 155u8, 13u8, 73u8, 166u8, 58u8, 67u8, 138u8, 58u8, 215u8, 172u8, 241u8, 168u8, 57u8, 4u8, 230u8, 248u8, 31u8, 183u8, 227u8, 224u8, 139u8, @@ -33294,7 +33322,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::hrmp_watermarks::HrmpWatermarks, ::subxt::storage::address::Yes, (), @@ -33303,7 +33331,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpWatermarks", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 245u8, 104u8, 137u8, 120u8, 131u8, 7u8, 178u8, 85u8, 96u8, 124u8, 241u8, 2u8, 86u8, 63u8, 116u8, 77u8, 217u8, 235u8, 162u8, 38u8, 104u8, @@ -33342,7 +33370,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::hrmp_channels::HrmpChannels, ::subxt::storage::address::Yes, (), @@ -33351,7 +33379,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannels", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 174u8, 90u8, 72u8, 93u8, 43u8, 140u8, 181u8, 170u8, 138u8, 171u8, 179u8, 156u8, 33u8, 87u8, 63u8, 1u8, 131u8, 59u8, 230u8, 14u8, 40u8, @@ -33411,7 +33439,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::hrmp_ingress_channels_index::Param0, >, types::hrmp_ingress_channels_index::HrmpIngressChannelsIndex, @@ -33422,7 +33450,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpIngressChannelsIndex", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 125u8, 229u8, 102u8, 230u8, 74u8, 109u8, 173u8, 67u8, 176u8, 169u8, 57u8, 24u8, 75u8, 129u8, 246u8, 198u8, 63u8, 49u8, 56u8, 102u8, 149u8, @@ -33455,7 +33483,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::hrmp_egress_channels_index::Param0, >, types::hrmp_egress_channels_index::HrmpEgressChannelsIndex, @@ -33466,7 +33494,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpEgressChannelsIndex", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 237u8, 183u8, 188u8, 57u8, 20u8, 238u8, 166u8, 7u8, 94u8, 155u8, 22u8, 9u8, 173u8, 209u8, 210u8, 17u8, 160u8, 79u8, 243u8, 4u8, 245u8, 240u8, @@ -33503,7 +33531,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::hrmp_channel_contents::Param0, + >, types::hrmp_channel_contents::HrmpChannelContents, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33512,7 +33542,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannelContents", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 55u8, 16u8, 135u8, 69u8, 54u8, 180u8, 246u8, 124u8, 104u8, 92u8, 45u8, 18u8, 223u8, 145u8, 43u8, 190u8, 121u8, 59u8, 35u8, 195u8, 234u8, @@ -33557,7 +33587,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::hrmp_channel_digests::Param0, + >, types::hrmp_channel_digests::HrmpChannelDigests, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -33566,7 +33598,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Hrmp", "HrmpChannelDigests", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 90u8, 90u8, 139u8, 78u8, 47u8, 2u8, 104u8, 211u8, 42u8, 246u8, 193u8, 210u8, 142u8, 223u8, 17u8, 136u8, 3u8, 182u8, 25u8, 56u8, 72u8, 72u8, @@ -33688,7 +33720,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::sessions::Sessions, ::subxt::storage::address::Yes, (), @@ -33697,7 +33729,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "Sessions", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 254u8, 40u8, 169u8, 18u8, 252u8, 203u8, 49u8, 182u8, 123u8, 19u8, 241u8, 150u8, 227u8, 153u8, 108u8, 109u8, 66u8, 129u8, 157u8, 27u8, @@ -33733,7 +33765,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::account_keys::AccountKeys, ::subxt::storage::address::Yes, (), @@ -33742,7 +33774,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "AccountKeys", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 30u8, 98u8, 58u8, 140u8, 96u8, 231u8, 205u8, 111u8, 194u8, 100u8, 185u8, 242u8, 210u8, 143u8, 110u8, 144u8, 170u8, 187u8, 62u8, 196u8, @@ -33777,7 +33809,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::session_executor_params::Param0, + >, types::session_executor_params::SessionExecutorParams, ::subxt::storage::address::Yes, (), @@ -33786,7 +33820,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParaSessionInfo", "SessionExecutorParams", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 38u8, 80u8, 118u8, 112u8, 189u8, 55u8, 95u8, 184u8, 19u8, 8u8, 114u8, 6u8, 173u8, 80u8, 254u8, 98u8, 107u8, 202u8, 215u8, 107u8, 149u8, @@ -34009,7 +34043,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::disputes::Disputes, (), (), @@ -34018,7 +34052,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Disputes", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 38u8, 237u8, 141u8, 222u8, 135u8, 82u8, 210u8, 166u8, 192u8, 122u8, 175u8, 96u8, 91u8, 1u8, 225u8, 182u8, 128u8, 4u8, 159u8, 56u8, 180u8, @@ -34034,8 +34068,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::disputes::Disputes, ::subxt::storage::address::Yes, @@ -34046,8 +34080,8 @@ pub mod api { "ParasDisputes", "Disputes", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 38u8, 237u8, 141u8, 222u8, 135u8, 82u8, 210u8, 166u8, 192u8, 122u8, @@ -34086,7 +34120,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::backers_on_disputes::BackersOnDisputes, (), (), @@ -34095,7 +34129,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "BackersOnDisputes", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 136u8, 171u8, 20u8, 204u8, 135u8, 153u8, 144u8, 241u8, 46u8, 193u8, 65u8, 22u8, 116u8, 161u8, 144u8, 186u8, 31u8, 194u8, 202u8, 225u8, @@ -34112,8 +34146,12 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::backers_on_disputes::Param0, + >, + ::subxt::storage::address::StaticStorageKey< + types::backers_on_disputes::Param1, + >, ), types::backers_on_disputes::BackersOnDisputes, ::subxt::storage::address::Yes, @@ -34124,8 +34162,8 @@ pub mod api { "ParasDisputes", "BackersOnDisputes", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 136u8, 171u8, 20u8, 204u8, 135u8, 153u8, 144u8, 241u8, 46u8, 193u8, @@ -34164,7 +34202,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::included::Included, (), (), @@ -34173,7 +34211,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasDisputes", "Included", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 47u8, 105u8, 189u8, 233u8, 206u8, 153u8, 162u8, 217u8, 141u8, 118u8, 31u8, 85u8, 87u8, 53u8, 100u8, 187u8, 31u8, 245u8, 50u8, 171u8, 4u8, @@ -34190,8 +34228,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::included::Included, ::subxt::storage::address::Yes, @@ -34202,8 +34240,8 @@ pub mod api { "ParasDisputes", "Included", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 47u8, 105u8, 189u8, 233u8, 206u8, 153u8, 162u8, 217u8, 141u8, 118u8, @@ -34353,7 +34391,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::unapplied_slashes::UnappliedSlashes, (), (), @@ -34362,7 +34400,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasSlashing", "UnappliedSlashes", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 114u8, 171u8, 137u8, 142u8, 180u8, 125u8, 226u8, 240u8, 99u8, 181u8, 68u8, 221u8, 91u8, 124u8, 172u8, 93u8, 103u8, 12u8, 95u8, 43u8, 67u8, @@ -34378,8 +34416,12 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::unapplied_slashes::Param0, + >, + ::subxt::storage::address::StaticStorageKey< + types::unapplied_slashes::Param1, + >, ), types::unapplied_slashes::UnappliedSlashes, ::subxt::storage::address::Yes, @@ -34390,8 +34432,8 @@ pub mod api { "ParasSlashing", "UnappliedSlashes", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 114u8, 171u8, 137u8, 142u8, 180u8, 125u8, 226u8, 240u8, 99u8, 181u8, @@ -34427,7 +34469,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::validator_set_counts::Param0, + >, types::validator_set_counts::ValidatorSetCounts, ::subxt::storage::address::Yes, (), @@ -34436,7 +34480,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "ParasSlashing", "ValidatorSetCounts", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 195u8, 220u8, 79u8, 140u8, 114u8, 80u8, 241u8, 103u8, 4u8, 7u8, 53u8, 100u8, 16u8, 78u8, 104u8, 171u8, 134u8, 110u8, 158u8, 191u8, 37u8, @@ -34728,7 +34772,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::book_state_for::BookStateFor, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -34737,7 +34781,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MessageQueue", "BookStateFor", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 32u8, 61u8, 161u8, 81u8, 134u8, 136u8, 252u8, 113u8, 204u8, 115u8, 206u8, 180u8, 33u8, 185u8, 137u8, 155u8, 178u8, 189u8, 234u8, 201u8, @@ -34795,7 +34839,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::pages::Pages, (), (), @@ -34804,7 +34848,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MessageQueue", "Pages", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 56u8, 181u8, 157u8, 16u8, 157u8, 123u8, 106u8, 93u8, 199u8, 208u8, 153u8, 53u8, 168u8, 188u8, 124u8, 77u8, 140u8, 163u8, 113u8, 16u8, @@ -34820,8 +34864,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::pages::Pages, ::subxt::storage::address::Yes, @@ -34832,8 +34876,8 @@ pub mod api { "MessageQueue", "Pages", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 56u8, 181u8, 157u8, 16u8, 157u8, 123u8, 106u8, 93u8, 199u8, 208u8, @@ -35160,7 +35204,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::para_id_affinity::ParaIdAffinity, ::subxt::storage::address::Yes, (), @@ -35169,7 +35213,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "OnDemandAssignmentProvider", "ParaIdAffinity", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 145u8, 117u8, 2u8, 170u8, 99u8, 68u8, 166u8, 236u8, 247u8, 80u8, 202u8, 87u8, 116u8, 244u8, 218u8, 172u8, 41u8, 187u8, 170u8, 163u8, 187u8, @@ -35265,7 +35309,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::core_schedules::CoreSchedules, (), (), @@ -35274,7 +35318,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreSchedules", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 34u8, 85u8, 91u8, 158u8, 28u8, 200u8, 76u8, 188u8, 253u8, 91u8, 153u8, 42u8, 42u8, 227u8, 119u8, 181u8, 247u8, 44u8, 29u8, 24u8, 128u8, 49u8, @@ -35292,8 +35336,8 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, ), types::core_schedules::CoreSchedules, ::subxt::storage::address::Yes, @@ -35304,8 +35348,8 @@ pub mod api { "CoretimeAssignmentProvider", "CoreSchedules", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 34u8, 85u8, 91u8, 158u8, 28u8, 200u8, 76u8, 188u8, 253u8, 91u8, 153u8, @@ -35346,7 +35390,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::core_descriptors::CoreDescriptors, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -35355,7 +35399,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreDescriptors", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 1u8, 90u8, 208u8, 119u8, 150u8, 241u8, 133u8, 74u8, 22u8, 166u8, 13u8, 7u8, 73u8, 136u8, 105u8, 61u8, 251u8, 245u8, 164u8, 7u8, 45u8, 68u8, @@ -35913,7 +35957,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::pending_swap::PendingSwap, ::subxt::storage::address::Yes, (), @@ -35922,7 +35966,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Registrar", "PendingSwap", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 75u8, 6u8, 68u8, 43u8, 108u8, 147u8, 220u8, 90u8, 190u8, 86u8, 209u8, 141u8, 9u8, 254u8, 103u8, 10u8, 94u8, 187u8, 155u8, 249u8, 140u8, @@ -35963,7 +36007,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::paras::Paras, ::subxt::storage::address::Yes, (), @@ -35972,7 +36016,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Registrar", "Paras", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 125u8, 62u8, 50u8, 209u8, 40u8, 170u8, 61u8, 62u8, 61u8, 246u8, 103u8, 229u8, 213u8, 94u8, 249u8, 49u8, 18u8, 90u8, 138u8, 14u8, 101u8, 133u8, @@ -36324,7 +36368,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::leases::Leases, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -36333,7 +36377,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Slots", "Leases", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 233u8, 226u8, 181u8, 160u8, 216u8, 86u8, 238u8, 229u8, 31u8, 67u8, 200u8, 188u8, 134u8, 22u8, 88u8, 147u8, 204u8, 11u8, 34u8, 244u8, @@ -36824,7 +36868,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::reserved_amounts::ReservedAmounts, (), (), @@ -36833,7 +36877,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "ReservedAmounts", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 77u8, 44u8, 116u8, 36u8, 189u8, 213u8, 126u8, 32u8, 42u8, 131u8, 108u8, 41u8, 147u8, 40u8, 247u8, 245u8, 161u8, 42u8, 152u8, 195u8, 28u8, @@ -36850,8 +36894,12 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::reserved_amounts::Param0, + >, + ::subxt::storage::address::StaticStorageKey< + types::reserved_amounts::Param1, + >, ), types::reserved_amounts::ReservedAmounts, ::subxt::storage::address::Yes, @@ -36862,8 +36910,8 @@ pub mod api { "Auctions", "ReservedAmounts", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 77u8, 44u8, 116u8, 36u8, 189u8, 213u8, 126u8, 32u8, 42u8, 131u8, 108u8, @@ -36903,7 +36951,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::winning::Winning, ::subxt::storage::address::Yes, (), @@ -36912,7 +36960,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Auctions", "Winning", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 8u8, 136u8, 174u8, 152u8, 223u8, 1u8, 143u8, 45u8, 213u8, 5u8, 239u8, 163u8, 152u8, 99u8, 197u8, 109u8, 194u8, 140u8, 246u8, 10u8, 40u8, @@ -37730,7 +37778,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::funds::Funds, ::subxt::storage::address::Yes, (), @@ -37739,7 +37787,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Crowdloan", "Funds", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 191u8, 255u8, 37u8, 49u8, 246u8, 246u8, 168u8, 178u8, 73u8, 238u8, 49u8, 76u8, 66u8, 246u8, 207u8, 12u8, 76u8, 233u8, 31u8, 218u8, 132u8, @@ -39391,7 +39439,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::queries::Queries, ::subxt::storage::address::Yes, (), @@ -39400,7 +39448,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "Queries", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 246u8, 75u8, 240u8, 129u8, 106u8, 114u8, 99u8, 154u8, 176u8, 188u8, 146u8, 125u8, 244u8, 103u8, 187u8, 171u8, 60u8, 119u8, 4u8, 90u8, 58u8, @@ -39441,7 +39489,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::asset_traps::AssetTraps, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -39450,7 +39498,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "AssetTraps", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 148u8, 41u8, 254u8, 134u8, 61u8, 172u8, 126u8, 146u8, 78u8, 178u8, 50u8, 77u8, 226u8, 8u8, 200u8, 78u8, 77u8, 91u8, 26u8, 133u8, 104u8, @@ -39508,7 +39556,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::supported_version::SupportedVersion, (), (), @@ -39517,7 +39565,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "SupportedVersion", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 144u8, 218u8, 177u8, 254u8, 210u8, 8u8, 84u8, 149u8, 163u8, 162u8, 238u8, 37u8, 157u8, 28u8, 140u8, 121u8, 201u8, 173u8, 204u8, 92u8, @@ -39533,8 +39581,12 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::supported_version::Param0, + >, + ::subxt::storage::address::StaticStorageKey< + types::supported_version::Param1, + >, ), types::supported_version::SupportedVersion, ::subxt::storage::address::Yes, @@ -39545,8 +39597,8 @@ pub mod api { "XcmPallet", "SupportedVersion", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 144u8, 218u8, 177u8, 254u8, 210u8, 8u8, 84u8, 149u8, 163u8, 162u8, @@ -39583,7 +39635,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::version_notifiers::VersionNotifiers, (), (), @@ -39592,7 +39644,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionNotifiers", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 175u8, 206u8, 29u8, 14u8, 111u8, 123u8, 211u8, 109u8, 159u8, 131u8, 80u8, 149u8, 216u8, 196u8, 181u8, 105u8, 117u8, 138u8, 80u8, 69u8, @@ -39608,8 +39660,12 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey, - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::version_notifiers::Param0, + >, + ::subxt::storage::address::StaticStorageKey< + types::version_notifiers::Param1, + >, ), types::version_notifiers::VersionNotifiers, ::subxt::storage::address::Yes, @@ -39620,8 +39676,8 @@ pub mod api { "XcmPallet", "VersionNotifiers", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 175u8, 206u8, 29u8, 14u8, 111u8, 123u8, 211u8, 109u8, 159u8, 131u8, @@ -39659,7 +39715,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::version_notify_targets::Param0, + >, types::version_notify_targets::VersionNotifyTargets, (), (), @@ -39668,7 +39726,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "VersionNotifyTargets", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 113u8, 77u8, 150u8, 42u8, 82u8, 49u8, 195u8, 120u8, 96u8, 80u8, 152u8, 67u8, 27u8, 142u8, 10u8, 74u8, 66u8, 134u8, 35u8, 202u8, 77u8, 187u8, @@ -39684,10 +39742,10 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::version_notify_targets::Param0, >, - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::version_notify_targets::Param1, >, ), @@ -39700,8 +39758,8 @@ pub mod api { "XcmPallet", "VersionNotifyTargets", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 113u8, 77u8, 150u8, 42u8, 82u8, 49u8, 195u8, 120u8, 96u8, 80u8, 152u8, @@ -39782,7 +39840,9 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey< + types::remote_locked_fungibles::Param0, + >, types::remote_locked_fungibles::RemoteLockedFungibles, (), (), @@ -39791,7 +39851,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "RemoteLockedFungibles", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 247u8, 124u8, 77u8, 42u8, 208u8, 183u8, 99u8, 196u8, 50u8, 113u8, 250u8, 221u8, 222u8, 170u8, 10u8, 60u8, 143u8, 172u8, 149u8, 198u8, @@ -39807,10 +39867,10 @@ pub mod api { _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::remote_locked_fungibles::Param0, >, - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::remote_locked_fungibles::Param1, >, ), @@ -39823,8 +39883,8 @@ pub mod api { "XcmPallet", "RemoteLockedFungibles", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), ), [ 247u8, 124u8, 77u8, 42u8, 208u8, 183u8, 99u8, 196u8, 50u8, 113u8, @@ -39842,13 +39902,13 @@ pub mod api { _2: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< ( - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::remote_locked_fungibles::Param0, >, - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::remote_locked_fungibles::Param1, >, - ::subxt::storage::address::StorageKey< + ::subxt::storage::address::StaticStorageKey< types::remote_locked_fungibles::Param2, >, ), @@ -39861,9 +39921,9 @@ pub mod api { "XcmPallet", "RemoteLockedFungibles", ( - ::subxt::storage::address::StorageKey::new(_0.borrow()), - ::subxt::storage::address::StorageKey::new(_1.borrow()), - ::subxt::storage::address::StorageKey::new(_2.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_2.borrow()), ), [ 247u8, 124u8, 77u8, 42u8, 208u8, 183u8, 99u8, 196u8, 50u8, 113u8, @@ -39899,7 +39959,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::locked_fungibles::LockedFungibles, ::subxt::storage::address::Yes, (), @@ -39908,7 +39968,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "XcmPallet", "LockedFungibles", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 254u8, 234u8, 1u8, 27u8, 27u8, 32u8, 217u8, 24u8, 47u8, 30u8, 62u8, 80u8, 86u8, 125u8, 120u8, 24u8, 143u8, 229u8, 161u8, 153u8, 240u8, @@ -40733,7 +40793,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::permanent_slots::PermanentSlots, ::subxt::storage::address::Yes, (), @@ -40742,7 +40802,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "PermanentSlots", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 133u8, 179u8, 221u8, 222u8, 50u8, 75u8, 158u8, 137u8, 167u8, 190u8, 19u8, 237u8, 201u8, 44u8, 86u8, 64u8, 57u8, 61u8, 96u8, 112u8, 218u8, @@ -40799,7 +40859,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StorageKey, + ::subxt::storage::address::StaticStorageKey, types::temporary_slots::TemporarySlots, ::subxt::storage::address::Yes, (), @@ -40808,7 +40868,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "AssignedSlots", "TemporarySlots", - ::subxt::storage::address::StorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 184u8, 245u8, 181u8, 90u8, 169u8, 232u8, 108u8, 3u8, 153u8, 4u8, 176u8, 170u8, 230u8, 163u8, 236u8, 111u8, 196u8, 218u8, 154u8, 125u8, 102u8, From 32026012b286af7c1ca51b9a162b6bf4ce77c529 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Mon, 19 Feb 2024 10:37:38 +0100 Subject: [PATCH 19/39] clippy and fmt --- subxt/src/storage/storage_key.rs | 4 ---- subxt/src/storage/utils.rs | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 1db4de8295..3eed4c1d57 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -2,17 +2,13 @@ use super::{ storage_address::StaticStorageKey, utils::{strip_concat_hash_bytes, strip_storage_addess_root_bytes}, }; - use crate::{ dynamic::DecodedValueThunk, error::{Error, StorageAddressError}, metadata::{DecodeWithMetadata, Metadata}, utils::{Encoded, Static}, }; - -use futures::StreamExt; use scale_encode::EncodeAsType; - use subxt_metadata::StorageHasher; /// This trait should be implemented by anything that can be used as one or multiple storage keys. diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index 9af9a32fa5..faa2e30efa 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -48,7 +48,7 @@ pub(crate) fn strip_storage_addess_root_bytes( address_bytes: &mut &[u8], ) -> Result<(), StorageAddressError> { if address_bytes.len() >= 16 { - *address_bytes = &mut &address_bytes[16..]; + *address_bytes = &address_bytes[16..]; Ok(()) } else { Err(StorageAddressError::UnexpectedAddressBytes) @@ -66,7 +66,7 @@ pub fn strip_concat_hash_bytes( match hasher { StorageHasher::Blake2_128Concat => { if hash.len() >= 16 { - *hash = &mut &hash[16..]; + *hash = &hash[16..]; Some(Ok(())) } else { Some(Err(StorageAddressError::UnexpectedAddressBytes)) @@ -74,7 +74,7 @@ pub fn strip_concat_hash_bytes( } StorageHasher::Twox64Concat => { if hash.len() >= 8 { - *hash = &mut &hash[8..]; + *hash = &hash[8..]; Some(Ok(())) } else { Some(Err(StorageAddressError::UnexpectedAddressBytes)) From 4c750f4044a1540745e95628ddc909a6aaf14b93 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Mon, 19 Feb 2024 16:23:36 +0100 Subject: [PATCH 20/39] regenerate polkadot file which got changed by the automatic PR --- .../src/full_client/codegen/polkadot.rs | 75 +++++++++---------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/testing/integration-tests/src/full_client/codegen/polkadot.rs b/testing/integration-tests/src/full_client/codegen/polkadot.rs index 9e28ce6cc6..07d42155b7 100644 --- a/testing/integration-tests/src/full_client/codegen/polkadot.rs +++ b/testing/integration-tests/src/full_client/codegen/polkadot.rs @@ -21441,7 +21441,7 @@ pub mod api { pub fn retries_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::retries::Retries, (), (), @@ -21450,7 +21450,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Retries", - vec![], + (), [ 164u8, 27u8, 208u8, 185u8, 19u8, 232u8, 190u8, 97u8, 137u8, 73u8, 146u8, 10u8, 241u8, 176u8, 251u8, 140u8, 133u8, 65u8, 190u8, 162u8, @@ -21464,7 +21464,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StaticStorageKey, types::retries::Retries, (), (), @@ -21473,9 +21473,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Retries", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 164u8, 27u8, 208u8, 185u8, 19u8, 232u8, 190u8, 97u8, 137u8, 73u8, 146u8, 10u8, 241u8, 176u8, 251u8, 140u8, 133u8, 65u8, 190u8, 162u8, @@ -21490,7 +21488,10 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ( + ::subxt::storage::address::StaticStorageKey, + ::subxt::storage::address::StaticStorageKey, + ), types::retries::Retries, ::subxt::storage::address::Yes, (), @@ -21499,10 +21500,10 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Scheduler", "Retries", - vec![ - ::subxt::storage::address::make_static_storage_map_key(_0.borrow()), - ::subxt::storage::address::make_static_storage_map_key(_1.borrow()), - ], + ( + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), + ), [ 164u8, 27u8, 208u8, 185u8, 19u8, 232u8, 190u8, 97u8, 137u8, 73u8, 146u8, 10u8, 241u8, 176u8, 251u8, 140u8, 133u8, 65u8, 190u8, 162u8, @@ -40139,7 +40140,7 @@ pub mod api { pub fn authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::authorities::Authorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40148,7 +40149,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "Authorities", - vec![], + (), [ 53u8, 171u8, 94u8, 33u8, 46u8, 83u8, 105u8, 120u8, 123u8, 201u8, 141u8, 71u8, 131u8, 150u8, 51u8, 121u8, 67u8, 45u8, 249u8, 146u8, 85u8, 113u8, @@ -40160,7 +40161,7 @@ pub mod api { pub fn validator_set_id( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::validator_set_id::ValidatorSetId, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40169,7 +40170,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "ValidatorSetId", - vec![], + (), [ 168u8, 84u8, 23u8, 134u8, 153u8, 30u8, 183u8, 176u8, 206u8, 100u8, 109u8, 86u8, 109u8, 126u8, 146u8, 175u8, 173u8, 1u8, 253u8, 42u8, @@ -40182,7 +40183,7 @@ pub mod api { pub fn next_authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::next_authorities::NextAuthorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40191,7 +40192,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "NextAuthorities", - vec![], + (), [ 87u8, 180u8, 0u8, 85u8, 209u8, 13u8, 131u8, 103u8, 8u8, 226u8, 42u8, 72u8, 38u8, 47u8, 190u8, 78u8, 62u8, 4u8, 161u8, 130u8, 87u8, 196u8, @@ -40212,7 +40213,7 @@ pub mod api { pub fn set_id_session_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::set_id_session::SetIdSession, (), (), @@ -40221,7 +40222,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "SetIdSession", - vec![], + (), [ 47u8, 0u8, 239u8, 121u8, 187u8, 213u8, 254u8, 50u8, 238u8, 10u8, 162u8, 65u8, 189u8, 166u8, 37u8, 74u8, 82u8, 81u8, 160u8, 20u8, 180u8, 253u8, @@ -40243,7 +40244,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StaticStorageKey, types::set_id_session::SetIdSession, ::subxt::storage::address::Yes, (), @@ -40252,9 +40253,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "SetIdSession", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 47u8, 0u8, 239u8, 121u8, 187u8, 213u8, 254u8, 50u8, 238u8, 10u8, 162u8, 65u8, 189u8, 166u8, 37u8, 74u8, 82u8, 81u8, 160u8, 20u8, 180u8, 253u8, @@ -40268,7 +40267,7 @@ pub mod api { pub fn genesis_block( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::genesis_block::GenesisBlock, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40277,7 +40276,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Beefy", "GenesisBlock", - vec![], + (), [ 198u8, 155u8, 11u8, 240u8, 189u8, 245u8, 159u8, 127u8, 55u8, 33u8, 48u8, 29u8, 209u8, 119u8, 163u8, 24u8, 28u8, 22u8, 163u8, 163u8, 124u8, @@ -40371,7 +40370,7 @@ pub mod api { pub fn root_hash( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::root_hash::RootHash, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40380,7 +40379,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "RootHash", - vec![], + (), [ 111u8, 206u8, 173u8, 92u8, 67u8, 49u8, 150u8, 113u8, 90u8, 245u8, 38u8, 254u8, 76u8, 250u8, 167u8, 66u8, 130u8, 129u8, 251u8, 220u8, 172u8, @@ -40392,7 +40391,7 @@ pub mod api { pub fn number_of_leaves( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::number_of_leaves::NumberOfLeaves, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40401,7 +40400,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "NumberOfLeaves", - vec![], + (), [ 123u8, 58u8, 149u8, 174u8, 85u8, 45u8, 20u8, 115u8, 241u8, 0u8, 51u8, 174u8, 234u8, 60u8, 230u8, 59u8, 237u8, 144u8, 170u8, 32u8, 4u8, 0u8, @@ -40416,7 +40415,7 @@ pub mod api { pub fn nodes_iter( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::nodes::Nodes, (), (), @@ -40425,7 +40424,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "Nodes", - vec![], + (), [ 27u8, 84u8, 41u8, 195u8, 146u8, 81u8, 211u8, 189u8, 63u8, 125u8, 173u8, 206u8, 69u8, 198u8, 202u8, 213u8, 89u8, 31u8, 89u8, 177u8, 76u8, 154u8, @@ -40441,7 +40440,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + ::subxt::storage::address::StaticStorageKey, types::nodes::Nodes, ::subxt::storage::address::Yes, (), @@ -40450,9 +40449,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "Mmr", "Nodes", - vec![::subxt::storage::address::make_static_storage_map_key( - _0.borrow(), - )], + ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), [ 27u8, 84u8, 41u8, 195u8, 146u8, 81u8, 211u8, 189u8, 63u8, 125u8, 173u8, 206u8, 69u8, 198u8, 202u8, 213u8, 89u8, 31u8, 89u8, 177u8, 76u8, 154u8, @@ -40491,7 +40488,7 @@ pub mod api { pub fn beefy_authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::beefy_authorities::BeefyAuthorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40500,7 +40497,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MmrLeaf", "BeefyAuthorities", - vec![], + (), [ 128u8, 35u8, 176u8, 79u8, 224u8, 58u8, 214u8, 234u8, 231u8, 71u8, 227u8, 153u8, 180u8, 189u8, 66u8, 44u8, 47u8, 174u8, 0u8, 83u8, 121u8, @@ -40515,7 +40512,7 @@ pub mod api { pub fn beefy_next_authorities( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::beefy_next_authorities::BeefyNextAuthorities, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -40524,7 +40521,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "MmrLeaf", "BeefyNextAuthorities", - vec![], + (), [ 97u8, 71u8, 52u8, 111u8, 120u8, 251u8, 183u8, 155u8, 177u8, 100u8, 236u8, 142u8, 204u8, 117u8, 95u8, 40u8, 201u8, 36u8, 32u8, 82u8, 38u8, From a404c8578e8c23a7ee2611c35cf5f3131f6b9f95 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Fri, 23 Feb 2024 17:31:50 +0100 Subject: [PATCH 21/39] nested design for storage keys --- subxt/expand.rs | 44181 +++++++++++++++++++++++++ subxt/expand.txt | 44181 +++++++++++++++++++++++++ subxt/src/error/mod.rs | 11 + subxt/src/storage/storage_address.rs | 2 +- subxt/src/storage/storage_key.rs | 248 +- subxt/src/storage/storage_type.rs | 14 +- subxt/src/storage/utils.rs | 60 +- 7 files changed, 88550 insertions(+), 147 deletions(-) create mode 100644 subxt/expand.rs create mode 100644 subxt/expand.txt diff --git a/subxt/expand.rs b/subxt/expand.rs new file mode 100644 index 0000000000..e3eef50a0a --- /dev/null +++ b/subxt/expand.rs @@ -0,0 +1,44181 @@ +#![feature(prelude_import)] +//! Subxt is a library for interacting with Substrate based nodes. Using it looks something like this: +//! +//! ```rust,ignore +/*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let from = dev::alice(); + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} +*/ +//! ``` +//! +//! Take a look at [the Subxt guide](book) to learn more about how to use Subxt. +#[prelude_import] +use std::prelude::rust_2021::*; +#[macro_use] +extern crate std; +pub mod book { + //! # The Subxt Guide + //! + //! Subxt is a library for interacting with Substrate based nodes. It has a focus on **sub**mitting + //! e**xt**rinsics, hence the name, however it's also capable of reading blocks, storage, events and + //! constants from a node. The aim of this guide is to explain key concepts and get you started with + //! using Subxt. + //! + //! 1. [Features](#features-at-a-glance) + //! 2. [Limitations](#limitations) + //! 3. [Quick start](#quick-start) + //! 4. [Usage](#usage) + //! + //! ## Features at a glance + //! + //! Here's a quick overview of the features that Subxt has to offer: + //! + //! - Subxt allows you to generate a static, type safe interface to a node given some metadata; this + //! allows you to catch many errors at compile time rather than runtime. + //! - Subxt also makes heavy use of node metadata to encode/decode the data sent to/from it. This + //! allows it to target almost any node which can output the correct metadata, and allows it some + //! flexibility in encoding and decoding things to account for cross-node differences. + //! - Subxt has a pallet-oriented interface, meaning that code you write to talk to some pallet on + //! one node will often "Just Work" when pointed at different nodes that use the same pallet. + //! - Subxt can work offline; you can generate and sign transactions, access constants from node + //! metadata and more, without a network connection. This is all checked at compile time, so you + //! can be certain it won't try to establish a network connection if you don't want it to. + //! - Subxt can forego the statically generated interface and build transactions, storage queries + //! and constant queries using data provided at runtime, rather than queries constructed + //! statically. + //! - Subxt can be compiled to WASM to run in the browser, allowing it to back Rust based browser + //! apps, or even bind to JS apps. + //! + //! ## Limitations + //! + //! In various places, you can provide a block hash to access data at a particular block, for + //! instance: + //! + //! - [`crate::storage::StorageClient::at`] + //! - [`crate::events::EventsClient::at`] + //! - [`crate::blocks::BlocksClient::at`] + //! - [`crate::runtime_api::RuntimeApiClient::at`] + //! + //! However, Subxt is (by default) only capable of properly working with blocks that were produced + //! after the most recent runtime update. This is because it uses the most recent metadata given + //! back by a node to encode and decode things. It's possible to decode older blocks produced by a + //! runtime that emits compatible (currently, V14) metadata by manually setting the metadata used by + //! the client using [`crate::client::OnlineClient::set_metadata()`]. + //! + //! Subxt does not support working with blocks produced prior to the runtime update that introduces + //! V14 metadata. It may have some success decoding older blocks using newer metadata, but may also + //! completely fail to do so. + //! + //! ## Quick start + //! + //! Here is a simple but complete example of using Subxt to transfer some tokens from the example + //! accounts, Alice to Bob: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let from = dev::alice(); + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} +*/ + //! ``` + //! + //! This example assumes that a Polkadot node is running locally (Subxt endeavors to support all + //! recent releases). Typically, to use Subxt to talk to some custom Substrate node (for example a + //! parachain node), you'll want to: + //! + //! 1. [Generate an interface](setup::codegen) + //! 2. [Create a config](setup::config) + //! 3. [Use the config to instantiate the client](setup::client) + //! + //! Follow the above links to learn more about each step. + //! + //! ## Usage + //! + //! Once Subxt is configured, the next step is interacting with a node. Follow the links + //! below to learn more about how to use Subxt for each of the following things: + //! + //! - [Transactions](usage::transactions): Subxt can build and submit transactions, wait until they are in + //! blocks, and retrieve the associated events. + //! - [Storage](usage::storage): Subxt can query the node storage. + //! - [Events](usage::events): Subxt can read the events emitted for recent blocks. + //! - [Constants](usage::constants): Subxt can access the constant values stored in a node, which + //! remain the same for a given runtime version. + //! - [Blocks](usage::blocks): Subxt can load recent blocks or subscribe to new/finalized blocks, + //! reading the extrinsics, events and storage at these blocks. + //! - [Runtime APIs](usage::runtime_apis): Subxt can make calls into pallet runtime APIs to retrieve + //! data. + //! - [Custom values](usage::custom_values): Subxt can access "custom values" stored in the metadata. + //! - [Raw RPC calls](usage::rpc): Subxt can be used to make raw RPC requests to compatible nodes. + //! + //! ## Examples + //! + //! Some complete, self contained examples which are not a part of this guide: + //! + //! - [`parachain-example`](https://github.com/paritytech/subxt/tree/master/examples/parachain-example) is an example + //! which uses Zombienet to spawn a parachain locally, and then connects to it using Subxt. + //! - [`wasm-example`](https://github.com/paritytech/subxt/tree/master/examples/wasm-example) is an example of writing + //! a Rust app that contains a Yew based UI, uses Subxt to interact with a chain, and compiles to WASM in order to + //! run entirely in the browser. + pub mod setup { + //! This modules contains details on setting up Subxt: + //! + //! - [Codegen](codegen) + //! - [Client](client) + //! + //! Alternately, [go back](super). + pub mod client { + //! # The Subxt client. + //! + //! The client forms the entry point to all of the Subxt APIs. Every client implements one or + //! both of [`crate::client::OfflineClientT`] and [`crate::client::OnlineClientT`]. + //! + //! Subxt ships with three clients which implement one or both of traits: + //! - An [online client](crate::client::OnlineClient). + //! - An [offline client](crate::client::OfflineClient). + //! - A light client (which is currently still unstable). + //! + //! In theory it's possible for users to implement their own clients, although this isn't generally + //! expected. + //! + //! The provided clients are all generic over the [`crate::config::Config`] that they accept, which + //! determines how they will interact with the chain. + //! + //! In the case of the [`crate::OnlineClient`], we have various ways to instantiate it: + //! + //! - [`crate::OnlineClient::new()`] to connect to a node running locally. This uses the default Subxt + //! backend, and the default RPC client. + //! - [`crate::OnlineClient::from_url()`] to connect to a node at a specific URL. This uses the default Subxt + //! backend, and the default RPC client. + //! - [`crate::OnlineClient::from_rpc_client()`] to instantiate the client with a [`crate::backend::rpc::RpcClient`]. + //! - [`crate::OnlineClient::from_backend()`] to instantiate Subxt using a custom backend. Currently there + //! is just one backend, [`crate::backend::legacy::LegacyBackend`]. This backend can be instantiated from + //! a [`crate::backend::rpc::RpcClient`]. + //! + //! [`crate::backend::rpc::RpcClient`] can itself be instantiated from anything that implements the low level + //! [`crate::backend::rpc::RpcClientT`] trait; this allows you to decide how Subxt will attempt to talk to a node + //! if you'd prefer something other default client. We use this approach under the hood to implement the light client. + //! + //! ## Examples + //! + //! Most of the other examples will instantiate a client. Here are a couple of examples for less common + //! cases. + //! + //! ### Writing a custom [`crate::backend::rpc::RpcClientT`] implementation: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use std::{ + fmt::Write, + pin::Pin, + sync::{Arc, Mutex}, +}; +use subxt::{ + backend::rpc::{RawRpcFuture, RawRpcSubscription, RawValue, RpcClient, RpcClientT}, + OnlineClient, PolkadotConfig, +}; + +// A dummy RPC client that doesn't actually handle requests properly +// at all, but instead just logs what requests to it were made. +struct MyLoggingClient { + log: Arc>, +} + +// We have to implement this fairly low level trait to turn [`MyLoggingClient`] +// into an RPC client that we can make use of in Subxt. Here we just log the requests +// made but don't forward them to any real node, and instead just return nonsense. +impl RpcClientT for MyLoggingClient { + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box> { + writeln!( + self.log.lock().unwrap(), + "{method}({})", + params.as_ref().map(|p| p.get()).unwrap_or("[]") + ) + .unwrap(); + + // We've logged the request; just return garbage. Because a boxed future is returned, + // you're able to run whatever async code you'd need to actually talk to a node. + let res = RawValue::from_string("[]".to_string()).unwrap(); + Box::pin(std::future::ready(Ok(res))) + } + + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription> { + writeln!( + self.log.lock().unwrap(), + "{sub}({}) (unsub: {unsub})", + params.as_ref().map(|p| p.get()).unwrap_or("[]") + ) + .unwrap(); + + // We've logged the request; just return garbage. Because a boxed future is returned, + // and that will return a boxed Stream impl, you have a bunch of flexibility to build + // and return whatever type of Stream you see fit. + let res = RawValue::from_string("[]".to_string()).unwrap(); + let stream = futures::stream::once(async move { Ok(res) }); + let stream: Pin + Send>> = Box::pin(stream); + // This subscription does not provide an ID. + Box::pin(std::future::ready(Ok(RawRpcSubscription { + stream, + id: None, + }))) + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Instantiate our replacement RPC client. + let log = Arc::default(); + let rpc_client = { + let inner = MyLoggingClient { + log: Arc::clone(&log), + }; + RpcClient::new(inner) + }; + + // Pass this into our OnlineClient to instantiate it. This will lead to some + // RPC calls being made to fetch chain details/metadata, which will immediately + // fail.. + let _ = OnlineClient::::from_rpc_client(rpc_client).await; + + // But, we can see that the calls were made via our custom RPC client: + println!("Log of calls made:\n\n{}", log.lock().unwrap().as_str()); + Ok(()) +} +*/ + //! ``` + //! + //! ### Creating an [`crate::OfflineClient`]: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::ext::codec::Decode; +use subxt::metadata::Metadata; +use subxt::utils::H256; +use subxt::{config::PolkadotConfig, OfflineClient}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // We need to obtain the following details for an OfflineClient to be instantiated: + + // 1. Genesis hash (RPC call: chain_getBlockHash(0)): + let genesis_hash = { + let h = "91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3"; + let bytes = hex::decode(h).unwrap(); + H256::from_slice(&bytes) + }; + + // 2. A runtime version (system_version constant on a Substrate node has these): + let runtime_version = subxt::backend::RuntimeVersion { + spec_version: 9370, + transaction_version: 20, + }; + + // 3. Metadata (I'll load it from the downloaded metadata, but you can use + // `subxt metadata > file.scale` to download it): + let metadata = { + let bytes = std::fs::read("./artifacts/polkadot_metadata_small.scale").unwrap(); + Metadata::decode(&mut &*bytes).unwrap() + }; + + // Create an offline client using the details obtained above: + let _api = OfflineClient::::new(genesis_hash, runtime_version, metadata); + + Ok(()) +} +*/ + //! ``` + //! + } + pub mod codegen { + //! # Generating an interface + //! + //! The simplest way to use Subxt is to generate an interface to a chain that you'd like to interact + //! with. This generated interface allows you to build transactions and construct queries to access + //! data while leveraging the full type safety of the Rust compiler. + //! + //! ## The `#[subxt]` macro + //! + //! The most common way to generate the interface is to use the [`#[subxt]`](crate::subxt) macro. + //! Using this macro looks something like: + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_tiny.scale")] + //! pub mod polkadot {} + //! ``` + //! + //! The macro takes a path to some node metadata, and uses that to generate the interface you'll use + //! to talk to it. [Go here](crate::subxt) to learn more about the options available to the macro. + //! + //! To obtain this metadata you'll need for the above, you can use the `subxt` CLI tool to download it + //! from a node. The tool can be installed via `cargo`: + //! + //! ```shell + //! cargo install subxt-cli + //! ``` + //! + //! And then it can be used to fetch metadata and save it to a file: + //! + //! ```shell + //! # Download and save all of the metadata: + //! subxt metadata > metadata.scale + //! # Download and save only the pallets you want to generate an interface for: + //! subxt metadata --pallets Balances,System > metadata.scale + //! ``` + //! + //! Explicitly specifying pallets will cause the tool to strip out all unnecessary metadata and type + //! information, making the bundle much smaller in the event that you only need to generate an + //! interface for a subset of the available pallets on the node. + //! + //! ## The CLI tool + //! + //! Using the [`#[subxt]`](crate::subxt) macro carries some downsides: + //! + //! - Using it to generate an interface will have a small impact on compile times (though much less of + //! one if you only need a few pallets). + //! - IDE support for autocompletion and documentation when using the macro interface can be poor. + //! - It's impossible to manually look at the generated code to understand and debug things. + //! + //! If these are an issue, you can manually generate the same code that the macro generates under the hood + //! by using the `subxt codegen` command: + //! + //! ```shell + //! # Install the CLI tool if you haven't already: + //! cargo install subxt-cli + //! # Generate and format rust code, saving it to `interface.rs`: + //! subxt codegen | rustfmt > interface.rs + //! ``` + //! + //! Use `subxt codegen --help` for more options; many of the options available via the macro are + //! also available via the CLI tool, such as the ability to substitute generated types for others, + //! or strip out docs from the generated code. + //! + } + pub mod config { + //! # Creating a Config + //! + //! Subxt requires you to provide a type implementing [`crate::config::Config`] in order to connect to a node. + //! The [`crate::config::Config`] trait for the most part mimics the `frame_system::Config` trait. + //! For most use cases, you can just use one of the following Configs shipped with Subxt: + //! + //! - [`PolkadotConfig`](crate::config::PolkadotConfig) for talking to Polkadot nodes, and + //! - [`SubstrateConfig`](crate::config::SubstrateConfig) for talking to generic nodes built with Substrate. + //! + //! # How to create a Config for a custom chain? + //! + //! Some chains may use config that is not compatible with our [`PolkadotConfig`](crate::config::PolkadotConfig) or + //! [`SubstrateConfig`](crate::config::SubstrateConfig). + //! + //! We now walk through creating a custom [`crate::config::Config`] for a parachain, using the + //! ["Statemint"](https://parachains.info/details/statemint) parachain, also known as "Asset Hub", as an example. It + //! is currently (as of 2023-06-26) deployed on Polkadot and [Kusama (as "Statemine")](https://parachains.info/details/statemine). + //! + //! To construct a valid [`crate::config::Config`] implementation, we need to find out which types to use for `AccountId`, `Hasher`, etc. + //! For this, we need to take a look at the source code of Statemint, which is currently a part of the [Cumulus Github repository](https://github.com/paritytech/cumulus). + //! The crate defining the asset hub runtime can be found [here](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/assets/asset-hub-polkadot). + //! + //! ## `AccountId`, `Hash`, `Hasher` and `Header` + //! + //! For these config types, we need to find out where the parachain runtime implements the `frame_system::Config` trait. + //! Look for a code fragment like `impl frame_system::Config for Runtime { ... }` In the source code. + //! For Statemint it looks like [this](https://github.com/paritytech/cumulus/blob/e2b7ad2061824f490c08df27a922c64f50accd6b/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs#L179) + //! at the time of writing. The `AccountId`, `Hash` and `Header` types of the [frame_system::pallet::Config](https://docs.rs/frame-system/latest/frame_system/pallet/trait.Config.html) + //! correspond to the ones we want to use in our Subxt [crate::Config]. In the Case of Statemint (Asset Hub) they are: + //! + //! - AccountId: `sp_core::crypto::AccountId32` + //! - Hash: `sp_core::H256` + //! - Hasher (type `Hashing` in [frame_system::pallet::Config](https://docs.rs/frame-system/latest/frame_system/pallet/trait.Config.html)): `sp_runtime::traits::BlakeTwo256` + //! - Header: `sp_runtime::generic::Header` + //! + //! Subxt has its own versions of some of these types in order to avoid needing to pull in Substrate dependencies: + //! + //! - `sp_core::crypto::AccountId32` can be swapped with [`crate::utils::AccountId32`]. + //! - `sp_core::H256` is a re-export which subxt also provides as [`crate::config::substrate::H256`]. + //! - `sp_runtime::traits::BlakeTwo256` can be swapped with [`crate::config::substrate::BlakeTwo256`]. + //! - `sp_runtime::generic::Header` can be swapped with [`crate::config::substrate::SubstrateHeader`]. + //! + //! Having a look at how those types are implemented can give some clues as to how to implement other custom types that + //! you may need to use as part of your config. + //! + //! ## `Address`, `Signature` + //! + //! A Substrate runtime is typically constructed by using the [frame_support::construct_runtime](https://docs.rs/frame-support/latest/frame_support/macro.construct_runtime.html) macro. + //! In this macro, we need to specify the type of an `UncheckedExtrinsic`. Most of the time, the `UncheckedExtrinsic` will be of the type + //! `sp_runtime::generic::UncheckedExtrinsic`. + //! The generic parameters `Address` and `Signature` specified when declaring the `UncheckedExtrinsic` type + //! are the types for `Address` and `Signature` we should use with our [crate::Config] implementation. This information can + //! also be obtained from the metadata (see [`frame_metadata::v15::ExtrinsicMetadata`]). In case of Statemint (Polkadot Asset Hub) + //! we see the following types being used in `UncheckedExtrinsic`: + //! + //! - Address: `sp_runtime::MultiAddress` + //! - Signature: `sp_runtime::MultiSignature` + //! + //! As above, Subxt has its own versions of these types that can be used instead to avoid pulling in Substrate dependencies. + //! Using the Subxt versions also makes interacting with generated code (which uses them in some places) a little nicer: + //! + //! - `sp_runtime::MultiAddress` can be swapped with [`crate::utils::MultiAddress`]. + //! - `sp_runtime::MultiSignature` can be swapped with [`crate::utils::MultiSignature`]. + //! + //! ## ExtrinsicParams + //! + //! Chains each have a set of "signed extensions" configured. Signed extensions provide a means to extend how transactions + //! work. Each signed extension can potentially encode some "extra" data which is sent along with a transaction, as well as some + //! "additional" data which is included in the transaction signer payload, but not transmitted along with the transaction. On + //! a node, signed extensions can then perform additional checks on the submitted transactions to ensure their validity. + //! + //! The `ExtrinsicParams` config type expects to be given an implementation of the [`crate::config::ExtrinsicParams`] trait. + //! Implementations of the [`crate::config::ExtrinsicParams`] trait are handed some parameters from Subxt itself, and can + //! accept arbitrary `OtherParams` from users, and are then expected to provide this "extra" and "additional" data when asked + //! via the required [`crate::config::ExtrinsicParamsEncoder`] impl. + //! + //! **In most cases, the default [crate::config::DefaultExtrinsicParams] type will work**: it understands the "standard" + //! signed extensions that are in use, and allows the user to provide things like a tip, and set the extrinsic mortality via + //! [`crate::config::DefaultExtrinsicParamsBuilder`]. It will use the chain metadata to decide which signed extensions to use + //! and in which order. It will return an error if the chain uses a signed extension which it doesn't know how to handle. + //! + //! If the chain uses novel signed extensions (or if you just wish to provide a different interface for users to configure + //! transactions), you can either: + //! + //! 1. Implement a new signed extension and add it to the list. + //! 2. Implement [`crate::config::DefaultExtrinsicParams`] from scratch. + //! + //! See below for examples of each. + //! + //! ### Finding out which signed extensions a chain is using. + //! + //! In either case, you'll want to find out which signed extensions a chain is using. This information can be obtained from + //! the `SignedExtra` parameter of the `UncheckedExtrinsic` of your parachain, which will be a tuple of signed extensions. + //! It can also be obtained from the metadata (see [`frame_metadata::v15::SignedExtensionMetadata`]). + //! + //! For statemint, the signed extensions look like + //! [this](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs#L779): + //! + //! ```rs + //! pub type SignedExtra = ( + //! frame_system::CheckNonZeroSender, + //! frame_system::CheckSpecVersion, + //! frame_system::CheckTxVersion, + //! frame_system::CheckGenesis, + //! frame_system::CheckEra, + //! frame_system::CheckNonce, + //! frame_system::CheckWeight, + //! pallet_asset_tx_payment::ChargeAssetTxPayment, + //! ); + //! ``` + //! + //! Each element of the `SignedExtra` tuple implements [codec::Encode] and `sp_runtime::traits::SignedExtension` + //! which has an associated type `AdditionalSigned` that also implements [codec::Encode]. Let's look at the underlying types + //! for each tuple element. All zero-sized types have been replaced by `()` for simplicity. + //! + //! | tuple element | struct type | `AdditionalSigned` type | + //! | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | + //! | [`frame_system::CheckNonZeroSender`](https://docs.rs/frame-system/latest/frame_system/struct.CheckNonZeroSender.html) | () | () | + //! | [`frame_system::CheckSpecVersion`](https://docs.rs/frame-system/latest/frame_system/struct.CheckSpecVersion.html) | () | [u32] | + //! | [`frame_system::CheckTxVersion`](https://docs.rs/frame-system/latest/frame_system/struct.CheckTxVersion.html) | () | [u32] | + //! | [`frame_system::CheckGenesis`](https://docs.rs/frame-system/latest/frame_system/struct.CheckGenesis.html) | () | `Config::Hash` = `sp_core::H256` | + //! | [`frame_system::CheckMortality`](https://docs.rs/frame-system/latest/frame_system/struct.CheckMortality.html) | `sp_runtime::generic::Era` | `Config::Hash` = `sp_core::H256` | + //! | [`frame_system::CheckNonce`](https://docs.rs/frame-system/latest/frame_system/struct.CheckNonce.html) | `frame_system::pallet::Config::Index` = u32 | () | + //! | [`frame_system::CheckWeight`](https://docs.rs/frame-system/latest/frame_system/struct.CheckWeight.html) | () | () | + //! | [`frame_system::ChargeAssetTxPayment`](https://docs.rs/frame-system/latest/frame_system/struct.ChargeAssetTxPayment.html) | [pallet_asset_tx_payment::ChargeAssetTxPayment](https://docs.rs/pallet-asset-tx-payment/latest/pallet_asset_tx_payment/struct.ChargeAssetTxPayment.html) | () | + //! + //! All types in the `struct type` column make up the "extra" data that we're expected to provide. All types in the + //! `AdditionalSigned` column make up the "additional" data that we're expected to provide. This information will be useful + //! whether we want to implement [`crate::config::SignedExtension`] for a signed extension, or implement + //! [`crate::config::ExtrinsicParams`] from scratch. + //! + //! As it happens, all of the signed extensions in the table are either already exported in [`crate::config::signed_extensions`], + //! or they hand back no "additional" or "extra" data. In both of these cases, the default `ExtrinsicParams` configuration will + //! work out of the box. + //! + //! ### Implementing and adding new signed extensions to the config + //! + //! If you do need to implement a novel signed extension, then you can implement [`crate::config::signed_extensions::SignedExtension`] + //! on a custom type and place it into a new set of signed extensions, like so: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use codec::Encode; +use scale_encode::EncodeAsType; +use scale_info::PortableRegistry; +use subxt::client::OfflineClientT; +use subxt::config::signed_extensions; +use subxt::config::{ + Config, DefaultExtrinsicParamsBuilder, ExtrinsicParams, ExtrinsicParamsEncoder, + ExtrinsicParamsError, +}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod runtime {} + +// We don't need to construct this at runtime, +// so an empty enum is appropriate: +#[derive(EncodeAsType)] +pub enum CustomConfig {} + +impl Config for CustomConfig { + type Hash = subxt::utils::H256; + type AccountId = subxt::utils::AccountId32; + type Address = subxt::utils::MultiAddress; + type Signature = subxt::utils::MultiSignature; + type Hasher = subxt::config::substrate::BlakeTwo256; + type Header = subxt::config::substrate::SubstrateHeader; + type ExtrinsicParams = signed_extensions::AnyOf< + Self, + ( + // Load in the existing signed extensions we're interested in + // (if the extension isn't actually needed it'll just be ignored): + signed_extensions::CheckSpecVersion, + signed_extensions::CheckTxVersion, + signed_extensions::CheckNonce, + signed_extensions::CheckGenesis, + signed_extensions::CheckMortality, + signed_extensions::ChargeAssetTxPayment, + signed_extensions::ChargeTransactionPayment, + // And add a new one of our own: + CustomSignedExtension, + ), + >; + type AssetId = u32; +} + +// Our custom signed extension doesn't do much: +pub struct CustomSignedExtension; + +// Give the extension a name; this allows `AnyOf` to look it +// up in the chain metadata in order to know when and if to use it. +impl signed_extensions::SignedExtension for CustomSignedExtension { + type Decoded = (); + fn matches(identifier: &str, _type_id: u32, _types: &PortableRegistry) -> bool { + identifier == "CustomSignedExtension" + } +} + +// Gather together any params we need for our signed extension, here none. +impl ExtrinsicParams for CustomSignedExtension { + type OtherParams = (); + + fn new>( + _nonce: u64, + _client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CustomSignedExtension) + } +} + +// Encode whatever the extension needs to provide when asked: +impl ExtrinsicParamsEncoder for CustomSignedExtension { + fn encode_extra_to(&self, v: &mut Vec) { + "Hello".encode_to(v); + } + fn encode_additional_to(&self, v: &mut Vec) { + true.encode_to(v) + } +} + +// When composing a tuple of signed extensions, the user parameters we need must +// be able to convert `Into` a tuple of corresponding `OtherParams`. Here, we just +// "hijack" the default param builder, but add the `OtherParams` (`()`) for our +// new signed extension at the end, to make the types line up. IN reality you may wish +// to construct an entirely new interface to provide the relevant `OtherParams`. +pub fn custom( + params: DefaultExtrinsicParamsBuilder, +) -> <::ExtrinsicParams as ExtrinsicParams>::OtherParams { + let (a, b, c, d, e, f, g) = params.build(); + (a, b, c, d, e, f, g, ()) +} + +#[tokio::main] +async fn main() { + // With the config defined, it can be handed to Subxt as follows: + let client = subxt::OnlineClient::::new().await.unwrap(); + + let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); + + // Configure the tx params: + let tx_config = DefaultExtrinsicParamsBuilder::new().tip(1234); + + // And provide them when submitting a transaction: + let _ = client + .tx() + .sign_and_submit_then_watch(&tx_payload, &dev::alice(), custom(tx_config)) + .await; +} +*/ + //! ``` + //! + //! ### Implementing [`crate::config::ExtrinsicParams`] from scratch + //! + //! Alternately, you are free to implement [`crate::config::ExtrinsicParams`] entirely from scratch if you know exactly what "extra" and` + //! "additional" data your node needs and would prefer to craft your own interface. + //! + //! Let's see what this looks like (this config won't work on any real node): + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use codec::Encode; +use subxt::client::OfflineClientT; +use subxt::config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] +pub mod runtime {} + +// We don't need to construct this at runtime, +// so an empty enum is appropriate: +pub enum CustomConfig {} + +impl Config for CustomConfig { + type Hash = subxt::utils::H256; + type AccountId = subxt::utils::AccountId32; + type Address = subxt::utils::MultiAddress; + type Signature = subxt::utils::MultiSignature; + type Hasher = subxt::config::substrate::BlakeTwo256; + type Header = subxt::config::substrate::SubstrateHeader; + type ExtrinsicParams = CustomExtrinsicParams; + type AssetId = u32; +} + +// This represents some arbitrary (and nonsensical) custom parameters that +// will be attached to transaction extra and additional payloads: +pub struct CustomExtrinsicParams { + genesis_hash: T::Hash, + tip: u128, + foo: bool, +} + +// We can provide a "pretty" interface to allow users to provide these: +#[derive(Default)] +pub struct CustomExtrinsicParamsBuilder { + tip: u128, + foo: bool, +} + +impl CustomExtrinsicParamsBuilder { + pub fn new() -> Self { + Default::default() + } + pub fn tip(mut self, value: u128) -> Self { + self.tip = value; + self + } + pub fn enable_foo(mut self) -> Self { + self.foo = true; + self + } +} + +// Describe how to fetch and then encode the params: +impl ExtrinsicParams for CustomExtrinsicParams { + type OtherParams = CustomExtrinsicParamsBuilder; + + // Gather together all of the params we will need to encode: + fn new>( + _nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + Ok(Self { + genesis_hash: client.genesis_hash(), + tip: other_params.tip, + foo: other_params.foo, + }) + } +} + +// Encode the relevant params when asked: +impl ExtrinsicParamsEncoder for CustomExtrinsicParams { + fn encode_extra_to(&self, v: &mut Vec) { + (self.tip, self.foo).encode_to(v); + } + fn encode_additional_to(&self, v: &mut Vec) { + self.genesis_hash.encode_to(v) + } +} + +#[tokio::main] +async fn main() { + // With the config defined, it can be handed to Subxt as follows: + let client = subxt::OnlineClient::::new().await.unwrap(); + + let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); + + // Build your custom "OtherParams": + let tx_config = CustomExtrinsicParamsBuilder::new().tip(1234).enable_foo(); + + // And provide them when submitting a transaction: + let _ = client + .tx() + .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) + .await; +} +*/ + //! ``` + //! + //! ### Using a type from the metadata as a config parameter + //! + //! You can also use types that are generated from chain metadata as type parameters of the Config trait. + //! Just make sure all trait bounds are satisfied. This can often be achieved by using custom derives with the subxt macro. + //! For example, the AssetHub Parachain expects tips to include a `MultiLocation`, which is a type we can draw from the metadata. + //! + //! This example shows what using the `MultiLocation` struct as part of your config would look like in subxt: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::config::{ + Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, PolkadotConfig, SubstrateConfig, +}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt( + runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", + derive_for_type( + path = "xcm::v2::multilocation::MultiLocation", + derive = "Clone", + recursive + ) +)] +pub mod runtime {} +use runtime::runtime_types::xcm::v2::multilocation::{Junctions, MultiLocation}; + +// We don't need to construct this at runtime, so an empty enum is appropriate. +pub enum AssetHubConfig {} + +impl Config for AssetHubConfig { + type Hash = ::Hash; + type AccountId = ::AccountId; + type Address = ::Address; + type Signature = ::Signature; + type Hasher = ::Hasher; + type Header = ::Header; + type ExtrinsicParams = DefaultExtrinsicParams; + // Here we use the MultiLocation from the metadata as a part of the config: + // The `ChargeAssetTxPayment` signed extension that is part of the ExtrinsicParams above, now uses the type: + type AssetId = MultiLocation; +} + +#[tokio::main] +async fn main() { + // With the config defined, we can create an extrinsic with subxt: + let client = subxt::OnlineClient::::new().await.unwrap(); + let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); + + // Build extrinsic params using an asset at this location as a tip: + let location: MultiLocation = MultiLocation { + parents: 3, + interior: Junctions::Here, + }; + let tx_config = DefaultExtrinsicParamsBuilder::::new() + .tip_of(1234, location) + .build(); + + // And provide the extrinsic params including the tip when submitting a transaction: + let _ = client + .tx() + .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) + .await; +} +*/ + //! ``` + } + } + pub mod usage { + //! This modules contains examples of using Subxt; follow the links for more: + //! + //! - [Transactions](transactions) + //! - [Storage](storage) + //! - [Events](events) + //! - [Constants](constants) + //! - [Blocks](blocks) + //! - [Runtime APIs](runtime_apis) + //! - [Unstable Light Client](light_client) + //! - [Custom Values](custom_values) + //! - [RPC calls](rpc) + //! + //! Alternately, [go back](super). + pub mod blocks { + //! # Blocks + //! + //! The [blocks API](crate::blocks::BlocksClient) in Subxt unifies many of the other interfaces, and + //! allows you to: + //! + //! - Access information about specific blocks (see [`crate::blocks::BlocksClient::at()`] and + //! [`crate::blocks::BlocksClient::at_latest()`]). + //! - Subscribe to [all](crate::blocks::BlocksClient::subscribe_all()), + //! [best](crate::blocks::BlocksClient::subscribe_best()) or + //! [finalized](crate::blocks::BlocksClient::subscribe_finalized()) blocks as they are produced. + //! Prefer to subscribe to finalized blocks unless you know what you're doing. + //! + //! In either case, you'll end up with [`crate::blocks::Block`]'s, from which you can access various + //! information about the block, such a the [header](crate::blocks::Block::header()), [block + //! number](crate::blocks::Block::number()) and [body (the extrinsics)](crate::blocks::Block::extrinsics()). + //! [`crate::blocks::Block`]'s also provide shortcuts to other Subxt APIs that will operate at the + //! given block: + //! + //! - [storage](crate::blocks::Block::storage()), + //! - [events](crate::blocks::Block::events()) + //! - [runtime APIs](crate::blocks::Block::runtime_api()) + //! + //! Aside from these links to other Subxt APIs, the main thing that we can do here is iterate over and + //! decode the extrinsics in a block body. + //! + //! ## Decoding Extrinsics + //! + //! Given a block, you can [download the block body](crate::blocks::Block::extrinsics()) and [iterate over + //! the extrinsics](crate::blocks::Extrinsics::iter()) stored within it. The extrinsics yielded are of type + //! [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), which is just a blob of bytes that also stores which + //! pallet and call in that pallet it belongs to. It also contains information about signed extensions that + //! have been used for submitting this extrinsic. + //! + //! To use the extrinsic, you probably want to decode it into a concrete Rust type. These Rust types representing + //! extrinsics from different pallets can be generated from metadata using the subxt macro or the CLI tool. + //! + //! When decoding the extrinsic into a static type you have two options: + //! + //! ### Statically decode the extrinsics into [the root extrinsic type](crate::blocks::ExtrinsicDetails::as_root_extrinsic()) + //! + //! The root extrinsic type generated by subxt is a Rust enum with one variant for each pallet. Each of these + //! variants has a field that is another enum whose variants cover all calls of the respective pallet. + //! If the extrinsic bytes are valid and your metadata matches the chain's metadata, decoding the bytes of an extrinsic into + //! this root extrinsic type should always succeed. + //! + //! This example shows how to subscribe to blocks and decode the extrinsics in each block into the root extrinsic type. + //! Once we get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), we can decode it statically or dynamically. + //! We can also access details about the extrinsic, including the associated events and signed extensions. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Subscribe to all finalized blocks: + let mut blocks_sub = api.blocks().subscribe_finalized().await?; + + // For each block, print a bunch of information about it: + while let Some(block) = blocks_sub.next().await { + let block = block?; + + let block_number = block.header().number; + let block_hash = block.hash(); + + println!("Block #{block_number}:"); + println!(" Hash: {block_hash}"); + println!(" Extrinsics:"); + + // Log each of the extrinsic with it's associated events: + let extrinsics = block.extrinsics().await?; + for ext in extrinsics.iter() { + let ext = ext?; + let idx = ext.index(); + let events = ext.events().await?; + let bytes_hex = format!("0x{}", hex::encode(ext.bytes())); + + // See the API docs for more ways to decode extrinsics: + let decoded_ext = ext.as_root_extrinsic::(); + + println!(" Extrinsic #{idx}:"); + println!(" Bytes: {bytes_hex}"); + println!(" Decoded: {decoded_ext:?}"); + + println!(" Events:"); + for evt in events.iter() { + let evt = evt?; + let pallet_name = evt.pallet_name(); + let event_name = evt.variant_name(); + let event_values = evt.field_values()?; + + println!(" {pallet_name}_{event_name}"); + println!(" {}", event_values); + } + + println!(" Signed Extensions:"); + if let Some(signed_extensions) = ext.signed_extensions() { + for signed_extension in signed_extensions.iter() { + let signed_extension = signed_extension?; + let name = signed_extension.name(); + let value = signed_extension.value()?.to_string(); + println!(" {name}: {value}"); + } + } + } + } + + Ok(()) +} +*/ + //! ``` + //! + //! ### Statically decode the extrinsic into [a specific pallet call](crate::blocks::ExtrinsicDetails::as_extrinsic()) + //! + //! This is useful if you are expecting a specific extrinsic to be part of some block. If the extrinsic you try to decode + //! is a different extrinsic, an `Ok(None)` value is returned from [`as_extrinsic::()`](crate::blocks::ExtrinsicDetails::as_extrinsic()); + //! + //! If you are only interested in finding specific extrinsics in a block, you can also [iterate over all of them](crate::blocks::Extrinsics::find), + //! get only [the first one](crate::blocks::Extrinsics::find_first), or [the last one](crate::blocks::Extrinsics::find_last). + //! + //! The following example monitors `TransferKeepAlive` extrinsics on the Polkadot network. + //! We statically decode them and access the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and [account nonce](crate::blocks::ExtrinsicSignedExtensions::nonce()) signed extensions. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{ + utils::{AccountId32, MultiAddress}, + OnlineClient, PolkadotConfig, +}; + +use codec::Decode; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +use polkadot::balances::calls::types::TransferKeepAlive; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client that subscribes to blocks of the Polkadot network. + let api = OnlineClient::::from_url("wss://rpc.polkadot.io:443").await?; + + // Subscribe to all finalized blocks: + let mut blocks_sub = api.blocks().subscribe_finalized().await?; + + // For each block, print details about the `TransferKeepAlive` transactions we are interested in. + while let Some(block) = blocks_sub.next().await { + let block = block?; + let block_number = block.header().number; + let block_hash = block.hash(); + println!("Block #{block_number} ({block_hash}):"); + + let extrinsics = block.extrinsics().await?; + for transfer in extrinsics.find::() { + let transfer = transfer?; + + let Some(extensions) = transfer.details.signed_extensions() else { + panic!("TransferKeepAlive should be signed") + }; + + let addr_bytes = transfer + .details + .address_bytes() + .expect("TransferKeepAlive should be signed"); + let sender = MultiAddress::::decode(&mut &addr_bytes[..]) + .expect("Decoding should work"); + let sender = display_address(&sender); + let receiver = display_address(&transfer.value.dest); + let value = transfer.value.value; + let tip = extensions.tip().expect("Should have tip"); + let nonce = extensions.nonce().expect("Should have nonce"); + + println!( + " Transfer of {value} DOT:\n {sender} (Tip: {tip}, Nonce: {nonce}) ---> {receiver}", + ); + } + } + + Ok(()) +} + +fn display_address(addr: &MultiAddress) -> String { + if let MultiAddress::Id(id32) = addr { + format!("{id32}") + } else { + "MultiAddress::...".into() + } +} +*/ + //! ``` + //! + //! ### Dynamically decode the extrinsic + //! + //! Sometimes you might use subxt with metadata that is not known at compile time. In this case, you do not have access to a statically generated + //! interface module that contains the relevant Rust types. You can [decode ExtrinsicDetails dynamically](crate::blocks::ExtrinsicDetails::field_values()), + //! which gives you access to it's fields as a [scale value composite](scale_value::Composite). + //! The following example looks for signed extrinsics on the Polkadot network and retrieves their pallet name, variant name, data fields and signed extensions dynamically. + //! Notice how we do not need to use code generation via the subxt macro. The only fixed component we provide is the [PolkadotConfig](crate::config::PolkadotConfig). + //! Other than that it works in a chain-agnostic way: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client that subscribes to blocks of the Polkadot network. + let api = OnlineClient::::from_url("wss://rpc.polkadot.io:443").await?; + + // Subscribe to all finalized blocks: + let mut blocks_sub = api.blocks().subscribe_finalized().await?; + while let Some(block) = blocks_sub.next().await { + let block = block?; + let block_number = block.header().number; + let block_hash = block.hash(); + println!("Block #{block_number} ({block_hash})"); + + // Decode each signed extrinsic in the block dynamically + let extrinsics = block.extrinsics().await?; + for ext in extrinsics.iter() { + let ext = ext?; + + let Some(signed_extensions) = ext.signed_extensions() else { + continue; // we do not look at inherents in this example + }; + + let meta = ext.extrinsic_metadata()?; + let fields = ext.field_values()?; + + println!(" {}/{}", meta.pallet.name(), meta.variant.name); + println!(" Signed Extensions:"); + for signed_ext in signed_extensions.iter() { + let signed_ext = signed_ext?; + // We only want to take a look at these 3 signed extensions, because the others all just have unit fields. + if ["CheckMortality", "CheckNonce", "ChargeTransactionPayment"] + .contains(&signed_ext.name()) + { + println!(" {}: {}", signed_ext.name(), signed_ext.value()?); + } + } + println!(" Fields:"); + println!(" {}\n", fields); + } + } + + Ok(()) +} +*/ + //! ``` + //! + //! ## Decoding signed extensions + //! + //! Extrinsics can contain signed extensions. The signed extensions can be different across chains. + //! The [Config](crate::Config) implementation for your chain defines which signed extensions you expect. + //! Once you get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails) for an extrinsic you are interested in, + //! you can try to [get its signed extensions](crate::blocks::ExtrinsicDetails::signed_extensions()). + //! These are only available on signed extrinsics. You can try to [find a specific signed extension](crate::blocks::ExtrinsicSignedExtensions::find), + //! in the returned [signed extensions](crate::blocks::ExtrinsicSignedExtensions). + //! + //! Subxt also provides utility functions to get the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and the + //! [account nonce](crate::blocks::ExtrinsicSignedExtensions::tip()) associated with an extrinsic, given its signed extensions. + //! If you prefer to do things dynamically you can get the data of the signed extension as a [scale value](crate::blocks::ExtrinsicSignedExtension::value()). + //! + } + pub mod constants { + //! # Constants + //! + //! There are various constants stored in a node; the types and values of these are defined in a + //! runtime, and can only change when the runtime is updated. Much like [`super::storage`], we can + //! query these using Subxt by taking the following steps: + //! + //! 1. [Constructing a constant query](#constructing-a-query). + //! 2. [Submitting the query to get back the associated value](#submitting-it). + //! + //! ## Constructing a constant query + //! + //! We can use the statically generated interface to build constant queries: + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] + //! pub mod polkadot {} + //! + //! let constant_query = polkadot::constants().system().block_length(); + //! ``` + //! + //! Alternately, we can dynamically construct a constant query: + //! + //! ```rust,no_run + //! use subxt::dynamic::Value; + //! + //! let storage_query = subxt::dynamic::constant("System", "BlockLength"); + //! ``` + //! + //! Static queries also have a static return type, so the constant is decoded appropriately. In + //! addition, they are validated at runtime to ensure that they align with the current node state. + //! Dynamic queries must be decoded into some static type manually, or into the dynamic + //! [`crate::dynamic::Value`] type. + //! + //! ## Submitting it + //! + //! Constant queries are handed to Subxt via [`crate::constants::ConstantsClient::at()`]. It's worth + //! noting that constant values are pulled directly out of the node metadata which Subxt has + //! already acquired, and so this function requires no network access and is available from a + //! [`crate::OfflineClient`]. + //! + //! Here's an example using a static query: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // A query to obtain some contant: + let constant_query = polkadot::constants().system().block_length(); + + // Obtain the value: + let value = api.constants().at(&constant_query)?; + + println!("Block length: {value:?}"); + Ok(()) +} +*/ + //! ``` + //! + //! And here's one using a dynamic query: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // A dynamic query to obtain some contant: + let constant_query = subxt::dynamic::constant("System", "BlockLength"); + + // Obtain the value: + let value = api.constants().at(&constant_query)?; + + println!("Constant bytes: {:?}", value.encoded()); + println!("Constant value: {}", value.to_value()?); + Ok(()) +} +*/ + //! ``` + //! + } + pub mod custom_values { + //! # Custom Values + //! + //! Substrate-based chains can expose custom values in their metadata. + //! Each of these values: + //! + //! - can be accessed by a unique __name__. + //! - refers to a concrete __type__ stored in the metadata. + //! - contains a scale encoded __value__ of that type. + //! + //! ## Getting a custom value + //! + //! Custom values can be accessed via a [`CustomValuesClient`](crate::custom_values::CustomValuesClient). + //! The client exposes an `at` function by which a custom value can be fetched, given an address to this custom value. + //! An address can be as simple as the aforementioned __name__ as a [str]. This will return a dynamic value, that you can manually decode into the type you want. + //! Suppose, the custom types contain a value of type `Foo` under the name `"foo"` you can access it like in this example: + //! + //! ```rust,ignore + //! use subxt::{OnlineClient, PolkadotConfig, ext::{codec::Decode, scale_decode::DecodeAsType}}; + //! + //! #[derive(Decode, DecodeAsType, Debug)] + //! struct Foo { + //! n: u8, + //! b: bool, + //! } + //! + //! let api = OnlineClient::::new().await?; + //! let custom_value_client = api.custom_values(); + //! let foo_dynamic = custom_value_client.at("foo")?; + //! let foo: Foo = foo_dynamic.as_type()?; + //! + //! ``` + //! + //! Alternatively we also provide a statically generated api for custom values: + //! + //! ```rust,ignore + //! #[subxt::subxt(runtime_metadata_path = "some_metadata.scale")] + //! pub mod interface {} + //! + //! let static_address = interface::custom().foo(); + //! + //! let api = OnlineClient::::new().await?; + //! let custom_value_client = api.custom_values(); + //! + //! // Now the `at()` function already decodes the value into the Foo type: + //! let foo = custom_value_client.at(&static_address)?; + //! ``` + //! + //! Note: Names of custom values are converted to __snake_case__ to produce a valid function name during code generation. + //! If there are multiple values where the names would be equal when converted to __snake_case__, functions might not be statically generated for some of them, because of naming conflicts. + //! Make sure names in the custom values of your metadata differ significantly. + } + pub mod events { + //! # Events + //! + //! In the process of adding extrinsics to a block, they are executed. When extrinsics are executed, + //! they normally produce events describing what's happening (at the very least, an event dictating whether + //! the extrinsic has succeeded or failed). The node may also emit some events of its own as the block is + //! processed. + //! + //! Events live in a single location in node storage which is overwritten at each block. Normal nodes tend to + //! keep a snapshot of the state at a small number of previous blocks, so you can sometimes access + //! older events by using [`crate::events::EventsClient::at()`] and providing an older block hash. + //! + //! When we submit transactions using Subxt, methods like [`crate::tx::TxProgress::wait_for_finalized_success()`] + //! return [`crate::blocks::ExtrinsicEvents`], which can be used to iterate and inspect the events produced + //! by that transaction being executed. We can also access _all_ of the events produced in a single block using one + //! of these two interfaces: + //! + //! ```rust,no_run + //! # #[tokio::main] + //! # async fn main() -> Result<(), Box> { + //! use subxt::client::OnlineClient; + //! use subxt::config::PolkadotConfig; + //! + //! // Create client: + //! let client = OnlineClient::::new().await?; + //! + //! // Get events from the latest block (use .at() to specify a block hash): + //! let events = client.blocks().at_latest().await?.events().await?; + //! // We can use this shorthand too: + //! let events = client.events().at_latest().await?; + //! # Ok(()) + //! # } + //! ``` + //! + //! Once we've loaded our events, we can iterate all events or search for specific events via + //! methods like [`crate::events::Events::iter()`] and [`crate::events::Events::find()`]. See + //! [`crate::events::Events`] and [`crate::events::EventDetails`] for more information. + //! + //! ## Example + //! + //! Here's an example which puts this all together: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Get events for the latest block: + let events = api.events().at_latest().await?; + + // We can dynamically decode events: + println!("Dynamic event details:"); + for event in events.iter() { + let event = event?; + + let pallet = event.pallet_name(); + let variant = event.variant_name(); + let field_values = event.field_values()?; + + println!("{pallet}::{variant}: {field_values}"); + } + + // Or we can attempt to statically decode them into the root Event type: + println!("Static event details:"); + for event in events.iter() { + let event = event?; + + if let Ok(ev) = event.as_root_event::() { + println!("{ev:?}"); + } else { + println!(""); + } + } + + // Or we can look for specific events which match our statically defined ones: + let transfer_event = events.find_first::()?; + if let Some(ev) = transfer_event { + println!(" - Balance transfer success: value: {:?}", ev.amount); + } else { + println!(" - No balance transfer event found in this block"); + } + + Ok(()) +} +*/ + //! ``` + //! + } + pub mod light_client { + //! # Light Client + //! + //! The light client based interface uses _Smoldot_ to connect to a _chain_, rather than an individual + //! node. This means that you don't have to trust a specific node when interacting with some chain. + //! + //! This feature is currently unstable. Use the `unstable-light-client` feature flag to enable it. + //! To use this in WASM environments, also enable the `web` feature flag. + //! + //! To connect to a blockchain network, the Light Client requires a trusted sync state of the network, + //! known as a _chain spec_. One way to obtain this is by making a `sync_state_genSyncSpec` RPC call to a + //! trusted node belonging to the chain that you wish to interact with. + //! + //! The following is an example of fetching the chain spec from a local running node on port 9933: + //! + //! ```bash + //! curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "sync_state_genSyncSpec", "params":[true]}' http://localhost:9933/ | jq .result > chain_spec.json + //! ``` + //! + //! Alternately, you can have the `LightClient` download the chain spec from a trusted node when it + //! initializes, which is not recommended in production but is useful for examples and testing, as below. + //! + //! ## Examples + //! + //! ### Basic Example + //! + //! This example connects to a local chain and submits a transaction. To run this, you first need + //! to have a local polkadot node running using the following command: + //! + //! ```text + //! polkadot --dev --node-key 0000000000000000000000000000000000000000000000000000000000000001 + //! ``` + //! + //! Leave that running for a minute, and then you can run the example using the following command + //! in the `subxt` crate: + //! + //! ```bash + //! cargo run --example light_client_tx_basic --features=unstable-light-client + //! ``` + //! + //! This is the code that will be executed: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{client::LightClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // The smoldot logs are informative: + tracing_subscriber::fmt::init(); + + // Create a light client by fetching the chain spec of a local running node. + // In this case, because we start one single node, the bootnodes must be overwritten + // for the light client to connect to the local node. + // + // The `12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp` is the P2P address + // from a local polkadot node starting with + // `--node-key 0000000000000000000000000000000000000000000000000000000000000001` + let api = LightClient::::builder() + .bootnodes([ + "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp", + ]) + .build_from_url("ws://127.0.0.1:9944") + .await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let from = dev::alice(); + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} +*/ + //! ``` + //! + //! ### Connecting to a parachain + //! + //! This example connects to a parachain using the light client. Currently, it's quite verbose to do this. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use futures::StreamExt; +use std::{iter, num::NonZeroU32}; +use subxt::{ + client::{LightClient, RawLightClient}, + PolkadotConfig, +}; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +const POLKADOT_SPEC: &str = include_str!("../../artifacts/demo_chain_specs/polkadot.json"); +const ASSET_HUB_SPEC: &str = + include_str!("../../artifacts/demo_chain_specs/polkadot_asset_hub.json"); + +#[tokio::main] +async fn main() -> Result<(), Box> { + // The smoldot logs are informative: + tracing_subscriber::fmt::init(); + + // Connecting to a parachain is a multi step process. + + // Step 1. Construct a new smoldot client. + let mut client = + subxt_lightclient::smoldot::Client::new(subxt_lightclient::smoldot::DefaultPlatform::new( + "subxt-example-light-client".into(), + "version-0".into(), + )); + + // Step 2. Connect to the relay chain of the parachain. For this example, the Polkadot relay chain. + let polkadot_connection = client + .add_chain(subxt_lightclient::smoldot::AddChainConfig { + specification: POLKADOT_SPEC, + json_rpc: subxt_lightclient::smoldot::AddChainConfigJsonRpc::Enabled { + max_pending_requests: NonZeroU32::new(128).unwrap(), + max_subscriptions: 1024, + }, + potential_relay_chains: iter::empty(), + database_content: "", + user_data: (), + }) + .expect("Light client chain added with valid spec; qed"); + let polkadot_json_rpc_responses = polkadot_connection + .json_rpc_responses + .expect("Light client configured with json rpc enabled; qed"); + let polkadot_chain_id = polkadot_connection.chain_id; + + // Step 3. Connect to the parachain. For this example, the Asset hub parachain. + let assethub_connection = client + .add_chain(subxt_lightclient::smoldot::AddChainConfig { + specification: ASSET_HUB_SPEC, + json_rpc: subxt_lightclient::smoldot::AddChainConfigJsonRpc::Enabled { + max_pending_requests: NonZeroU32::new(128).unwrap(), + max_subscriptions: 1024, + }, + // The chain specification of the asset hub parachain mentions that the identifier + // of its relay chain is `polkadot`. + potential_relay_chains: [polkadot_chain_id].into_iter(), + database_content: "", + user_data: (), + }) + .expect("Light client chain added with valid spec; qed"); + let parachain_json_rpc_responses = assethub_connection + .json_rpc_responses + .expect("Light client configured with json rpc enabled; qed"); + let parachain_chain_id = assethub_connection.chain_id; + + // Step 4. Turn the smoldot client into a raw client. + let raw_light_client = RawLightClient::builder() + .add_chain(polkadot_chain_id, polkadot_json_rpc_responses) + .add_chain(parachain_chain_id, parachain_json_rpc_responses) + .build(client) + .await?; + + // Step 5. Obtain a client to target the relay chain and the parachain. + let polkadot_api: LightClient = + raw_light_client.for_chain(polkadot_chain_id).await?; + let parachain_api: LightClient = + raw_light_client.for_chain(parachain_chain_id).await?; + + // Step 6. Subscribe to the finalized blocks of the chains. + let polkadot_sub = polkadot_api + .blocks() + .subscribe_finalized() + .await? + .map(|block| ("Polkadot", block)); + let parachain_sub = parachain_api + .blocks() + .subscribe_finalized() + .await? + .map(|block| ("AssetHub", block)); + let mut stream_combinator = futures::stream::select(polkadot_sub, parachain_sub); + + while let Some((chain, block)) = stream_combinator.next().await { + let block = block?; + + println!(" Chain {:?} hash={:?}", chain, block.hash()); + } + + Ok(()) +} +*/ + //! ``` + } + pub mod rpc { + //! # RPC calls + //! + //! Subxt exposes low level interfaces that can be used to make RPC requests; [`crate::backend::legacy::rpc_methods`] + //! and [`crate::backend::unstable::rpc_methods`]. + //! + //! These interfaces cannot be accessed directly through an [`crate::OnlineClient`]; this is so that the high level + //! Subxt APIs can target either the "legacy" or the more modern "unstable" sets of RPC methods by selecting an appropriate + //! [`crate::backend::Backend`]. It also means that there could exist a backend in the future that doesn't use JSON-RPC at all. + //! + //! # Example + //! + //! Here's an example which calls some legacy JSON-RPC methods, and reuses the same connection to run a full Subxt client + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::backend::{legacy::LegacyRpcMethods, rpc::RpcClient}; +use subxt::config::DefaultExtrinsicParamsBuilder as Params; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // First, create a raw RPC client: + let rpc_client = RpcClient::from_url("ws://127.0.0.1:9944").await?; + + // Use this to construct our RPC methods: + let rpc = LegacyRpcMethods::::new(rpc_client.clone()); + + // We can use the same client to drive our full Subxt interface too: + let api = OnlineClient::::from_rpc_client(rpc_client.clone()).await?; + + // Now, we can make some RPC calls using some legacy RPC methods. + println!( + "📛 System Name: {:?}\n🩺 Health: {:?}\n🖫 Properties: {:?}\n🔗 Chain: {:?}\n", + rpc.system_name().await?, + rpc.system_health().await?, + rpc.system_properties().await?, + rpc.system_chain().await? + ); + + // We can also interleave RPC calls and using the full Subxt client, here to submit multiple + // transactions using the legacy `system_account_next_index` RPC call, which returns a nonce + // that is adjusted for any transactions already in the pool: + + let alice = dev::alice(); + let bob = dev::bob(); + + loop { + let current_nonce = rpc + .system_account_next_index(&alice.public_key().into()) + .await?; + let current_header = rpc.chain_get_header(None).await?.unwrap(); + + let ext_params = Params::new().mortal(¤t_header, 8).build(); + + let balance_transfer = polkadot::tx() + .balances() + .transfer_allow_death(bob.public_key().into(), 1_000_000); + + let ext_hash = api + .tx() + .create_signed_with_nonce(&balance_transfer, &alice, current_nonce, ext_params)? + .submit() + .await?; + + println!("Submitted ext {ext_hash} with nonce {current_nonce}"); + + // Sleep less than block time, but long enough to ensure + // not all transactions end up in the same block. + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + } +} +*/ + //! ``` + } + pub mod runtime_apis { + //! # Runtime API interface + //! + //! The Runtime API interface allows Subxt to call runtime APIs exposed by certain pallets in order + //! to obtain information. Much like [`super::storage`] and [`super::transactions`], Making a runtime + //! call to a node and getting the response back takes the following steps: + //! + //! 1. [Constructing a runtime call](#constructing-a-runtime-call) + //! 2. [Submitting it to get back the response](#submitting-it) + //! + //! **Note:** Runtime APIs are only available when using V15 metadata, which is currently unstable. + //! You'll need to use `subxt metadata --version unstable` command to download the unstable V15 metadata, + //! and activate the `unstable-metadata` feature in Subxt for it to also use this metadata from a node. The + //! metadata format is unstable because it may change and break compatibility with Subxt at any moment, so + //! use at your own risk. + //! + //! ## Constructing a runtime call + //! + //! We can use the statically generated interface to build runtime calls: + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] + //! pub mod polkadot {} + //! + //! let runtime_call = polkadot::apis().metadata().metadata_versions(); + //! ``` + //! + //! Alternately, we can dynamically construct a runtime call: + //! + //! ```rust,no_run + //! use subxt::dynamic::Value; + //! + //! let runtime_call = subxt::dynamic::runtime_api_call( + //! "Metadata", + //! "metadata_versions", + //! Vec::>::new() + //! ); + //! ``` + //! + //! All valid runtime calls implement [`crate::runtime_api::RuntimeApiPayload`], a trait which + //! describes how to encode the runtime call arguments and what return type to decode from the + //! response. + //! + //! ## Submitting it + //! + //! Runtime calls can be handed to [`crate::runtime_api::RuntimeApi::call()`], which will submit + //! them and hand back the associated response. + //! + //! ### Making a static Runtime API call + //! + //! The easiest way to make a runtime API call is to use the statically generated interface. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{config::PolkadotConfig, OnlineClient}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Create a runtime API payload that calls into + // `AccountNonceApi_account_nonce` function. + let account = dev::alice().public_key().into(); + let runtime_api_call = polkadot::apis().account_nonce_api().account_nonce(account); + + // Submit the call and get back a result. + let nonce = api + .runtime_api() + .at_latest() + .await? + .call(runtime_api_call) + .await; + + println!("AccountNonceApi_account_nonce for Alice: {:?}", nonce); + Ok(()) +} +*/ + //! ``` + //! + //! ### Making a dynamic Runtime API call + //! + //! If you'd prefer to construct the call at runtime, you can do this using the + //! [`crate::dynamic::runtime_api_call`] method. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::dynamic::Value; +use subxt::{config::PolkadotConfig, OnlineClient}; +use subxt_signer::sr25519::dev; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Create a dynamically runtime API payload that calls the + // `AccountNonceApi_account_nonce` function. + let account = dev::alice().public_key(); + let runtime_api_call = subxt::dynamic::runtime_api_call( + "AccountNonceApi", + "account_nonce", + vec![Value::from_bytes(account)], + ); + + // Submit the call to get back a result. + let nonce = api + .runtime_api() + .at_latest() + .await? + .call(runtime_api_call) + .await?; + + println!("Account nonce: {:#?}", nonce.to_value()); + Ok(()) +} +*/ + //! ``` + //! + //! ### Making a raw call + //! + //! This is generally discouraged in favour of one of the above, but may be necessary (especially if + //! the node you're talking to does not yet serve V15 metadata). Here, you must manually encode + //! the argument bytes and manually provide a type for the response bytes to be decoded into. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::ext::codec::Compact; +use subxt::ext::frame_metadata::RuntimeMetadataPrefixed; +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Use runtime APIs at the latest block: + let runtime_apis = api.runtime_api().at_latest().await?; + + // Ask for metadata and decode it: + let (_, meta): (Compact, RuntimeMetadataPrefixed) = + runtime_apis.call_raw("Metadata_metadata", None).await?; + + println!("{meta:?}"); + Ok(()) +} +*/ + //! ``` + //! + } + pub mod storage { + //! # Storage + //! + //! A Substrate based chain can be seen as a key/value database which starts off at some initial + //! state, and is modified by the extrinsics in each block. This database is referred to as the + //! node storage. With Subxt, you can query this key/value storage with the following steps: + //! + //! 1. [Constructing a storage query](#constructing-a-storage-query). + //! 2. [Submitting the query to get back the associated values](#submitting-it). + //! + //! ## Constructing a storage query + //! + //! We can use the statically generated interface to build storage queries: + //! + //! ```rust,no_run + //! use subxt_signer::sr25519::dev; + //! + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] + //! pub mod polkadot {} + //! + //! let account = dev::alice().public_key().into(); + //! let storage_query = polkadot::storage().system().account(&account); + //! ``` + //! + //! Alternately, we can dynamically construct a storage query. This will not be type checked or + //! validated until it's submitted: + //! + //! ```rust,no_run + //! use subxt_signer::sr25519::dev; + //! use subxt::dynamic::Value; + //! + //! let account = dev::alice().public_key(); + //! let storage_query = subxt::dynamic::storage("System", "Account", vec![ + //! Value::from_bytes(account) + //! ]); + //! ``` + //! + //! As well as accessing specific entries, some storage locations can also be iterated over (such as + //! the map of account information). To do this, suffix `_iter` onto the query constructor (this + //! will only be available on static constructors when iteration is actually possible): + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] + //! pub mod polkadot {} + //! + //! // A static query capable of iterating over accounts: + //! let storage_query = polkadot::storage().system().account_iter(); + //! // A dynamic query to do the same: + //! let storage_query = subxt::dynamic::storage("System", "Account", ()); + //! ``` + //! + //! Some storage entries are maps with multiple keys. As an example, we might end up with + //! an API like `runtime::storage().foo().bar(u8, bool, u16, String)` to fetch some entry "bar". + //! When this is the case, the codegen will generate multiple iterator query functions alongside + //! the function to fetch an individual value: + //! + //! - `runtime::storage().foo().bar(u8, bool, u16, String)`: fetch a single entry from the "bar" map. + //! - `runtime::storage().foo().bar_iter()`: iterate over all of the entries in the "bar" map. + //! - `runtime::storage().foo().bar_iter1(u8)`: iterate over all of the entries in the "bar" map under + //! a given `u8`. + //! - `runtime::storage().foo().bar_iter2(u8, bool)`: iterate over all of the entries in the "bar" map under + //! a given `u8` and `bool` value. + //! - `runtime::storage().foo().bar_iter3(u8, bool, u16)`: iterate over all of the entries in the "bar" map under + //! a given `u8`, `bool` and `u16` value. + //! + //! All valid storage queries implement [`crate::storage::StorageAddress`]. As well as describing + //! how to build a valid storage query, this trait also has some associated types that determine the + //! shape of the result you'll get back, and determine what you can do with it (ie, can you iterate + //! over storage entries using it). + //! + //! Static queries set appropriate values for these associated types, and can therefore only be used + //! where it makes sense. Dynamic queries don't know any better and can be used in more places, but + //! may fail at runtime instead if they are invalid in those places. + //! + //! ## Submitting it + //! + //! Storage queries can be handed to various functions in [`crate::storage::Storage`] in order to + //! obtain the associated values (also referred to as storage entries) back. + //! + //! ### Fetching storage entries + //! + //! The simplest way to access storage entries is to construct a query and then call either + //! [`crate::storage::Storage::fetch()`] or [`crate::storage::Storage::fetch_or_default()`] (the + //! latter will only work for storage queries that have a default value when empty): + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a storage query to access account information. + let account = dev::alice().public_key().into(); + let storage_query = polkadot::storage().system().account(&account); + + // Use that query to `fetch` a result. This returns an `Option<_>`, which will be + // `None` if no value exists at the given address. You can also use `fetch_default` + // where applicable, which will return the default value if none exists. + let result = api + .storage() + .at_latest() + .await? + .fetch(&storage_query) + .await?; + + println!("Alice has free balance: {}", result.unwrap().data.free); + Ok(()) +} +*/ + //! ``` + //! + //! For completeness, below is an example using a dynamic query instead. The return type from a + //! dynamic query is a [`crate::dynamic::DecodedValueThunk`], which can be decoded into a + //! [`crate::dynamic::Value`], or else the raw bytes can be accessed instead. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::dynamic::{At, Value}; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a dynamic storage query to access account information. + let account = dev::alice().public_key(); + let storage_query = + subxt::dynamic::storage("System", "Account", vec![Value::from_bytes(account)]); + + // Use that query to `fetch` a result. Because the query is dynamic, we don't know what the result + // type will be either, and so we get a type back that can be decoded into a dynamic Value type. + let result = api + .storage() + .at_latest() + .await? + .fetch(&storage_query) + .await?; + let value = result.unwrap().to_value()?; + + println!("Alice has free balance: {:?}", value.at("data").at("free")); + Ok(()) +} +*/ + //! ``` + //! + //! ### Iterating storage entries + //! + //! Many storage entries are maps of values; as well as fetching individual values, it's possible to + //! iterate over all of the values stored at that location: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a storage query to iterate over account information. + let storage_query = polkadot::storage().system().account_iter(); + + // Get back an iterator of results (here, we are fetching 10 items at + // a time from the node, but we always iterate over one at a time). + let mut results = api.storage().at_latest().await?.iter(storage_query).await?; + + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value); + } + + Ok(()) +} +*/ + //! ``` + //! + //! Here's the same logic but using dynamically constructed values instead: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a dynamic storage query to iterate account information. + // With a dynamic query, we can just provide an empty vector as the keys to iterate over all entries. + let keys: Vec = vec![]; + let storage_query = subxt::dynamic::storage("System", "Account", keys); + + // Use that query to return an iterator over the results. + let mut results = api.storage().at_latest().await?.iter(storage_query).await?; + + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value.to_value()?); + } + + Ok(()) +} +*/ + //! ``` + //! + //! Here is an example of iterating over partial keys. In this example some multi-signature operations + //! are sent to the node. We can iterate over the pending multisig operations of a single multisig account: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use polkadot::multisig::events::NewMultisig; +use polkadot::runtime_types::{ + frame_system::pallet::Call, rococo_runtime::RuntimeCall, sp_weights::weight_v2::Weight, +}; +use subxt::utils::AccountId32; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::{dev, Keypair}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Prepare the chain to have 3 open multisig requests (2 of them are alice + bob): + let alice_signer = dev::alice(); + let bob = AccountId32(dev::bob().public_key().0); + let charlie = AccountId32(dev::charlie().public_key().0); + + let new_multisig_1 = submit_remark_as_multi(&alice_signer, &bob, b"Hello", &api).await?; + let new_multisig_2 = submit_remark_as_multi(&alice_signer, &bob, b"Hi", &api).await?; + let new_multisig_3 = submit_remark_as_multi(&alice_signer, &charlie, b"Hello", &api).await?; + + // Note: the NewMultisig event contains the multisig address we need to use for the storage queries: + assert_eq!(new_multisig_1.multisig, new_multisig_2.multisig); + assert_ne!(new_multisig_1.multisig, new_multisig_3.multisig); + + // Build a storage query to iterate over open multisig extrinsics from + // new_multisig_1.multisig which is the AccountId of the alice + bob multisig account + let alice_bob_account_id = &new_multisig_1.multisig; + let storage_query = polkadot::storage() + .multisig() + .multisigs_iter1(alice_bob_account_id); + + // Get back an iterator of results. + let mut results = api.storage().at_latest().await?.iter(storage_query).await?; + + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value); + } + Ok(()) +} + +async fn submit_remark_as_multi( + signer: &Keypair, + other: &AccountId32, + remark: &[u8], + api: &OnlineClient, +) -> Result> { + let multisig_remark_tx = polkadot::tx().multisig().as_multi( + 2, + vec![other.clone()], + None, + RuntimeCall::System(Call::remark { + remark: remark.to_vec(), + }), + Weight { + ref_time: 0, + proof_size: 0, + }, + ); + let events = api + .tx() + .sign_and_submit_then_watch_default(&multisig_remark_tx, signer) + .await? + .wait_for_finalized_success() + .await?; + let new_multisig = events + .find_first::()? + .expect("should contain event"); + Ok(new_multisig) +} +*/ + //! ``` + //! + //! ### Advanced + //! + //! For more advanced use cases, have a look at [`crate::storage::Storage::fetch_raw`] and + //! [`crate::storage::Storage::fetch_raw_keys`]. Both of these take raw bytes as arguments, which can be + //! obtained from a [`crate::storage::StorageAddress`] by using + //! [`crate::storage::StorageClient::address_bytes()`] or + //! [`crate::storage::StorageClient::address_root_bytes()`]. + //! + } + pub mod transactions { + //! # Transactions + //! + //! A transaction is an extrinsic that's signed (ie it originates from a given address). The purpose + //! of extrinsics is to modify the node storage in a deterministic way, and so being able to submit + //! transactions to a node is one of the core features of Subxt. + //! + //! > Note: the documentation tends to use the terms _extrinsic_ and _transaction_ interchangeably; + //! > An extrinsic is some data that can be added to a block, and is either signed (a _transaction_) + //! > or unsigned (an _inherent_). Subxt can construct either, but overwhelmingly you'll need to + //! > sign the payload you'd like to submit. + //! + //! Submitting a transaction to a node consists of the following steps: + //! + //! 1. [Constructing a transaction payload to submit](#constructing-a-transaction-payload). + //! 2. [Signing it](#signing-it). + //! 3. [Submitting it (optionally with some additional parameters)](#submitting-it). + //! + //! We'll look at each of these steps in turn. + //! + //! ## Constructing a transaction payload + //! + //! We can use the statically generated interface to build transaction payloads: + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] + //! pub mod polkadot {} + //! + //! let remark = "Hello there".as_bytes().to_vec(); + //! let tx_payload = polkadot::tx().system().remark(remark); + //! ``` + //! + //! > If you're not sure what types to import and use to build a given payload, you can use the + //! > `subxt` CLI tool to generate the interface by using something like `subxt codegen | rustfmt > + //! > interface.rs`, to see what types and things are available (or even just to use directly + //! > instead of the [`#[subxt]`](crate::subxt) macro). + //! + //! Alternately, we can dynamically construct a transaction payload. This will not be type checked or + //! validated until it's submitted: + //! + //! ```rust,no_run + //! use subxt::dynamic::Value; + //! + //! let tx_payload = subxt::dynamic::tx("System", "remark", vec![ + //! Value::from_bytes("Hello there") + //! ]); + //! ``` + //! + //! The [`crate::dynamic::Value`] type is a dynamic type much like a `serde_json::Value` but instead + //! represents any type of data that can be SCALE encoded or decoded. It can be serialized, + //! deserialized and parsed from/to strings. + //! + //! A valid transaction payload is just something that implements the [`crate::tx::TxPayload`] trait; + //! you can implement this trait on your own custom types if the built-in ones are not suitable for + //! your needs. + //! + //! ## Signing it + //! + //! You'll normally need to sign an extrinsic to prove that it originated from an account that you + //! control. To do this, you will typically first create a [`crate::tx::Signer`] instance, which tells + //! Subxt who the extrinsic is from, and takes care of signing the relevant details to prove this. + //! + //! There are two main ways to create a compatible signer instance: + //! 1. The `subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`] + //! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled). + //! 2. Alternately, Subxt can use instances of Substrate's `sp_core::Pair` to sign things by wrapping + //! them in a `crate::tx::PairSigner` (requires the `substrate-compat` feature to be enabled). + //! + //! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via + //! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or + //! need additional signing algorithms that `subxt_signer` doesn't support, and don't care about WASM + //! compatibility. + //! + //! Let's see how to use each of these approaches: + //! + //! ```rust + //! # #[cfg(feature = "substrate-compat")] + //! # { + //! use subxt::config::PolkadotConfig; + //! use std::str::FromStr; + //! + //! //// 1. Use a `subxt_signer` impl: + //! use subxt_signer::{ SecretUri, sr25519 }; + //! + //! // Get hold of a `Signer` for a test account: + //! let alice = sr25519::dev::alice(); + //! + //! // Or generate a keypair, here from an SURI: + //! let uri = SecretUri::from_str("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password") + //! .expect("valid URI"); + //! let keypair = sr25519::Keypair::from_uri(&uri) + //! .expect("valid keypair"); + //! + //! //// 2. Use the corresponding `sp_core::Pair` impl: + //! use subxt::tx::PairSigner; + //! use sp_core::Pair; + //! + //! // Get hold of a `Signer` for a test account: + //! let alice = sp_keyring::AccountKeyring::Alice.pair(); + //! let alice = PairSigner::::new(alice); + //! + //! // Or generate a keypair, here from an SURI: + //! let keypair = sp_core::sr25519::Pair::from_string("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password", None) + //! .expect("valid URI"); + //! let keypair = PairSigner::::new(keypair); + //! # + //! # // Test that these all impl Signer trait while we're here: + //! # + //! # fn is_subxt_signer(_signer: impl subxt::tx::Signer) {} + //! # is_subxt_signer(subxt_signer::sr25519::dev::alice()); + //! # is_subxt_signer(subxt_signer::ecdsa::dev::alice()); + //! # is_subxt_signer(PairSigner::::new(sp_keyring::AccountKeyring::Alice.pair())); + //! # } + //! ``` + //! + //! See the `subxt_signer` crate or the `sp_core::Pair` docs for more ways to construct + //! and work with key pairs. + //! + //! If this isn't suitable/available, you can either implement [`crate::tx::Signer`] yourself to use + //! custom signing logic, or you can use some external signing logic, like so: + //! + //! ```rust,no_run + //! # #[tokio::main] + //! # async fn main() -> Result<(), Box> { + //! use subxt::client::OnlineClient; + //! use subxt::config::PolkadotConfig; + //! use subxt::dynamic::Value; + //! + //! // Create client: + //! let client = OnlineClient::::new().await?; + //! + //! // Create a dummy tx payload to sign: + //! let payload = subxt::dynamic::tx("System", "remark", vec![ + //! Value::from_bytes("Hello there") + //! ]); + //! + //! // Construct the tx but don't sign it. You need to provide the nonce + //! // here, or can use `create_partial_signed` to fetch the correct nonce. + //! let partial_tx = client.tx().create_partial_signed_with_nonce( + //! &payload, + //! 0u64, + //! Default::default() + //! )?; + //! + //! // Fetch the payload that needs to be signed: + //! let signer_payload = partial_tx.signer_payload(); + //! + //! // ... At this point, we can hand off the `signer_payload` to be signed externally. + //! // Ultimately we need to be given back a `signature` (or really, anything + //! // that can be SCALE encoded) and an `address`: + //! let signature; + //! let address; + //! # use subxt::tx::Signer; + //! # let signer = subxt_signer::sr25519::dev::alice(); + //! # signature = signer.sign(&signer_payload).into(); + //! # address = signer.public_key().to_address(); + //! + //! // Now we can build an tx, which one can call `submit` or `submit_and_watch` + //! // on to submit to a node and optionally watch the status. + //! let tx = partial_tx.sign_with_address_and_signature( + //! &address, + //! &signature + //! ); + //! # Ok(()) + //! # } + //! ``` + //! + //! ## Submitting it + //! + //! Once we have signed the transaction, we need to submit it. + //! + //! ### The high level API + //! + //! The highest level approach to doing this is to call + //! [`crate::tx::TxClient::sign_and_submit_then_watch_default`]. This hands back a + //! [`crate::tx::TxProgress`] struct which will monitor the transaction status. We can then call + //! [`crate::tx::TxProgress::wait_for_finalized_success()`] to wait for this transaction to make it + //! into a finalized block, check for an `ExtrinsicSuccess` event, and then hand back the events for + //! inspection. This looks like: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let from = dev::alice(); + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} +*/ + //! ``` + //! + //! ### Providing transaction parameters + //! + //! If you'd like to provide parameters (such as mortality) to the transaction, you can use + //! [`crate::tx::TxClient::sign_and_submit_then_watch`] instead: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::config::polkadot::PolkadotExtrinsicParamsBuilder as Params; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + let latest_block = api.blocks().at_latest().await?; + + // Configure the transaction parameters; we give a small tip and set the + // transaction to live for 32 blocks from the `latest_block` above. + let tx_params = Params::new() + .tip(1_000) + .mortal(latest_block.header(), 32) + .build(); + + // submit the transaction: + let from = dev::alice(); + let hash = api.tx().sign_and_submit(&tx, &from, tx_params).await?; + println!("Balance transfer extrinsic submitted with hash : {hash}"); + + Ok(()) +} +*/ + //! ``` + //! + //! This example doesn't wait for the transaction to be included in a block; it just submits it and + //! hopes for the best! + //! + //! ### Custom handling of transaction status updates + //! + //! If you'd like more control or visibility over exactly which status updates are being emitted for + //! the transaction, you can monitor them as they are emitted and react however you choose: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{tx::TxStatus, OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and then monitor the + // progress of it. + let from = dev::alice(); + let mut balance_transfer_progress = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await?; + + while let Some(status) = balance_transfer_progress.next().await { + match status? { + // It's finalized in a block! + TxStatus::InFinalizedBlock(in_block) => { + println!( + "Transaction {:?} is finalized in block {:?}", + in_block.extrinsic_hash(), + in_block.block_hash() + ); + + // grab the events and fail if no ExtrinsicSuccess event seen: + let events = in_block.wait_for_success().await?; + // We can look for events (this uses the static interface; we can also iterate + // over them and dynamically decode them): + let transfer_event = events.find_first::()?; + + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } else { + println!("Failed to find Balances::Transfer Event"); + } + } + // Just log any other status we encounter: + other => { + println!("Status: {other:?}"); + } + } + } + Ok(()) +} +*/ + //! ``` + //! + //! Take a look at the API docs for [`crate::tx::TxProgress`], [`crate::tx::TxStatus`] and + //! [`crate::tx::TxInBlock`] for more options. + //! + } + } +} +pub mod backend { + //! This module exposes a backend trait for Subxt which allows us to get and set + //! the necessary information (probably from a JSON-RPC API, but that's up to the + //! implementation). + pub mod legacy { + //! This module exposes a legacy backend implementation, which relies + //! on the legacy RPC API methods. + pub mod rpc_methods { + //! An interface to call the raw legacy RPC methods. + use crate::backend::rpc::{rpc_params, RpcClient, RpcSubscription}; + use crate::metadata::Metadata; + use crate::{Config, Error}; + use codec::Decode; + use derivative::Derivative; + use primitive_types::U256; + use serde::{Deserialize, Serialize}; + /// An interface to call the legacy RPC methods. This interface is instantiated with + /// some `T: Config` trait which determines some of the types that the RPC methods will + /// take or hand back. + #[derivative(Clone(bound = ""), Debug(bound = ""))] + pub struct LegacyRpcMethods { + client: RpcClient, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for LegacyRpcMethods { + fn clone(&self) -> Self { + match *self { + LegacyRpcMethods { + client: ref __arg_0, + _marker: ref __arg_1, + } => { + LegacyRpcMethods { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for LegacyRpcMethods { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + LegacyRpcMethods { + client: ref __arg_0, + _marker: ref __arg_1, + } => { + let mut __debug_trait_builder = __f + .debug_struct("LegacyRpcMethods"); + let _ = __debug_trait_builder.field("client", &&(*__arg_0)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + impl LegacyRpcMethods { + /// Instantiate the legacy RPC method interface. + pub fn new(client: RpcClient) -> Self { + LegacyRpcMethods { + client, + _marker: std::marker::PhantomData, + } + } + /// Fetch the raw bytes for a given storage key + pub async fn state_get_storage( + &self, + key: &[u8], + hash: Option, + ) -> Result, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(key)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let data: Option = self + .client + .request("state_getStorage", params) + .await?; + Ok(data.map(|b| b.0)) + } + /// Returns the keys with prefix with pagination support. + /// Up to `count` keys will be returned. + /// If `start_key` is passed, return next keys in storage in lexicographic order. + pub async fn state_get_keys_paged( + &self, + key: &[u8], + count: u32, + start_key: Option<&[u8]>, + at: Option, + ) -> Result, Error> { + let start_key = start_key.map(to_hex); + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(key)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(count) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(start_key) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let data: Vec = self + .client + .request("state_getKeysPaged", params) + .await?; + Ok(data.into_iter().map(|b| b.0).collect()) + } + /// Query historical storage entries in the range from the start block to the end block, + /// defaulting the end block to the current best block if it's not given. The first + /// [`StorageChangeSet`] returned has all of the values for each key, and subsequent ones + /// only contain values for any keys which have changed since the last. + pub async fn state_query_storage( + &self, + keys: impl IntoIterator, + from: T::Hash, + to: Option, + ) -> Result>, Error> { + let keys: Vec = keys.into_iter().map(to_hex).collect(); + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(keys) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(from) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(to) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client + .request("state_queryStorage", params) + .await + .map_err(Into::into) + } + /// Query storage entries at some block, using the best block if none is given. + /// This essentially provides a way to ask for a batch of values given a batch of keys, + /// despite the name of the [`StorageChangeSet`] type. + pub async fn state_query_storage_at( + &self, + keys: impl IntoIterator, + at: Option, + ) -> Result>, Error> { + let keys: Vec = keys.into_iter().map(to_hex).collect(); + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(keys) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client + .request("state_queryStorageAt", params) + .await + .map_err(Into::into) + } + /// Fetch the genesis hash + pub async fn genesis_hash(&self) -> Result { + let block_zero = 0u32; + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(block_zero) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let genesis_hash: Option = self + .client + .request("chain_getBlockHash", params) + .await?; + genesis_hash.ok_or_else(|| "Genesis hash not found".into()) + } + /// Fetch the metadata via the legacy `state_getMetadata` RPC method. + pub async fn state_get_metadata( + &self, + at: Option, + ) -> Result { + let bytes: Bytes = self + .client + .request( + "state_getMetadata", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + let metadata = Metadata::decode(&mut &bytes[..])?; + Ok(metadata) + } + /// Fetch system health + pub async fn system_health(&self) -> Result { + self.client + .request( + "system_health", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch system chain + pub async fn system_chain(&self) -> Result { + self.client + .request( + "system_chain", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch system name + pub async fn system_name(&self) -> Result { + self.client + .request( + "system_name", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch system version + pub async fn system_version(&self) -> Result { + self.client + .request( + "system_version", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch system properties + pub async fn system_properties( + &self, + ) -> Result { + self.client + .request( + "system_properties", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch next nonce for an Account + /// + /// Return account nonce adjusted for extrinsics currently in transaction pool + pub async fn system_account_next_index( + &self, + account_id: &T::AccountId, + ) -> Result + where + T::AccountId: Serialize, + { + self.client + .request( + "system_accountNextIndex", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(&account_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await + } + /// Get a header + pub async fn chain_get_header( + &self, + hash: Option, + ) -> Result, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let header = self.client.request("chain_getHeader", params).await?; + Ok(header) + } + /// Get a block hash, returns hash of latest _best_ block by default. + pub async fn chain_get_block_hash( + &self, + block_number: Option, + ) -> Result, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(block_number) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let block_hash = self + .client + .request("chain_getBlockHash", params) + .await?; + Ok(block_hash) + } + /// Get a block hash of the latest finalized block + pub async fn chain_get_finalized_head(&self) -> Result { + let hash = self + .client + .request( + "chain_getFinalizedHead", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await?; + Ok(hash) + } + /// Get a Block + pub async fn chain_get_block( + &self, + hash: Option, + ) -> Result>, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let block = self.client.request("chain_getBlock", params).await?; + Ok(block) + } + /// Reexecute the specified `block_hash` and gather statistics while doing so. + /// + /// This function requires the specified block and its parent to be available + /// at the queried node. If either the specified block or the parent is pruned, + /// this function will return `None`. + pub async fn dev_get_block_stats( + &self, + block_hash: T::Hash, + ) -> Result, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(block_hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let stats = self.client.request("dev_getBlockStats", params).await?; + Ok(stats) + } + /// Get proof of storage entries at a specific block's state. + pub async fn state_get_read_proof( + &self, + keys: impl IntoIterator, + hash: Option, + ) -> Result, Error> { + let keys: Vec = keys.into_iter().map(to_hex).collect(); + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(keys) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let proof = self.client.request("state_getReadProof", params).await?; + Ok(proof) + } + /// Fetch the runtime version + pub async fn state_get_runtime_version( + &self, + at: Option, + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let version = self + .client + .request("state_getRuntimeVersion", params) + .await?; + Ok(version) + } + /// Subscribe to all new best block headers. + pub async fn chain_subscribe_new_heads( + &self, + ) -> Result, Error> { + let subscription = self + .client + .subscribe( + "chain_subscribeNewHeads", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + "chain_unsubscribeNewHeads", + ) + .await?; + Ok(subscription) + } + /// Subscribe to all new block headers. + pub async fn chain_subscribe_all_heads( + &self, + ) -> Result, Error> { + let subscription = self + .client + .subscribe( + "chain_subscribeAllHeads", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + "chain_unsubscribeAllHeads", + ) + .await?; + Ok(subscription) + } + /// Subscribe to finalized block headers. + /// + /// Note: this may not produce _every_ block in the finalized chain; + /// sometimes multiple blocks are finalized at once, and in this case only the + /// latest one is returned. the higher level APIs that use this "fill in" the + /// gaps for us. + pub async fn chain_subscribe_finalized_heads( + &self, + ) -> Result, Error> { + let subscription = self + .client + .subscribe( + "chain_subscribeFinalizedHeads", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + "chain_unsubscribeFinalizedHeads", + ) + .await?; + Ok(subscription) + } + /// Subscribe to runtime version updates that produce changes in the metadata. + /// The first item emitted by the stream is the current runtime version. + pub async fn state_subscribe_runtime_version( + &self, + ) -> Result, Error> { + let subscription = self + .client + .subscribe( + "state_subscribeRuntimeVersion", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + "state_unsubscribeRuntimeVersion", + ) + .await?; + Ok(subscription) + } + /// Create and submit an extrinsic and return corresponding Hash if successful + pub async fn author_submit_extrinsic( + &self, + extrinsic: &[u8], + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(extrinsic)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let xt_hash = self + .client + .request("author_submitExtrinsic", params) + .await?; + Ok(xt_hash) + } + /// Create and submit an extrinsic and return a subscription to the events triggered. + pub async fn author_submit_and_watch_extrinsic( + &self, + extrinsic: &[u8], + ) -> Result>, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(extrinsic)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let subscription = self + .client + .subscribe( + "author_submitAndWatchExtrinsic", + params, + "author_unwatchExtrinsic", + ) + .await?; + Ok(subscription) + } + /// Insert a key into the keystore. + pub async fn author_insert_key( + &self, + key_type: String, + suri: String, + public: Vec, + ) -> Result<(), Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(key_type) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(suri) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(Bytes(public)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client.request("author_insertKey", params).await?; + Ok(()) + } + /// Generate new session keys and returns the corresponding public keys. + pub async fn author_rotate_keys(&self) -> Result, Error> { + let bytes: Bytes = self + .client + .request( + "author_rotateKeys", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await?; + Ok(bytes.0) + } + /// Checks if the keystore has private keys for the given session public keys. + /// + /// `session_keys` is the SCALE encoded session keys object from the runtime. + /// + /// Returns `true` if all private keys could be found. + pub async fn author_has_session_keys( + &self, + session_keys: Vec, + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(Bytes(session_keys)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client.request("author_hasSessionKeys", params).await + } + /// Checks if the keystore has private keys for the given public key and key type. + /// + /// Returns `true` if a private key could be found. + pub async fn author_has_key( + &self, + public_key: Vec, + key_type: String, + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(Bytes(public_key)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(key_type) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client.request("author_hasKey", params).await + } + /// Execute a runtime API call via `state_call` RPC method. + pub async fn state_call( + &self, + function: &str, + call_parameters: Option<&[u8]>, + at: Option, + ) -> Result, Error> { + let call_parameters = call_parameters.unwrap_or_default(); + let bytes: Bytes = self + .client + .request( + "state_call", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(function) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(to_hex(call_parameters)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(bytes.0) + } + /// Submits the extrinsic to the dry_run RPC, to test if it would succeed. + /// + /// Returns a [`DryRunResult`], which is the result of performing the dry run. + pub async fn dry_run( + &self, + encoded_signed: &[u8], + at: Option, + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(encoded_signed)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let result_bytes: Bytes = self + .client + .request("system_dryRun", params) + .await?; + Ok(DryRunResultBytes(result_bytes.0)) + } + } + /// Storage key. + pub type StorageKey = Vec; + /// Storage data. + pub type StorageData = Vec; + /// Health struct returned by the RPC + #[serde(rename_all = "camelCase")] + pub struct SystemHealth { + /// Number of connected peers + pub peers: usize, + /// Is the node syncing + pub is_syncing: bool, + /// Should this node have any peers + /// + /// Might be false for local chains or when running without discovery. + pub should_have_peers: bool, + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SystemHealth { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "peers" => _serde::__private::Ok(__Field::__field0), + "isSyncing" => _serde::__private::Ok(__Field::__field1), + "shouldHavePeers" => { + _serde::__private::Ok(__Field::__field2) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"peers" => _serde::__private::Ok(__Field::__field0), + b"isSyncing" => _serde::__private::Ok(__Field::__field1), + b"shouldHavePeers" => { + _serde::__private::Ok(__Field::__field2) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SystemHealth; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct SystemHealth", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + usize, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SystemHealth with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + bool, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct SystemHealth with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + bool, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct SystemHealth with 3 elements", + ), + ); + } + }; + _serde::__private::Ok(SystemHealth { + peers: __field0, + is_syncing: __field1, + should_have_peers: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("peers"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "isSyncing", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "shouldHavePeers", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("peers")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("isSyncing")? + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("shouldHavePeers")? + } + }; + _serde::__private::Ok(SystemHealth { + peers: __field0, + is_syncing: __field1, + should_have_peers: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "peers", + "isSyncing", + "shouldHavePeers", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SystemHealth", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for SystemHealth { + #[inline] + fn clone(&self) -> SystemHealth { + SystemHealth { + peers: ::core::clone::Clone::clone(&self.peers), + is_syncing: ::core::clone::Clone::clone(&self.is_syncing), + should_have_peers: ::core::clone::Clone::clone( + &self.should_have_peers, + ), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for SystemHealth { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "SystemHealth", + "peers", + &self.peers, + "is_syncing", + &self.is_syncing, + "should_have_peers", + &&self.should_have_peers, + ) + } + } + /// System properties; an arbitrary JSON object. + pub type SystemProperties = serde_json::Map; + /// A block number + pub type BlockNumber = NumberOrHex; + /// The response from `chain_getBlock` + #[serde(bound = "T: Config")] + pub struct BlockDetails { + /// The block itself. + pub block: Block, + /// Block justification. + pub justifications: Option>, + } + #[automatically_derived] + impl ::core::fmt::Debug for BlockDetails { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "BlockDetails", + "block", + &self.block, + "justifications", + &&self.justifications, + ) + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, T: Config> _serde::Deserialize<'de> for BlockDetails + where + T: Config, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "block" => _serde::__private::Ok(__Field::__field0), + "justifications" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"block" => _serde::__private::Ok(__Field::__field0), + b"justifications" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, T: Config> + where + T: Config, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, T: Config> _serde::de::Visitor<'de> + for __Visitor<'de, T> + where + T: Config, + { + type Value = BlockDetails; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct BlockDetails", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Block, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct BlockDetails with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Option>, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct BlockDetails with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(BlockDetails { + block: __field0, + justifications: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option> = _serde::__private::None; + let mut __field1: _serde::__private::Option< + Option>, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("block"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "justifications", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option>, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("block")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("justifications")? + } + }; + _serde::__private::Ok(BlockDetails { + block: __field0, + justifications: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "block", + "justifications", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "BlockDetails", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Block details in the [`BlockDetails`]. + pub struct Block { + /// The block header. + pub header: T::Header, + /// The accompanying extrinsics. + pub extrinsics: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for Block + where + T::Header: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Block", + "header", + &self.header, + "extrinsics", + &&self.extrinsics, + ) + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, T: Config> _serde::Deserialize<'de> for Block + where + T::Header: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "header" => _serde::__private::Ok(__Field::__field0), + "extrinsics" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"header" => _serde::__private::Ok(__Field::__field0), + b"extrinsics" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, T: Config> + where + T::Header: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, T: Config> _serde::de::Visitor<'de> + for __Visitor<'de, T> + where + T::Header: _serde::Deserialize<'de>, + { + type Value = Block; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct Block", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + T::Header, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Block with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Block with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(Block { + header: __field0, + extrinsics: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option> = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("header"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "extrinsics", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("header")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("extrinsics")? + } + }; + _serde::__private::Ok(Block { + header: __field0, + extrinsics: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "header", + "extrinsics", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Block", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// An abstraction over justification for a block's validity under a consensus algorithm. + pub type BlockJustification = (ConsensusEngineId, EncodedJustification); + /// Consensus engine unique ID. + pub type ConsensusEngineId = [u8; 4]; + /// The encoded justification specific to a consensus engine. + pub type EncodedJustification = Vec; + /// This contains the runtime version information necessary to make transactions, as obtained from + /// the RPC call `state_getRuntimeVersion`, + #[serde(rename_all = "camelCase")] + pub struct RuntimeVersion { + /// Version of the runtime specification. A full-node will not attempt to use its native + /// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, + /// `spec_version` and `authoring_version` are the same between Wasm and native. + pub spec_version: u32, + /// All existing dispatches are fully compatible when this number doesn't change. If this + /// number changes, then `spec_version` must change, also. + /// + /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, + /// either through an alteration in its user-level semantics, a parameter + /// added/removed/changed, a dispatchable being removed, a module being removed, or a + /// dispatchable/module changing its index. + /// + /// It need *not* change when a new module is added or when a dispatchable is added. + pub transaction_version: u32, + /// Fields unnecessary to Subxt are written out to this map. + #[serde(flatten)] + pub other: std::collections::HashMap, + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeVersion { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "RuntimeVersion", + "spec_version", + &self.spec_version, + "transaction_version", + &self.transaction_version, + "other", + &&self.other, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeVersion { + #[inline] + fn clone(&self) -> RuntimeVersion { + RuntimeVersion { + spec_version: ::core::clone::Clone::clone(&self.spec_version), + transaction_version: ::core::clone::Clone::clone( + &self.transaction_version, + ), + other: ::core::clone::Clone::clone(&self.other), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeVersion {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeVersion { + #[inline] + fn eq(&self, other: &RuntimeVersion) -> bool { + self.spec_version == other.spec_version + && self.transaction_version == other.transaction_version + && self.other == other.other + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeVersion { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq< + std::collections::HashMap, + >; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RuntimeVersion { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field<'de> { + __field0, + __field1, + __other(_serde::__private::de::Content<'de>), + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field<'de>; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_bool<__E>( + self, + __value: bool, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::Bool(__value), + ), + ) + } + fn visit_i8<__E>( + self, + __value: i8, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I8(__value), + ), + ) + } + fn visit_i16<__E>( + self, + __value: i16, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I16(__value), + ), + ) + } + fn visit_i32<__E>( + self, + __value: i32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I32(__value), + ), + ) + } + fn visit_i64<__E>( + self, + __value: i64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I64(__value), + ), + ) + } + fn visit_u8<__E>( + self, + __value: u8, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U8(__value), + ), + ) + } + fn visit_u16<__E>( + self, + __value: u16, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U16(__value), + ), + ) + } + fn visit_u32<__E>( + self, + __value: u32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U32(__value), + ), + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U64(__value), + ), + ) + } + fn visit_f32<__E>( + self, + __value: f32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::F32(__value), + ), + ) + } + fn visit_f64<__E>( + self, + __value: f64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::F64(__value), + ), + ) + } + fn visit_char<__E>( + self, + __value: char, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::Char(__value), + ), + ) + } + fn visit_unit<__E>( + self, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other(_serde::__private::de::Content::Unit), + ) + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "specVersion" => _serde::__private::Ok(__Field::__field0), + "transactionVersion" => { + _serde::__private::Ok(__Field::__field1) + } + _ => { + let __value = _serde::__private::de::Content::String( + _serde::__private::ToString::to_string(__value), + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"specVersion" => _serde::__private::Ok(__Field::__field0), + b"transactionVersion" => { + _serde::__private::Ok(__Field::__field1) + } + _ => { + let __value = _serde::__private::de::Content::ByteBuf( + __value.to_vec(), + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_borrowed_str<__E>( + self, + __value: &'de str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "specVersion" => _serde::__private::Ok(__Field::__field0), + "transactionVersion" => { + _serde::__private::Ok(__Field::__field1) + } + _ => { + let __value = _serde::__private::de::Content::Str(__value); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_borrowed_bytes<__E>( + self, + __value: &'de [u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"specVersion" => _serde::__private::Ok(__Field::__field0), + b"transactionVersion" => { + _serde::__private::Ok(__Field::__field1) + } + _ => { + let __value = _serde::__private::de::Content::Bytes( + __value, + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field<'de> { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = RuntimeVersion; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct RuntimeVersion", + ) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __collect = _serde::__private::Vec::< + _serde::__private::Option< + ( + _serde::__private::de::Content, + _serde::__private::de::Content, + ), + >, + >::new(); + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "specVersion", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "transactionVersion", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__other(__name) => { + __collect + .push( + _serde::__private::Some(( + __name, + _serde::de::MapAccess::next_value(&mut __map)?, + )), + ); + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("specVersion")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("transactionVersion")? + } + }; + let __field2: std::collections::HashMap< + String, + serde_json::Value, + > = _serde::de::Deserialize::deserialize( + _serde::__private::de::FlatMapDeserializer( + &mut __collect, + _serde::__private::PhantomData, + ), + )?; + _serde::__private::Ok(RuntimeVersion { + spec_version: __field0, + transaction_version: __field1, + other: __field2, + }) + } + } + _serde::Deserializer::deserialize_map( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Possible transaction status events. + /// + /// # Note + /// + /// This is copied from `sp-transaction-pool` to avoid a dependency on that crate. Therefore it + /// must be kept compatible with that type from the target substrate version. + #[serde(rename_all = "camelCase")] + pub enum TransactionStatus { + /// Transaction is part of the future queue. + Future, + /// Transaction is part of the ready queue. + Ready, + /// The transaction has been broadcast to the given peers. + Broadcast(Vec), + /// Transaction has been included in block with given hash. + InBlock(Hash), + /// The block this transaction was included in has been retracted. + Retracted(Hash), + /// Maximum number of finality watchers has been reached, + /// old watchers are being removed. + FinalityTimeout(Hash), + /// Transaction has been finalized by a finality-gadget, e.g GRANDPA + Finalized(Hash), + /// Transaction has been replaced in the pool, by another transaction + /// that provides the same tags. (e.g. same (sender, nonce)). + Usurped(Hash), + /// Transaction has been dropped from the pool because of the limit. + Dropped, + /// Transaction is no longer valid in the current state. + Invalid, + } + #[automatically_derived] + impl ::core::fmt::Debug + for TransactionStatus { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionStatus::Future => { + ::core::fmt::Formatter::write_str(f, "Future") + } + TransactionStatus::Ready => { + ::core::fmt::Formatter::write_str(f, "Ready") + } + TransactionStatus::Broadcast(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Broadcast", + &__self_0, + ) + } + TransactionStatus::InBlock(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InBlock", + &__self_0, + ) + } + TransactionStatus::Retracted(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Retracted", + &__self_0, + ) + } + TransactionStatus::FinalityTimeout(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "FinalityTimeout", + &__self_0, + ) + } + TransactionStatus::Finalized(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Finalized", + &__self_0, + ) + } + TransactionStatus::Usurped(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Usurped", + &__self_0, + ) + } + TransactionStatus::Dropped => { + ::core::fmt::Formatter::write_str(f, "Dropped") + } + TransactionStatus::Invalid => { + ::core::fmt::Formatter::write_str(f, "Invalid") + } + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for TransactionStatus + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __field6, + __field7, + __field8, + __field9, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + 5u64 => _serde::__private::Ok(__Field::__field5), + 6u64 => _serde::__private::Ok(__Field::__field6), + 7u64 => _serde::__private::Ok(__Field::__field7), + 8u64 => _serde::__private::Ok(__Field::__field8), + 9u64 => _serde::__private::Ok(__Field::__field9), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 10", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "future" => _serde::__private::Ok(__Field::__field0), + "ready" => _serde::__private::Ok(__Field::__field1), + "broadcast" => _serde::__private::Ok(__Field::__field2), + "inBlock" => _serde::__private::Ok(__Field::__field3), + "retracted" => _serde::__private::Ok(__Field::__field4), + "finalityTimeout" => { + _serde::__private::Ok(__Field::__field5) + } + "finalized" => _serde::__private::Ok(__Field::__field6), + "usurped" => _serde::__private::Ok(__Field::__field7), + "dropped" => _serde::__private::Ok(__Field::__field8), + "invalid" => _serde::__private::Ok(__Field::__field9), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"future" => _serde::__private::Ok(__Field::__field0), + b"ready" => _serde::__private::Ok(__Field::__field1), + b"broadcast" => _serde::__private::Ok(__Field::__field2), + b"inBlock" => _serde::__private::Ok(__Field::__field3), + b"retracted" => _serde::__private::Ok(__Field::__field4), + b"finalityTimeout" => { + _serde::__private::Ok(__Field::__field5) + } + b"finalized" => _serde::__private::Ok(__Field::__field6), + b"usurped" => _serde::__private::Ok(__Field::__field7), + b"dropped" => _serde::__private::Ok(__Field::__field8), + b"invalid" => _serde::__private::Ok(__Field::__field9), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "enum TransactionStatus", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(TransactionStatus::Future) + } + (__Field::__field1, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(TransactionStatus::Ready) + } + (__Field::__field2, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Vec, + >(__variant), + TransactionStatus::Broadcast, + ) + } + (__Field::__field3, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::InBlock, + ) + } + (__Field::__field4, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::Retracted, + ) + } + (__Field::__field5, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::FinalityTimeout, + ) + } + (__Field::__field6, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::Finalized, + ) + } + (__Field::__field7, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::Usurped, + ) + } + (__Field::__field8, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(TransactionStatus::Dropped) + } + (__Field::__field9, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(TransactionStatus::Invalid) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "future", + "ready", + "broadcast", + "inBlock", + "retracted", + "finalityTimeout", + "finalized", + "usurped", + "dropped", + "invalid", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "TransactionStatus", + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The decoded result returned from calling `system_dryRun` on some extrinsic. + pub enum DryRunResult { + /// The transaction could be included in the block and executed. + Success, + /// The transaction could be included in the block, but the call failed to dispatch. + DispatchError(crate::error::DispatchError), + /// The transaction could not be included in the block. + TransactionValidityError, + } + #[automatically_derived] + impl ::core::fmt::Debug for DryRunResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + DryRunResult::Success => { + ::core::fmt::Formatter::write_str(f, "Success") + } + DryRunResult::DispatchError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "DispatchError", + &__self_0, + ) + } + DryRunResult::TransactionValidityError => { + ::core::fmt::Formatter::write_str( + f, + "TransactionValidityError", + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DryRunResult {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DryRunResult { + #[inline] + fn eq(&self, other: &DryRunResult) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + DryRunResult::DispatchError(__self_0), + DryRunResult::DispatchError(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DryRunResult { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + /// The bytes representing an error dry running an extrinsic. call [`DryRunResultBytes::into_dry_run_result`] + /// to attempt to decode this into something more meaningful. + pub struct DryRunResultBytes(pub Vec); + impl DryRunResultBytes { + /// Attempt to decode the error bytes into a [`DryRunResult`] using the provided [`Metadata`]. + pub fn into_dry_run_result( + self, + metadata: &crate::metadata::Metadata, + ) -> Result { + let bytes = self.0; + if bytes[0] == 0 && bytes[1] == 0 { + Ok(DryRunResult::Success) + } else if bytes[0] == 0 && bytes[1] == 1 { + let dispatch_error = crate::error::DispatchError::decode_from( + &bytes[2..], + metadata.clone(), + )?; + Ok(DryRunResult::DispatchError(dispatch_error)) + } else if bytes[0] == 1 { + Ok(DryRunResult::TransactionValidityError) + } else { + Err(crate::Error::Unknown(bytes)) + } + } + } + /// Storage change set + #[serde(rename_all = "camelCase")] + pub struct StorageChangeSet { + /// Block hash + pub block: Hash, + /// A list of changes; tuples of storage key and optional storage data. + pub changes: Vec<(Bytes, Option)>, + } + #[automatically_derived] + impl ::core::clone::Clone + for StorageChangeSet { + #[inline] + fn clone(&self) -> StorageChangeSet { + StorageChangeSet { + block: ::core::clone::Clone::clone(&self.block), + changes: ::core::clone::Clone::clone(&self.changes), + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for StorageChangeSet + where + Hash: _serde::Serialize, + { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "StorageChangeSet", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "block", + &self.block, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "changes", + &self.changes, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for StorageChangeSet + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "block" => _serde::__private::Ok(__Field::__field0), + "changes" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"block" => _serde::__private::Ok(__Field::__field0), + b"changes" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + StorageChangeSet, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = StorageChangeSet; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct StorageChangeSet", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct StorageChangeSet with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec<(Bytes, Option)>, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct StorageChangeSet with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(StorageChangeSet { + block: __field0, + changes: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + Vec<(Bytes, Option)>, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("block"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "changes", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Vec<(Bytes, Option)>, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("block")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("changes")? + } + }; + _serde::__private::Ok(StorageChangeSet { + block: __field0, + changes: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["block", "changes"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "StorageChangeSet", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + StorageChangeSet, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageChangeSet {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for StorageChangeSet { + #[inline] + fn eq(&self, other: &StorageChangeSet) -> bool { + self.block == other.block && self.changes == other.changes + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageChangeSet { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq)>>; + } + } + #[automatically_derived] + impl ::core::fmt::Debug + for StorageChangeSet { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "StorageChangeSet", + "block", + &self.block, + "changes", + &&self.changes, + ) + } + } + /// Statistics of a block returned by the `dev_getBlockStats` RPC. + #[serde(rename_all = "camelCase")] + pub struct BlockStats { + /// The length in bytes of the storage proof produced by executing the block. + pub witness_len: u64, + /// The length in bytes of the storage proof after compaction. + pub witness_compact_len: u64, + /// Length of the block in bytes. + /// + /// This information can also be acquired by downloading the whole block. This merely + /// saves some complexity on the client side. + pub block_len: u64, + /// Number of extrinsics in the block. + /// + /// This information can also be acquired by downloading the whole block. This merely + /// saves some complexity on the client side. + pub num_extrinsics: u64, + } + #[automatically_derived] + impl ::core::clone::Clone for BlockStats { + #[inline] + fn clone(&self) -> BlockStats { + BlockStats { + witness_len: ::core::clone::Clone::clone(&self.witness_len), + witness_compact_len: ::core::clone::Clone::clone( + &self.witness_compact_len, + ), + block_len: ::core::clone::Clone::clone(&self.block_len), + num_extrinsics: ::core::clone::Clone::clone(&self.num_extrinsics), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for BlockStats { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "BlockStats", + "witness_len", + &self.witness_len, + "witness_compact_len", + &self.witness_compact_len, + "block_len", + &self.block_len, + "num_extrinsics", + &&self.num_extrinsics, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BlockStats {} + #[automatically_derived] + impl ::core::cmp::PartialEq for BlockStats { + #[inline] + fn eq(&self, other: &BlockStats) -> bool { + self.witness_len == other.witness_len + && self.witness_compact_len == other.witness_compact_len + && self.block_len == other.block_len + && self.num_extrinsics == other.num_extrinsics + } + } + #[automatically_derived] + impl ::core::cmp::Eq for BlockStats { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for BlockStats { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "BlockStats", + false as usize + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "witnessLen", + &self.witness_len, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "witnessCompactLen", + &self.witness_compact_len, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "blockLen", + &self.block_len, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "numExtrinsics", + &self.num_extrinsics, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for BlockStats { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "witnessLen" => _serde::__private::Ok(__Field::__field0), + "witnessCompactLen" => { + _serde::__private::Ok(__Field::__field1) + } + "blockLen" => _serde::__private::Ok(__Field::__field2), + "numExtrinsics" => _serde::__private::Ok(__Field::__field3), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"witnessLen" => _serde::__private::Ok(__Field::__field0), + b"witnessCompactLen" => { + _serde::__private::Ok(__Field::__field1) + } + b"blockLen" => _serde::__private::Ok(__Field::__field2), + b"numExtrinsics" => _serde::__private::Ok(__Field::__field3), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = BlockStats; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct BlockStats", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct BlockStats with 4 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct BlockStats with 4 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct BlockStats with 4 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct BlockStats with 4 elements", + ), + ); + } + }; + _serde::__private::Ok(BlockStats { + witness_len: __field0, + witness_compact_len: __field1, + block_len: __field2, + num_extrinsics: __field3, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option = _serde::__private::None; + let mut __field3: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "witnessLen", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "witnessCompactLen", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "blockLen", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private::Option::is_some(&__field3) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "numExtrinsics", + ), + ); + } + __field3 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("witnessLen")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("witnessCompactLen")? + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("blockLen")? + } + }; + let __field3 = match __field3 { + _serde::__private::Some(__field3) => __field3, + _serde::__private::None => { + _serde::__private::de::missing_field("numExtrinsics")? + } + }; + _serde::__private::Ok(BlockStats { + witness_len: __field0, + witness_compact_len: __field1, + block_len: __field2, + num_extrinsics: __field3, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "witnessLen", + "witnessCompactLen", + "blockLen", + "numExtrinsics", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "BlockStats", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// ReadProof struct returned by the RPC + /// + /// # Note + /// + /// This is copied from `sc-rpc-api` to avoid a dependency on that crate. Therefore it + /// must be kept compatible with that type from the target substrate version. + #[serde(rename_all = "camelCase")] + pub struct ReadProof { + /// Block hash used to generate the proof + pub at: Hash, + /// A proof used to prove that storage entries are included in the storage trie + pub proof: Vec, + } + #[automatically_derived] + impl ::core::clone::Clone for ReadProof { + #[inline] + fn clone(&self) -> ReadProof { + ReadProof { + at: ::core::clone::Clone::clone(&self.at), + proof: ::core::clone::Clone::clone(&self.proof), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ReadProof { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "ReadProof", + "at", + &self.at, + "proof", + &&self.proof, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ReadProof {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for ReadProof { + #[inline] + fn eq(&self, other: &ReadProof) -> bool { + self.at == other.at && self.proof == other.proof + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ReadProof { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ReadProof + where + Hash: _serde::Serialize, + { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "ReadProof", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "at", + &self.at, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "proof", + &self.proof, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for ReadProof + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "at" => _serde::__private::Ok(__Field::__field0), + "proof" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"at" => _serde::__private::Ok(__Field::__field0), + b"proof" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = ReadProof; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct ReadProof", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ReadProof with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct ReadProof with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(ReadProof { + at: __field0, + proof: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option> = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("at"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("proof"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("at")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("proof")? + } + }; + _serde::__private::Ok(ReadProof { + at: __field0, + proof: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["at", "proof"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ReadProof", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// A number type that can be serialized both as a number or a string that encodes a number in a + /// string. + /// + /// We allow two representations of the block number as input. Either we deserialize to the type + /// that is specified in the block type or we attempt to parse given hex value. + /// + /// The primary motivation for having this type is to avoid overflows when using big integers in + /// JavaScript (which we consider as an important RPC API consumer). + #[serde(untagged)] + pub enum NumberOrHex { + /// The number represented directly. + Number(u64), + /// Hex representation of the number. + Hex(U256), + } + #[automatically_derived] + impl ::core::marker::Copy for NumberOrHex {} + #[automatically_derived] + impl ::core::clone::Clone for NumberOrHex { + #[inline] + fn clone(&self) -> NumberOrHex { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for NumberOrHex { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + NumberOrHex::Number(ref __field0) => { + _serde::Serialize::serialize(__field0, __serializer) + } + NumberOrHex::Hex(ref __field0) => { + _serde::Serialize::serialize(__field0, __serializer) + } + } + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for NumberOrHex { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + let __content = <_serde::__private::de::Content as _serde::Deserialize>::deserialize( + __deserializer, + )?; + let __deserializer = _serde::__private::de::ContentRefDeserializer::< + __D::Error, + >::new(&__content); + if let _serde::__private::Ok(__ok) + = _serde::__private::Result::map( + ::deserialize(__deserializer), + NumberOrHex::Number, + ) { + return _serde::__private::Ok(__ok); + } + if let _serde::__private::Ok(__ok) + = _serde::__private::Result::map( + ::deserialize(__deserializer), + NumberOrHex::Hex, + ) { + return _serde::__private::Ok(__ok); + } + _serde::__private::Err( + _serde::de::Error::custom( + "data did not match any variant of untagged enum NumberOrHex", + ), + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for NumberOrHex { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + NumberOrHex::Number(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Number", + &__self_0, + ) + } + NumberOrHex::Hex(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Hex", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for NumberOrHex {} + #[automatically_derived] + impl ::core::cmp::PartialEq for NumberOrHex { + #[inline] + fn eq(&self, other: &NumberOrHex) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + NumberOrHex::Number(__self_0), + NumberOrHex::Number(__arg1_0), + ) => *__self_0 == *__arg1_0, + (NumberOrHex::Hex(__self_0), NumberOrHex::Hex(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for NumberOrHex { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + impl NumberOrHex { + /// Converts this number into an U256. + pub fn into_u256(self) -> U256 { + match self { + NumberOrHex::Number(n) => n.into(), + NumberOrHex::Hex(h) => h, + } + } + } + impl From for U256 { + fn from(num_or_hex: NumberOrHex) -> U256 { + num_or_hex.into_u256() + } + } + impl From for NumberOrHex { + fn from(x: u8) -> Self { + NumberOrHex::Number(x.into()) + } + } + impl From for NumberOrHex { + fn from(x: u16) -> Self { + NumberOrHex::Number(x.into()) + } + } + impl From for NumberOrHex { + fn from(x: u32) -> Self { + NumberOrHex::Number(x.into()) + } + } + impl From for NumberOrHex { + fn from(x: u64) -> Self { + NumberOrHex::Number(x.into()) + } + } + impl From for NumberOrHex { + fn from(n: u128) -> Self { + NumberOrHex::Hex(n.into()) + } + } + impl From for NumberOrHex { + fn from(n: U256) -> Self { + NumberOrHex::Hex(n) + } + } + /// A quick helper to encode some bytes to hex. + fn to_hex(bytes: impl AsRef<[u8]>) -> String { + { + let res = ::alloc::fmt::format( + format_args!("0x{0}", hex::encode(bytes.as_ref())), + ); + res + } + } + /// Hex-serialized shim for `Vec`. + pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec); + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Bytes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Bytes { + #[inline] + fn eq(&self, other: &Bytes) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Bytes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Bytes { + #[inline] + fn clone(&self) -> Bytes { + Bytes(::core::clone::Clone::clone(&self.0)) + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Bytes { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "Bytes", + { + #[doc(hidden)] + struct __SerializeWith<'__a> { + values: (&'__a Vec,), + phantom: _serde::__private::PhantomData, + } + impl<'__a> _serde::Serialize for __SerializeWith<'__a> { + fn serialize<__S>( + &self, + __s: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + impl_serde::serialize::serialize(self.values.0, __s) + } + } + &__SerializeWith { + values: (&self.0,), + phantom: _serde::__private::PhantomData::, + } + }, + ) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Bytes { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Bytes; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "tuple struct Bytes", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: Vec = impl_serde::serialize::deserialize( + __e, + )?; + _serde::__private::Ok(Bytes(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match { + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: Vec, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: impl_serde::serialize::deserialize(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct Bytes with 1 element", + ), + ); + } + }; + _serde::__private::Ok(Bytes(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "Bytes", + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::hash::Hash for Bytes { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Bytes { + #[inline] + fn partial_cmp( + &self, + other: &Bytes, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Bytes { + #[inline] + fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Bytes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Bytes", + &&self.0, + ) + } + } + impl std::ops::Deref for Bytes { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.0[..] + } + } + impl From> for Bytes { + fn from(s: Vec) -> Self { + Bytes(s) + } + } + } + use self::rpc_methods::TransactionStatus as RpcTransactionStatus; + use crate::backend::{ + rpc::RpcClient, Backend, BlockRef, RuntimeVersion, StorageResponse, StreamOf, + StreamOfResults, TransactionStatus, + }; + use crate::{config::Header, Config, Error}; + use async_trait::async_trait; + use futures::{ + future, future::Either, stream, Future, FutureExt, Stream, StreamExt, + }; + use std::collections::VecDeque; + use std::pin::Pin; + use std::task::{Context, Poll}; + pub use rpc_methods::LegacyRpcMethods; + /// The legacy backend. + pub struct LegacyBackend { + methods: LegacyRpcMethods, + } + #[automatically_derived] + impl ::core::fmt::Debug for LegacyBackend { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "LegacyBackend", + "methods", + &&self.methods, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for LegacyBackend { + #[inline] + fn clone(&self) -> LegacyBackend { + LegacyBackend { + methods: ::core::clone::Clone::clone(&self.methods), + } + } + } + impl LegacyBackend { + /// Instantiate a new backend which uses the legacy API methods. + pub fn new(client: RpcClient) -> Self { + Self { + methods: LegacyRpcMethods::new(client), + } + } + } + impl super::sealed::Sealed for LegacyBackend {} + impl Backend for LegacyBackend { + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_values<'life0, 'async_trait>( + &'life0 self, + keys: Vec>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let keys = keys; + let at = at; + let __ret: Result, Error> = { + let methods = __self.methods.clone(); + let iter = keys + .into_iter() + .map(move |key| { + let methods = methods.clone(); + async move { + let res = methods.state_get_storage(&key, Some(at)).await?; + Ok(res.map(|value| StorageResponse { key, value })) + } + }); + let s = stream::iter(iter) + .then(|fut| fut) + .filter_map(|r| future::ready(r.transpose())); + Ok(StreamOf(Box::pin(s))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_descendant_keys<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>, Error>, + > { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result>, Error> = { + let keys = StorageFetchDescendantKeysStream { + at, + key, + methods: __self.methods.clone(), + done: Default::default(), + keys_fut: Default::default(), + pagination_start_key: None, + }; + let keys = keys + .flat_map(|keys| { + match keys { + Err(e) => { + Either::Left(stream::iter(std::iter::once(Err(e)))) + } + Ok(keys) => { + Either::Right(stream::iter(keys.into_iter().map(Ok))) + } + } + }); + Ok(StreamOf(Box::pin(keys))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_descendant_values<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result, Error> = { + let keys_stream = StorageFetchDescendantKeysStream { + at, + key, + methods: __self.methods.clone(), + done: Default::default(), + keys_fut: Default::default(), + pagination_start_key: None, + }; + Ok( + StreamOf( + Box::pin(StorageFetchDescendantValuesStream { + keys: keys_stream, + results_fut: None, + results: Default::default(), + }), + ), + ) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn genesis_hash<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let __ret: Result = { + __self.methods.genesis_hash().await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn block_header<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result, Error> = { + __self.methods.chain_get_header(Some(at)).await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn block_body<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>>, Error>, + > { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result>>, Error> = { + let Some(details) = __self + .methods + .chain_get_block(Some(at)) + .await? else { return Ok(None); + }; + Ok( + Some( + details.block.extrinsics.into_iter().map(|b| b.0).collect(), + ), + ) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn latest_finalized_block_ref<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result, Error> = { + let hash = __self.methods.chain_get_finalized_head().await?; + Ok(BlockRef::from_hash(hash)) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn current_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let __ret: Result = { + let details = __self + .methods + .state_get_runtime_version(None) + .await?; + Ok(RuntimeVersion { + spec_version: details.spec_version, + transaction_version: details.transaction_version, + }) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result, Error> = { + let sub = __self + .methods + .state_subscribe_runtime_version() + .await?; + let sub = sub + .map(|r| { + r.map(|v| RuntimeVersion { + spec_version: v.spec_version, + transaction_version: v.transaction_version, + }) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_all_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + let sub = __self.methods.chain_subscribe_all_heads().await?; + let sub = sub + .map(|r| { + r.map(|h| { + let hash = h.hash(); + (h, BlockRef::from_hash(hash)) + }) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_best_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + let sub = __self.methods.chain_subscribe_new_heads().await?; + let sub = sub + .map(|r| { + r.map(|h| { + let hash = h.hash(); + (h, BlockRef::from_hash(hash)) + }) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_finalized_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + let sub: super::rpc::RpcSubscription<::Header> = __self + .methods + .chain_subscribe_finalized_heads() + .await?; + let last_finalized_block_ref = __self + .latest_finalized_block_ref() + .await?; + let last_finalized_block_num = __self + .block_header(last_finalized_block_ref.hash()) + .await? + .map(|h| h.number().into()); + let sub = subscribe_to_block_headers_filling_in_gaps( + __self.methods.clone(), + sub, + last_finalized_block_num, + ); + let sub = sub + .map(|r| { + r.map(|h| { + let hash = h.hash(); + (h, BlockRef::from_hash(hash)) + }) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn submit_transaction<'life0, 'life1, 'async_trait>( + &'life0 self, + extrinsic: &'life1 [u8], + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults>, + Error, + > = { + let sub = __self + .methods + .author_submit_and_watch_extrinsic(extrinsic) + .await?; + let sub = sub + .filter_map(|r| { + let mapped = r + .map(|tx| { + match tx { + RpcTransactionStatus::Future => None, + RpcTransactionStatus::Retracted(_) => None, + RpcTransactionStatus::Ready => { + Some(TransactionStatus::Validated) + } + RpcTransactionStatus::Broadcast(peers) => { + Some(TransactionStatus::Broadcasted { + num_peers: peers.len() as u32, + }) + } + RpcTransactionStatus::InBlock(hash) => { + Some(TransactionStatus::InBestBlock { + hash: BlockRef::from_hash(hash), + }) + } + RpcTransactionStatus::FinalityTimeout(_) => { + Some(TransactionStatus::Invalid { + message: "Finality timeout".into(), + }) + } + RpcTransactionStatus::Finalized(hash) => { + Some(TransactionStatus::InFinalizedBlock { + hash: BlockRef::from_hash(hash), + }) + } + RpcTransactionStatus::Usurped(_) => { + Some(TransactionStatus::Invalid { + message: "Transaction was usurped by another with the same nonce" + .into(), + }) + } + RpcTransactionStatus::Dropped => { + Some(TransactionStatus::Dropped { + message: "Transaction was dropped".into(), + }) + } + RpcTransactionStatus::Invalid => { + Some(TransactionStatus::Invalid { + message: "Transaction is invalid (eg because of a bad nonce, signature etc)" + .into(), + }) + } + } + }) + .transpose(); + future::ready(mapped) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn call<'life0, 'life1, 'life2, 'async_trait>( + &'life0 self, + method: &'life1 str, + call_parameters: Option<&'life2 [u8]>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + 'life2: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::, Error>> { + return __ret; + } + let __self = self; + let call_parameters = call_parameters; + let at = at; + let __ret: Result, Error> = { + __self + .methods + .state_call(method, call_parameters, Some(at)) + .await + }; + #[allow(unreachable_code)] __ret + }) + } + } + /// Note: This is exposed for testing but is not considered stable and may change + /// without notice in a patch release. + #[doc(hidden)] + pub fn subscribe_to_block_headers_filling_in_gaps( + methods: LegacyRpcMethods, + sub: S, + mut last_block_num: Option, + ) -> impl Stream> + Send + where + T: Config, + S: Stream> + Send, + E: Into + Send + 'static, + { + sub.flat_map(move |s| { + let header = match s { + Ok(header) => header, + Err(e) => return Either::Left(stream::once(async { Err(e.into()) })), + }; + let end_block_num = header.number().into(); + let start_block_num = last_block_num + .map(|n| n + 1) + .unwrap_or(end_block_num); + let methods = methods.clone(); + let previous_headers = stream::iter(start_block_num..end_block_num) + .then(move |n| { + let methods = methods.clone(); + async move { + let hash = methods + .chain_get_block_hash(Some(n.into())) + .await?; + let header = methods.chain_get_header(hash).await?; + Ok::<_, Error>(header) + } + }) + .filter_map(|h| async { h.transpose() }); + last_block_num = Some(end_block_num); + Either::Right(previous_headers.chain(stream::once(async { Ok(header) }))) + }) + } + /// How many keys/values to fetch at once. + const STORAGE_PAGE_SIZE: u32 = 32; + /// This provides a stream of values given some prefix `key`. It + /// internally manages pagination and such. + #[allow(clippy::type_complexity)] + pub struct StorageFetchDescendantKeysStream { + methods: LegacyRpcMethods, + key: Vec, + at: T::Hash, + pagination_start_key: Option>, + keys_fut: Option< + Pin< + Box< + dyn Future>, Error>> + Send + 'static, + >, + >, + >, + done: bool, + } + impl std::marker::Unpin for StorageFetchDescendantKeysStream {} + impl Stream for StorageFetchDescendantKeysStream { + type Item = Result>, Error>; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let mut this = self.as_mut(); + loop { + if this.done { + return Poll::Ready(None); + } + if let Some(mut keys_fut) = this.keys_fut.take() { + let Poll::Ready(keys) = keys_fut.poll_unpin(cx) else { + this.keys_fut = Some(keys_fut); + return Poll::Pending; + }; + match keys { + Ok(keys) => { + if keys.is_empty() { + this.done = true; + return Poll::Ready(None); + } + this.pagination_start_key = keys.last().cloned(); + return Poll::Ready(Some(Ok(keys))); + } + Err(e) => { + return Poll::Ready(Some(Err(e))); + } + } + } + let methods = this.methods.clone(); + let key = this.key.clone(); + let at = this.at; + let pagination_start_key = this.pagination_start_key.take(); + let keys_fut = async move { + methods + .state_get_keys_paged( + &key, + STORAGE_PAGE_SIZE, + pagination_start_key.as_deref(), + Some(at), + ) + .await + }; + this.keys_fut = Some(Box::pin(keys_fut)); + } + } + } + /// This provides a stream of values given some stream of keys. + #[allow(clippy::type_complexity)] + pub struct StorageFetchDescendantValuesStream { + keys: StorageFetchDescendantKeysStream, + results_fut: Option< + Pin< + Box< + dyn Future< + Output = Result, Vec)>>, Error>, + > + Send + 'static, + >, + >, + >, + results: VecDeque<(Vec, Vec)>, + } + impl Stream for StorageFetchDescendantValuesStream { + type Item = Result; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let mut this = self.as_mut(); + loop { + if let Some((key, value)) = this.results.pop_front() { + let res = StorageResponse { key, value }; + return Poll::Ready(Some(Ok(res))); + } + if let Some(mut results_fut) = this.results_fut.take() { + match results_fut.poll_unpin(cx) { + Poll::Ready(Ok(Some(results))) => { + this.results = results; + continue; + } + Poll::Ready(Ok(None)) => { + continue; + } + Poll::Ready(Err(e)) => return Poll::Ready(Some(Err(e))), + Poll::Pending => { + this.results_fut = Some(results_fut); + return Poll::Pending; + } + } + } + match this.keys.poll_next_unpin(cx) { + Poll::Ready(Some(Ok(keys))) => { + let methods = this.keys.methods.clone(); + let at = this.keys.at; + let results_fut = async move { + let keys = keys.iter().map(|k| &**k); + let values = methods + .state_query_storage_at(keys, Some(at)) + .await?; + let values: VecDeque<_> = values + .into_iter() + .flat_map(|v| { + v.changes + .into_iter() + .filter_map(|(k, v)| { + let v = v?; + Some((k.0, v.0)) + }) + }) + .collect(); + Ok(Some(values)) + }; + this.results_fut = Some(Box::pin(results_fut)); + continue; + } + Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(e))), + Poll::Ready(None) => return Poll::Ready(None), + Poll::Pending => return Poll::Pending, + } + } + } + } + } + pub mod rpc { + //! RPC types and client for interacting with a substrate node. + //! + //! These are used behind the scenes by Subxt backend implementations, for + //! example [`crate::backend::legacy::LegacyBackend`]. If you need an RPC client, + //! then you can manually instantiate one, and then hand it to Subxt if you'd like + //! to re-use it for the Subxt connection. + //! + //! - [`RpcClientT`] is the underlying dynamic RPC implementation. This provides + //! the low level [`RpcClientT::request_raw`] and [`RpcClientT::subscribe_raw`] + //! methods. + //! - [`RpcClient`] is the higher level wrapper around this, offering + //! the [`RpcClient::request`] and [`RpcClient::subscribe`] methods. + //! + //! # Example + //! + //! Fetching the genesis hash. + //! + //! ```no_run + //! # #[tokio::main] + //! # async fn main() { + //! use subxt::{ + //! client::OnlineClient, + //! config::SubstrateConfig, + //! backend::rpc::RpcClient, + //! backend::legacy::LegacyRpcMethods, + //! }; + //! + //! // Instantiate a default RPC client pointing at some URL. + //! let rpc_client = RpcClient::from_url("ws://localhost:9944") + //! .await + //! .unwrap(); + //! + //! // Instantiate the legacy RPC interface, providing an appropriate + //! // config so that it uses the correct types for your chain. + //! let rpc_methods = LegacyRpcMethods::::new(rpc_client.clone()); + //! + //! // Use it to make RPC calls, here using the legacy genesis_hash method. + //! let genesis_hash = rpc_methods + //! .genesis_hash() + //! .await + //! .unwrap(); + //! + //! println!("{genesis_hash}"); + //! + //! // Instantiate the Subxt interface using the same client and config if you + //! // want to reuse the same connection: + //! let client = OnlineClient::::from_rpc_client(rpc_client); + //! # } + //! ``` + #![allow(clippy::module_inception)] + #[cfg(feature = "jsonrpsee")] + mod jsonrpsee_impl { + use super::{RawRpcFuture, RawRpcSubscription, RpcClientT}; + use crate::error::RpcError; + use futures::stream::{StreamExt, TryStreamExt}; + use jsonrpsee::{ + core::{ + client::{Client, ClientT, SubscriptionClientT, SubscriptionKind}, + traits::ToRpcParams, + }, + types::SubscriptionId, + }; + use serde_json::value::RawValue; + struct Params(Option>); + impl ToRpcParams for Params { + fn to_rpc_params( + self, + ) -> Result>, serde_json::Error> { + Ok(self.0) + } + } + impl RpcClientT for Client { + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box> { + Box::pin(async move { + let res = ClientT::request(self, method, Params(params)) + .await + .map_err(|e| RpcError::ClientError(Box::new(e)))?; + Ok(res) + }) + } + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription> { + Box::pin(async move { + let stream = SubscriptionClientT::subscribe::< + Box, + _, + >(self, sub, Params(params), unsub) + .await + .map_err(|e| RpcError::ClientError(Box::new(e)))?; + let id = match stream.kind() { + SubscriptionKind::Subscription(SubscriptionId::Str(id)) => { + Some(id.clone().into_owned()) + } + _ => None, + }; + let stream = stream + .map_err(|e| RpcError::ClientError(Box::new(e))) + .boxed(); + Ok(RawRpcSubscription { stream, id }) + }) + } + } + } + mod rpc_client { + use super::{RawRpcSubscription, RpcClientT}; + use crate::error::Error; + use futures::{Stream, StreamExt}; + use serde::{de::DeserializeOwned, Serialize}; + use serde_json::value::RawValue; + use std::{pin::Pin, sync::Arc, task::Poll}; + /// A concrete wrapper around an [`RpcClientT`] which provides some higher level helper methods, + /// is cheaply cloneable, and can be handed to things like [`crate::client::OnlineClient`] to + /// instantiate it. + pub struct RpcClient { + client: Arc, + } + #[automatically_derived] + impl ::core::clone::Clone for RpcClient { + #[inline] + fn clone(&self) -> RpcClient { + RpcClient { + client: ::core::clone::Clone::clone(&self.client), + } + } + } + impl RpcClient { + #[cfg(feature = "jsonrpsee")] + /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. + /// + /// Errors if an insecure URL is provided. In this case, use [`RpcClient::from_insecure_url`] instead. + pub async fn from_url>(url: U) -> Result { + crate::utils::validate_url_is_secure(url.as_ref())?; + RpcClient::from_insecure_url(url).await + } + #[cfg(feature = "jsonrpsee")] + /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. + /// + /// Allows insecure URLs without SSL encryption, e.g. (http:// and ws:// URLs). + pub async fn from_insecure_url>( + url: U, + ) -> Result { + let client = jsonrpsee_helpers::client(url.as_ref()) + .await + .map_err(|e| crate::error::RpcError::ClientError(Box::new(e)))?; + Ok(Self::new(client)) + } + /// Create a new [`RpcClient`] from an arbitrary [`RpcClientT`] implementation. + pub fn new(client: R) -> Self { + RpcClient { + client: Arc::new(client), + } + } + /// Make an RPC request, given a method name and some parameters. + /// + /// See [`RpcParams`] and the [`rpc_params!`] macro for an example of how to + /// construct the parameters. + pub async fn request( + &self, + method: &str, + params: RpcParams, + ) -> Result { + let res = self.client.request_raw(method, params.build()).await?; + let val = serde_json::from_str(res.get())?; + Ok(val) + } + /// Subscribe to an RPC endpoint, providing the parameters and the method to call to + /// unsubscribe from it again. + /// + /// See [`RpcParams`] and the [`rpc_params!`] macro for an example of how to + /// construct the parameters. + pub async fn subscribe( + &self, + sub: &str, + params: RpcParams, + unsub: &str, + ) -> Result, Error> { + let sub = self + .client + .subscribe_raw(sub, params.build(), unsub) + .await?; + Ok(RpcSubscription::new(sub)) + } + } + impl std::fmt::Debug for RpcClient { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("RpcClient").finish() + } + } + impl std::ops::Deref for RpcClient { + type Target = dyn RpcClientT; + fn deref(&self) -> &Self::Target { + &*self.client + } + } + pub use rpc_params; + /// This represents the parameters passed to an [`RpcClient`], and exists to + /// enforce that parameters are provided in the correct format. + /// + /// Prefer to use the [`rpc_params!`] macro for simpler creation of these. + /// + /// # Example + /// + /// ```rust + /// use subxt::backend::rpc::RpcParams; + /// + /// let mut params = RpcParams::new(); + /// params.push(1).unwrap(); + /// params.push(true).unwrap(); + /// params.push("foo").unwrap(); + /// + /// assert_eq!(params.build().unwrap().get(), "[1,true,\"foo\"]"); + /// ``` + pub struct RpcParams(Vec); + #[automatically_derived] + impl ::core::fmt::Debug for RpcParams { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "RpcParams", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RpcParams { + #[inline] + fn clone(&self) -> RpcParams { + RpcParams(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::default::Default for RpcParams { + #[inline] + fn default() -> RpcParams { + RpcParams(::core::default::Default::default()) + } + } + impl RpcParams { + /// Create a new empty set of [`RpcParams`]. + pub fn new() -> Self { + Self(Vec::new()) + } + /// Push a parameter into our [`RpcParams`]. This serializes it to JSON + /// in the process, and so will return an error if this is not possible. + pub fn push(&mut self, param: P) -> Result<(), Error> { + if self.0.is_empty() { + self.0.push(b'['); + } else { + self.0.push(b',') + } + serde_json::to_writer(&mut self.0, ¶m)?; + Ok(()) + } + /// Build a [`RawValue`] from our params, returning `None` if no parameters + /// were provided. + pub fn build(mut self) -> Option> { + if self.0.is_empty() { + None + } else { + self.0.push(b']'); + let s = unsafe { String::from_utf8_unchecked(self.0) }; + Some(RawValue::from_string(s).expect("Should be valid JSON")) + } + } + } + /// A generic RPC Subscription. This implements [`Stream`], and so most of + /// the functionality you'll need to interact with it comes from the + /// [`StreamExt`] extension trait. + pub struct RpcSubscription { + inner: RawRpcSubscription, + _marker: std::marker::PhantomData, + } + impl std::fmt::Debug for RpcSubscription { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("RpcSubscription") + .field("inner", &"RawRpcSubscription") + .field("_marker", &self._marker) + .finish() + } + } + impl RpcSubscription { + /// Creates a new [`RpcSubscription`]. + pub fn new(inner: RawRpcSubscription) -> Self { + Self { + inner, + _marker: std::marker::PhantomData, + } + } + /// Obtain the ID associated with this subscription. + pub fn subscription_id(&self) -> Option<&str> { + self.inner.id.as_deref() + } + } + impl RpcSubscription { + /// Returns the next item in the stream. This is just a wrapper around + /// [`StreamExt::next()`] so that you can avoid the extra import. + pub async fn next(&mut self) -> Option> { + StreamExt::next(self).await + } + } + impl std::marker::Unpin for RpcSubscription {} + impl Stream for RpcSubscription { + type Item = Result; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let res = match self.inner.stream.poll_next_unpin(cx) { + ::futures_core::task::Poll::Ready(t) => t, + ::futures_core::task::Poll::Pending => { + return ::futures_core::task::Poll::Pending; + } + }; + let res = res + .map(|r| { + r.map_err(|e| e.into()) + .and_then(|raw_val| { + serde_json::from_str(raw_val.get()).map_err(|e| e.into()) + }) + }); + Poll::Ready(res) + } + } + #[cfg(all(feature = "jsonrpsee", feature = "native"))] + mod jsonrpsee_helpers { + pub use jsonrpsee::{ + client_transport::ws::{ + self, EitherStream, Url, WsTransportClientBuilder, + }, + core::client::{Client, Error}, + }; + use tokio_util::compat::Compat; + pub type Sender = ws::Sender>; + pub type Receiver = ws::Receiver>; + /// Build WS RPC client from URL + pub async fn client(url: &str) -> Result { + let (sender, receiver) = ws_transport(url).await?; + Ok( + Client::builder() + .max_buffer_capacity_per_subscription(4096) + .build_with_tokio(sender, receiver), + ) + } + async fn ws_transport(url: &str) -> Result<(Sender, Receiver), Error> { + let url = Url::parse(url).map_err(|e| Error::Transport(e.into()))?; + WsTransportClientBuilder::default() + .build(url) + .await + .map_err(|e| Error::Transport(e.into())) + } + } + } + mod rpc_client_t { + use crate::error::RpcError; + use futures::Stream; + use std::{future::Future, pin::Pin}; + pub use serde_json::value::RawValue; + /// A trait describing low level JSON-RPC interactions. Implementations of this can be + /// used to instantiate a [`super::RpcClient`], which can be passed to [`crate::OnlineClient`] + /// or used for lower level RPC calls via eg [`crate::backend::legacy::LegacyRpcMethods`]. + /// + /// This is a low level interface whose methods expect an already-serialized set of params, + /// and return an owned but still-serialized [`RawValue`], deferring deserialization to + /// the caller. This is the case because we want the methods to be object-safe (which prohibits + /// generics), and want to avoid any unnecessary allocations in serializing/deserializing + /// parameters. + /// + /// # Panics + /// + /// Implementations are free to panic if the `RawValue`'s passed to `request_raw` or + /// `subscribe_raw` are not JSON arrays. Internally, we ensure that this is always the case. + pub trait RpcClientT: Send + Sync + 'static { + /// Make a raw request for which we expect a single response back from. Implementations + /// should expect that the params will either be `None`, or be an already-serialized + /// JSON array of parameters. + /// + /// See [`super::RpcParams`] and the [`super::rpc_params!`] macro for an example of how to + /// construct the parameters. + /// + /// Prefer to use the interface provided on [`super::RpcClient`] where possible. + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box>; + /// Subscribe to some method. Implementations should expect that the params will + /// either be `None`, or be an already-serialized JSON array of parameters. + /// + /// See [`super::RpcParams`] and the [`super::rpc_params!`] macro for an example of how to + /// construct the parameters. + /// + /// Prefer to use the interface provided on [`super::RpcClient`] where possible. + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription>; + } + /// A boxed future that is returned from the [`RpcClientT`] methods. + pub type RawRpcFuture<'a, T> = Pin< + Box> + Send + 'a>, + >; + /// The RPC subscription returned from [`RpcClientT`]'s `subscription` method. + pub struct RawRpcSubscription { + /// The subscription stream. + pub stream: Pin< + Box< + dyn Stream< + Item = Result, RpcError>, + > + Send + 'static, + >, + >, + /// The ID associated with the subscription. + pub id: Option, + } + impl RpcClientT for std::sync::Arc { + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box> { + (**self).request_raw(method, params) + } + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription> { + (**self).subscribe_raw(sub, params, unsub) + } + } + impl RpcClientT for Box { + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box> { + (**self).request_raw(method, params) + } + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription> { + (**self).subscribe_raw(sub, params, unsub) + } + } + } + pub use rpc_client::{rpc_params, RpcClient, RpcParams, RpcSubscription}; + pub use rpc_client_t::{RawRpcFuture, RawRpcSubscription, RawValue, RpcClientT}; + } + pub mod unstable { + //! This module will expose a backend implementation based on the new APIs + //! described at . See + //! [`rpc_methods`] for the raw API calls. + //! + //! # Warning + //! + //! Everything in this module is **unstable**, meaning that it could change without + //! warning at any time. + mod follow_stream { + use super::rpc_methods::{FollowEvent, UnstableRpcMethods}; + use crate::config::Config; + use crate::error::Error; + use futures::{FutureExt, Stream, StreamExt}; + use std::future::Future; + use std::pin::Pin; + use std::task::{Context, Poll}; + /// A `Stream` whose goal is to remain subscribed to `chainHead_follow`. It will re-subscribe if the subscription + /// is ended for any reason, and it will return the current `subscription_id` as an event, along with the other + /// follow events. + pub struct FollowStream { + stream_getter: FollowEventStreamGetter, + stream: InnerStreamState, + } + impl std::fmt::Debug for FollowStream { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("FollowStream") + .field("stream_getter", &"..") + .field("stream", &self.stream) + .finish() + } + } + /// A getter function that returns an [`FollowEventStreamFut`]. + pub type FollowEventStreamGetter = Box< + dyn FnMut() -> FollowEventStreamFut + Send, + >; + /// The future which will return a stream of follow events and the subscription ID for it. + pub type FollowEventStreamFut = Pin< + Box< + dyn Future< + Output = Result<(FollowEventStream, String), Error>, + > + Send + 'static, + >, + >; + /// The stream of follow events. + pub type FollowEventStream = Pin< + Box, Error>> + Send + 'static>, + >; + /// Either a ready message with the current subscription ID, or + /// an event from the stream itself. + pub enum FollowStreamMsg { + /// The stream is ready (and has a subscription ID) + Ready(String), + /// An event from the stream. + Event(FollowEvent), + } + #[automatically_derived] + impl ::core::fmt::Debug for FollowStreamMsg { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + FollowStreamMsg::Ready(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Ready", + &__self_0, + ) + } + FollowStreamMsg::Event(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Event", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone + for FollowStreamMsg { + #[inline] + fn clone(&self) -> FollowStreamMsg { + match self { + FollowStreamMsg::Ready(__self_0) => { + FollowStreamMsg::Ready(::core::clone::Clone::clone(__self_0)) + } + FollowStreamMsg::Event(__self_0) => { + FollowStreamMsg::Event(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for FollowStreamMsg {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for FollowStreamMsg { + #[inline] + fn eq(&self, other: &FollowStreamMsg) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + FollowStreamMsg::Ready(__self_0), + FollowStreamMsg::Ready(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowStreamMsg::Event(__self_0), + FollowStreamMsg::Event(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for FollowStreamMsg { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + impl FollowStreamMsg { + /// Return an event, or none if the message is a "ready" one. + pub fn into_event(self) -> Option> { + match self { + FollowStreamMsg::Ready(_) => None, + FollowStreamMsg::Event(e) => Some(e), + } + } + } + enum InnerStreamState { + /// We've just created the stream; we'll start Initializing it + New, + /// We're fetching the inner subscription. Move to Ready when we have one. + Initializing(FollowEventStreamFut), + /// Report back the subscription ID here, and then start ReceivingEvents. + Ready(Option<(FollowEventStream, String)>), + /// We are polling for, and receiving events from the stream. + ReceivingEvents(FollowEventStream), + /// We received a stop event. We'll send one on and restart the stream. + Stopped, + /// The stream is finished and will not restart (likely due to an error). + Finished, + } + impl std::fmt::Debug for InnerStreamState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::New => f.write_fmt(format_args!("New")), + Self::Initializing(_) => { + f.write_fmt(format_args!("Initializing(..)")) + } + Self::Ready(_) => f.write_fmt(format_args!("Ready(..)")), + Self::ReceivingEvents(_) => { + f.write_fmt(format_args!("ReceivingEvents(..)")) + } + Self::Stopped => f.write_fmt(format_args!("Stopped")), + Self::Finished => f.write_fmt(format_args!("Finished")), + } + } + } + impl FollowStream { + /// Create a new [`FollowStream`] given a function which returns the stream. + pub fn new(stream_getter: FollowEventStreamGetter) -> Self { + Self { + stream_getter, + stream: InnerStreamState::New, + } + } + /// Create a new [`FollowStream`] given the RPC methods. + pub fn from_methods( + methods: UnstableRpcMethods, + ) -> FollowStream { + FollowStream { + stream_getter: Box::new(move || { + let methods = methods.clone(); + Box::pin(async move { + let stream = methods.chainhead_unstable_follow(true).await?; + let Some(sub_id) = stream + .subscription_id() + .map(ToOwned::to_owned) else { + return Err( + Error::Other( + "Subscription ID expected for chainHead_follow response, but not given" + .to_owned(), + ), + ); + }; + let stream: FollowEventStream = Box::pin(stream); + Ok((stream, sub_id)) + }) + }), + stream: InnerStreamState::New, + } + } + } + impl std::marker::Unpin for FollowStream {} + impl Stream for FollowStream { + type Item = Result, Error>; + fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let this = self.get_mut(); + loop { + match &mut this.stream { + InnerStreamState::New => { + let fut = (this.stream_getter)(); + this.stream = InnerStreamState::Initializing(fut); + continue; + } + InnerStreamState::Initializing(fut) => { + match fut.poll_unpin(cx) { + Poll::Pending => { + return Poll::Pending; + } + Poll::Ready(Ok(sub_with_id)) => { + this.stream = InnerStreamState::Ready(Some(sub_with_id)); + continue; + } + Poll::Ready(Err(e)) => { + this.stream = InnerStreamState::Finished; + return Poll::Ready(Some(Err(e))); + } + } + } + InnerStreamState::Ready(stream) => { + let (sub, sub_id) = stream + .take() + .expect("should always be Some"); + this.stream = InnerStreamState::ReceivingEvents(sub); + return Poll::Ready( + Some(Ok(FollowStreamMsg::Ready(sub_id))), + ); + } + InnerStreamState::ReceivingEvents(stream) => { + match stream.poll_next_unpin(cx) { + Poll::Pending => { + return Poll::Pending; + } + Poll::Ready(None) => { + this.stream = InnerStreamState::Stopped; + continue; + } + Poll::Ready(Some(Ok(ev))) => { + if let FollowEvent::Stop = ev { + this.stream = InnerStreamState::Stopped; + continue; + } + return Poll::Ready(Some(Ok(FollowStreamMsg::Event(ev)))); + } + Poll::Ready(Some(Err(e))) => { + this.stream = InnerStreamState::Finished; + return Poll::Ready(Some(Err(e))); + } + } + } + InnerStreamState::Stopped => { + this.stream = InnerStreamState::New; + return Poll::Ready( + Some(Ok(FollowStreamMsg::Event(FollowEvent::Stop))), + ); + } + InnerStreamState::Finished => { + return Poll::Ready(None); + } + } + } + } + } + } + mod follow_stream_driver { + use super::follow_stream_unpin::{ + BlockRef, FollowStreamMsg, FollowStreamUnpin, + }; + use crate::backend::unstable::rpc_methods::{ + FollowEvent, Initialized, RuntimeEvent, + }; + use crate::config::BlockHash; + use crate::error::Error; + use futures::stream::{Stream, StreamExt}; + use std::collections::{HashMap, HashSet, VecDeque}; + use std::ops::DerefMut; + use std::pin::Pin; + use std::sync::{Arc, Mutex}; + use std::task::{Context, Poll, Waker}; + /// A `Stream` which builds on `FollowStreamDriver`, and allows multiple subscribers to obtain events + /// from the single underlying subscription (each being provided an `Initialized` message and all new + /// blocks since then, as if they were each creating a unique `chainHead_follow` subscription). This + /// is the "top" layer of our follow stream subscriptions, and the one that's interacted with elsewhere. + pub struct FollowStreamDriver { + inner: FollowStreamUnpin, + shared: Shared, + } + #[automatically_derived] + impl ::core::fmt::Debug + for FollowStreamDriver { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "FollowStreamDriver", + "inner", + &self.inner, + "shared", + &&self.shared, + ) + } + } + impl FollowStreamDriver { + /// Create a new [`FollowStreamDriver`]. This must be polled by some executor + /// in order for any progress to be made. Things can subscribe to events. + pub fn new(follow_unpin: FollowStreamUnpin) -> Self { + Self { + inner: follow_unpin, + shared: Shared::default(), + } + } + /// Return a handle from which we can create new subscriptions to follow events. + pub fn handle(&self) -> FollowStreamDriverHandle { + FollowStreamDriverHandle { + shared: self.shared.clone(), + } + } + } + impl Stream for FollowStreamDriver { + type Item = Result<(), Error>; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + match self.inner.poll_next_unpin(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(None) => { + self.shared.done(); + Poll::Ready(None) + } + Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))), + Poll::Ready(Some(Ok(item))) => { + self.shared.push_item(item); + Poll::Ready(Some(Ok(()))) + } + } + } + } + /// A handle that can be used to create subscribers, but that doesn't + /// itself subscribe to events. + pub struct FollowStreamDriverHandle { + shared: Shared, + } + #[automatically_derived] + impl ::core::fmt::Debug + for FollowStreamDriverHandle { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "FollowStreamDriverHandle", + "shared", + &&self.shared, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for FollowStreamDriverHandle { + #[inline] + fn clone(&self) -> FollowStreamDriverHandle { + FollowStreamDriverHandle { + shared: ::core::clone::Clone::clone(&self.shared), + } + } + } + impl FollowStreamDriverHandle { + /// Subscribe to follow events. + pub fn subscribe(&self) -> FollowStreamDriverSubscription { + self.shared.subscribe() + } + } + /// A subscription to events from the [`FollowStreamDriver`]. All subscriptions + /// begin first with a `Ready` event containing the current subscription ID, and + /// then with an `Initialized` event containing the latest finalized block and latest + /// runtime information, and then any new/best block events and so on received since + /// the latest finalized block. + pub struct FollowStreamDriverSubscription { + id: usize, + done: bool, + shared: Shared, + local_items: VecDeque>>, + } + #[automatically_derived] + impl ::core::fmt::Debug + for FollowStreamDriverSubscription { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "FollowStreamDriverSubscription", + "id", + &self.id, + "done", + &self.done, + "shared", + &self.shared, + "local_items", + &&self.local_items, + ) + } + } + impl Stream for FollowStreamDriverSubscription { + type Item = FollowStreamMsg>; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + if self.done { + return Poll::Ready(None); + } + loop { + if let Some(item) = self.local_items.pop_front() { + return Poll::Ready(Some(item)); + } + let items = self + .shared + .take_items_and_save_waker(self.id, cx.waker()); + let Some(items) = items else { self.done = true; + return Poll::Ready(None); + }; + if items.is_empty() { + return Poll::Pending; + } else { + self.local_items = items; + } + } + } + } + impl FollowStreamDriverSubscription { + /// Return the current subscription ID. If the subscription has stopped, then this will + /// wait until a new subscription has started with a new ID. + pub async fn subscription_id(self) -> Option { + let ready_event = self + .skip_while(|ev| std::future::ready( + !match ev { + FollowStreamMsg::Ready(_) => true, + _ => false, + }, + )) + .next() + .await?; + match ready_event { + FollowStreamMsg::Ready(sub_id) => Some(sub_id), + _ => None, + } + } + /// Subscribe to the follow events, ignoring any other messages. + pub fn events( + self, + ) -> impl Stream>> + Send + Sync { + self.filter_map(|ev| std::future::ready(ev.into_event())) + } + } + impl Clone for FollowStreamDriverSubscription { + fn clone(&self) -> Self { + self.shared.subscribe() + } + } + impl Drop for FollowStreamDriverSubscription { + fn drop(&mut self) { + self.shared.remove_sub(self.id); + } + } + /// Locked shared state. The driver stream will access this state to push + /// events to any subscribers, and subscribers will access it to pull the + /// events destined for themselves. + struct Shared(Arc>>); + #[automatically_derived] + impl ::core::fmt::Debug + for Shared { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Shared", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for Shared { + #[inline] + fn clone(&self) -> Shared { + Shared(::core::clone::Clone::clone(&self.0)) + } + } + struct SharedState { + done: bool, + next_id: usize, + subscribers: HashMap>, + /// Keep a buffer of all events that should be handed to a new subscription. + block_events_for_new_subscriptions: VecDeque< + FollowEvent>, + >, + current_subscription_id: Option, + current_init_message: Option>>, + seen_runtime_events: HashMap, + } + #[automatically_derived] + impl ::core::fmt::Debug + for SharedState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "done", + "next_id", + "subscribers", + "block_events_for_new_subscriptions", + "current_subscription_id", + "current_init_message", + "seen_runtime_events", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.done, + &self.next_id, + &self.subscribers, + &self.block_events_for_new_subscriptions, + &self.current_subscription_id, + &self.current_init_message, + &&self.seen_runtime_events, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "SharedState", + names, + values, + ) + } + } + impl Default for Shared { + fn default() -> Self { + Shared( + Arc::new( + Mutex::new(SharedState { + next_id: 1, + done: false, + subscribers: HashMap::new(), + current_init_message: None, + current_subscription_id: None, + seen_runtime_events: HashMap::new(), + block_events_for_new_subscriptions: VecDeque::new(), + }), + ), + ) + } + } + impl Shared { + /// Set the shared state to "done"; no more items will be handed to it. + pub fn done(&self) { + let mut shared = self.0.lock().unwrap(); + shared.done = true; + } + /// Cleanup a subscription. + pub fn remove_sub(&self, sub_id: usize) { + let mut shared = self.0.lock().unwrap(); + shared.subscribers.remove(&sub_id); + } + /// Take items for some subscription ID and save the waker. + pub fn take_items_and_save_waker( + &self, + sub_id: usize, + waker: &Waker, + ) -> Option>>> { + let mut shared = self.0.lock().unwrap(); + let is_done = shared.done; + let details = shared.subscribers.get_mut(&sub_id)?; + if details.items.is_empty() && is_done { + return None; + } + let items = std::mem::take(&mut details.items); + if !is_done { + details.waker = Some(waker.clone()); + } + Some(items) + } + /// Push a new item out to subscribers. + pub fn push_item(&self, item: FollowStreamMsg>) { + let mut shared = self.0.lock().unwrap(); + let shared = shared.deref_mut(); + for details in shared.subscribers.values_mut() { + details.items.push_back(item.clone()); + if let Some(waker) = details.waker.take() { + waker.wake(); + } + } + match item { + FollowStreamMsg::Ready(sub_id) => { + shared.current_subscription_id = Some(sub_id); + } + FollowStreamMsg::Event(FollowEvent::Initialized(ev)) => { + shared.current_init_message = Some(ev.clone()); + shared.block_events_for_new_subscriptions.clear(); + } + FollowStreamMsg::Event(FollowEvent::Finalized(finalized_ev)) => { + if let Some(init_message) = &mut shared.current_init_message + { + let newest_runtime = finalized_ev + .finalized_block_hashes + .iter() + .rev() + .filter_map(|h| { + shared.seen_runtime_events.get(&h.hash()).cloned() + }) + .next(); + shared.seen_runtime_events.clear(); + if let Some(finalized) + = finalized_ev.finalized_block_hashes.last() + { + init_message.finalized_block_hash = finalized.clone(); + } + if let Some(runtime_ev) = newest_runtime { + init_message.finalized_block_runtime = Some(runtime_ev); + } + } + let to_remove: HashSet = finalized_ev + .finalized_block_hashes + .iter() + .chain(finalized_ev.pruned_block_hashes.iter()) + .map(|h| h.hash()) + .collect(); + shared + .block_events_for_new_subscriptions + .retain(|ev| match ev { + FollowEvent::NewBlock(new_block_ev) => { + !to_remove.contains(&new_block_ev.block_hash.hash()) + } + FollowEvent::BestBlockChanged(best_block_ev) => { + !to_remove.contains(&best_block_ev.best_block_hash.hash()) + } + _ => true, + }); + } + FollowStreamMsg::Event(FollowEvent::NewBlock(new_block_ev)) => { + if let Some(runtime_event) = &new_block_ev.new_runtime { + shared + .seen_runtime_events + .insert( + new_block_ev.block_hash.hash(), + runtime_event.clone(), + ); + } + shared + .block_events_for_new_subscriptions + .push_back(FollowEvent::NewBlock(new_block_ev)); + } + FollowStreamMsg::Event( + ev @ FollowEvent::BestBlockChanged(_), + ) => { + shared.block_events_for_new_subscriptions.push_back(ev); + } + FollowStreamMsg::Event(FollowEvent::Stop) => { + shared.block_events_for_new_subscriptions.clear(); + shared.current_subscription_id = None; + shared.current_init_message = None; + } + _ => {} + } + } + /// Create a new subscription. + pub fn subscribe(&self) -> FollowStreamDriverSubscription { + let mut shared = self.0.lock().unwrap(); + let id = shared.next_id; + shared.next_id += 1; + shared + .subscribers + .insert( + id, + SubscriberDetails { + items: VecDeque::new(), + waker: None, + }, + ); + let mut local_items = VecDeque::new(); + if let Some(sub_id) = &shared.current_subscription_id { + local_items.push_back(FollowStreamMsg::Ready(sub_id.clone())); + } + if let Some(init_msg) = &shared.current_init_message { + local_items + .push_back( + FollowStreamMsg::Event( + FollowEvent::Initialized(init_msg.clone()), + ), + ); + } + for ev in &shared.block_events_for_new_subscriptions { + local_items.push_back(FollowStreamMsg::Event(ev.clone())); + } + drop(shared); + FollowStreamDriverSubscription { + id, + done: false, + shared: self.clone(), + local_items, + } + } + } + /// Details for a given subscriber: any items it's not yet claimed, + /// and a way to wake it up when there are more items for it. + struct SubscriberDetails { + items: VecDeque>>, + waker: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug + for SubscriberDetails { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "SubscriberDetails", + "items", + &self.items, + "waker", + &&self.waker, + ) + } + } + } + mod follow_stream_unpin { + use super::follow_stream::FollowStream; + use super::UnstableRpcMethods; + use crate::backend::unstable::rpc_methods::{ + BestBlockChanged, Finalized, FollowEvent, Initialized, NewBlock, + }; + use crate::config::{BlockHash, Config}; + use crate::error::Error; + use futures::stream::{FuturesUnordered, Stream, StreamExt}; + use std::collections::{HashMap, HashSet}; + use std::future::Future; + use std::pin::Pin; + use std::sync::{Arc, Mutex}; + use std::task::{Context, Poll, Waker}; + /// The type of stream item. + pub use super::follow_stream::FollowStreamMsg; + /// A `Stream` which builds on `FollowStream`, and handles pinning. It replaces any block hash seen in + /// the follow events with a `BlockRef` which, when all clones are dropped, will lead to an "unpin" call + /// for that block hash being queued. It will also automatically unpin any blocks that exceed a given max + /// age, to try and prevent the underlying stream from ending (and _all_ blocks from being unpinned as a + /// result). Put simply, it tries to keep every block pinned as long as possible until the block is no longer + /// used anywhere. + pub struct FollowStreamUnpin { + inner: FollowStream, + unpin_method: UnpinMethodHolder, + unpin_futs: FuturesUnordered, + rel_block_num: usize, + subscription_id: Option>, + max_block_life: usize, + pinned: HashMap>, + unpin_flags: UnpinFlags, + } + #[automatically_derived] + impl ::core::fmt::Debug + for FollowStreamUnpin { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "inner", + "unpin_method", + "unpin_futs", + "rel_block_num", + "subscription_id", + "max_block_life", + "pinned", + "unpin_flags", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.inner, + &self.unpin_method, + &self.unpin_futs, + &self.rel_block_num, + &self.subscription_id, + &self.max_block_life, + &self.pinned, + &&self.unpin_flags, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "FollowStreamUnpin", + names, + values, + ) + } + } + struct UnpinMethodHolder(UnpinMethod); + impl std::fmt::Debug for UnpinMethodHolder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt( + format_args!( + "UnpinMethodHolder(Box) -> UnpinFut>)" + ), + ) + } + } + /// The type of the unpin method that we need to provide. + pub type UnpinMethod = Box< + dyn FnMut(Hash, Arc) -> UnpinFut + Send, + >; + /// The future returned from [`UnpinMethod`]. + pub type UnpinFut = Pin + Send + 'static>>; + impl std::marker::Unpin for FollowStreamUnpin {} + impl Stream for FollowStreamUnpin { + type Item = Result>, Error>; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let mut this = self.as_mut(); + loop { + let unpin_futs_are_pending = match this + .unpin_futs + .poll_next_unpin(cx) + { + Poll::Ready(Some(())) => continue, + Poll::Ready(None) => false, + Poll::Pending => true, + }; + let Poll::Ready(ev) = this.inner.poll_next_unpin(cx) else { + return Poll::Pending; + }; + let Some(ev) = ev else { + return match unpin_futs_are_pending { + true => Poll::Pending, + false => Poll::Ready(None), + }; + }; + let ev = match ev { + Ok(ev) => ev, + Err(e) => { + return Poll::Ready(Some(Err(e))); + } + }; + let ev = match ev { + FollowStreamMsg::Ready(subscription_id) => { + this.subscription_id = Some(subscription_id.clone().into()); + FollowStreamMsg::Ready(subscription_id) + } + FollowStreamMsg::Event( + FollowEvent::Initialized(details), + ) => { + let rel_block_num = this.rel_block_num; + let block_ref = this + .pin_unpinnable_block_at( + rel_block_num, + details.finalized_block_hash, + ); + FollowStreamMsg::Event( + FollowEvent::Initialized(Initialized { + finalized_block_hash: block_ref, + finalized_block_runtime: details.finalized_block_runtime, + }), + ) + } + FollowStreamMsg::Event(FollowEvent::NewBlock(details)) => { + let parent_rel_block_num = this + .pinned + .get(&details.parent_block_hash) + .map(|p| p.rel_block_num) + .unwrap_or(this.rel_block_num); + let block_ref = this + .pin_block_at(parent_rel_block_num + 1, details.block_hash); + let parent_block_ref = this + .pin_block_at( + parent_rel_block_num, + details.parent_block_hash, + ); + FollowStreamMsg::Event( + FollowEvent::NewBlock(NewBlock { + block_hash: block_ref, + parent_block_hash: parent_block_ref, + new_runtime: details.new_runtime, + }), + ) + } + FollowStreamMsg::Event( + FollowEvent::BestBlockChanged(details), + ) => { + let rel_block_num = this.rel_block_num + 1; + let block_ref = this + .pin_block_at(rel_block_num, details.best_block_hash); + FollowStreamMsg::Event( + FollowEvent::BestBlockChanged(BestBlockChanged { + best_block_hash: block_ref, + }), + ) + } + FollowStreamMsg::Event(FollowEvent::Finalized(details)) => { + let finalized_block_refs: Vec<_> = details + .finalized_block_hashes + .into_iter() + .enumerate() + .map(|(idx, hash)| { + let rel_block_num = this.rel_block_num + idx + 1; + this.pin_unpinnable_block_at(rel_block_num, hash) + }) + .collect(); + this.rel_block_num += finalized_block_refs.len(); + let pruned_block_refs: Vec<_> = details + .pruned_block_hashes + .into_iter() + .map(|hash| { + let rel_block_num = this.rel_block_num + 1; + this.pin_unpinnable_block_at(rel_block_num, hash) + }) + .collect(); + this.unpin_blocks(cx.waker()); + FollowStreamMsg::Event( + FollowEvent::Finalized(Finalized { + finalized_block_hashes: finalized_block_refs, + pruned_block_hashes: pruned_block_refs, + }), + ) + } + FollowStreamMsg::Event(FollowEvent::Stop) => { + this.subscription_id = None; + this.pinned.clear(); + this.unpin_futs.clear(); + this.unpin_flags.lock().unwrap().clear(); + this.rel_block_num = 0; + FollowStreamMsg::Event(FollowEvent::Stop) + } + FollowStreamMsg::Event( + FollowEvent::OperationBodyDone(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationBodyDone(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationCallDone(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationCallDone(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationStorageItems(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationStorageItems(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationWaitingForContinue(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationWaitingForContinue(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationStorageDone(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationStorageDone(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationInaccessible(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationInaccessible(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationError(details), + ) => { + FollowStreamMsg::Event(FollowEvent::OperationError(details)) + } + }; + return Poll::Ready(Some(Ok(ev))); + } + } + } + impl FollowStreamUnpin { + /// Create a new [`FollowStreamUnpin`]. + pub fn new( + follow_stream: FollowStream, + unpin_method: UnpinMethod, + max_block_life: usize, + ) -> Self { + Self { + inner: follow_stream, + unpin_method: UnpinMethodHolder(unpin_method), + max_block_life, + pinned: Default::default(), + subscription_id: None, + rel_block_num: 0, + unpin_flags: Default::default(), + unpin_futs: Default::default(), + } + } + /// Create a new [`FollowStreamUnpin`] given the RPC methods. + pub fn from_methods( + follow_stream: FollowStream, + methods: UnstableRpcMethods, + max_block_life: usize, + ) -> FollowStreamUnpin { + let unpin_method = Box::new(move |hash: T::Hash, sub_id: Arc| { + let methods = methods.clone(); + let fut: UnpinFut = Box::pin(async move { + let _ = methods + .chainhead_unstable_unpin(&sub_id, hash) + .await; + }); + fut + }); + FollowStreamUnpin::new(follow_stream, unpin_method, max_block_life) + } + /// Is the block hash currently pinned. + pub fn is_pinned(&self, hash: &Hash) -> bool { + self.pinned.contains_key(hash) + } + /// Pin a block, or return the reference to an already-pinned block. If the block has been registered to + /// be unpinned, we'll clear those flags, so that it won't be unpinned. If the unpin request has already + /// been sent though, then the block will be unpinned. + fn pin_block_at( + &mut self, + rel_block_num: usize, + hash: Hash, + ) -> BlockRef { + self.pin_block_at_setting_unpinnable_flag(rel_block_num, hash, false) + } + /// Pin a block, or return the reference to an already-pinned block. + /// + /// This is the same as [`Self::pin_block_at`], except that it also marks the block as being unpinnable now, + /// which should be done for any block that will no longer be seen in future events. + fn pin_unpinnable_block_at( + &mut self, + rel_block_num: usize, + hash: Hash, + ) -> BlockRef { + self.pin_block_at_setting_unpinnable_flag(rel_block_num, hash, true) + } + fn pin_block_at_setting_unpinnable_flag( + &mut self, + rel_block_num: usize, + hash: Hash, + can_be_unpinned: bool, + ) -> BlockRef { + let entry = self + .pinned + .entry(hash) + .and_modify(|entry| { + entry + .can_be_unpinned = entry.can_be_unpinned || can_be_unpinned; + self.unpin_flags.lock().unwrap().remove(&hash); + }) + .or_insert_with(|| PinnedDetails { + rel_block_num, + block_ref: BlockRef { + inner: Arc::new(BlockRefInner { + hash, + unpin_flags: self.unpin_flags.clone(), + }), + }, + can_be_unpinned, + }); + entry.block_ref.clone() + } + /// Unpin any blocks that are either too old, or have the unpin flag set and are old enough. + fn unpin_blocks(&mut self, waker: &Waker) { + let mut unpin_flags = self.unpin_flags.lock().unwrap(); + let rel_block_num = self.rel_block_num; + let Some(sub_id) = &self.subscription_id else { return; + }; + let mut blocks_to_unpin = ::alloc::vec::Vec::new(); + for (hash, details) in &self.pinned { + if rel_block_num.saturating_sub(details.rel_block_num) + >= self.max_block_life + || (unpin_flags.contains(hash) && details.can_be_unpinned) + { + blocks_to_unpin.push(*hash); + unpin_flags.remove(hash); + } + } + drop(unpin_flags); + if blocks_to_unpin.is_empty() { + return; + } + for hash in blocks_to_unpin { + self.pinned.remove(&hash); + let fut = (self.unpin_method.0)(hash, sub_id.clone()); + self.unpin_futs.push(fut); + } + waker.wake_by_ref(); + } + } + type UnpinFlags = Arc>>; + struct PinnedDetails { + /// How old is the block? + rel_block_num: usize, + /// A block ref we can hand out to keep blocks pinned. + /// Because we store one here until it's unpinned, the live count + /// will only drop to 1 when no external refs are left. + block_ref: BlockRef, + /// Has this block showed up in the list of pruned blocks, or has it + /// been finalized? In this case, it can now been pinned as it won't + /// show up again in future events (except as a "parent block" of some + /// new block, which we're currently ignoring). + can_be_unpinned: bool, + } + #[automatically_derived] + impl ::core::fmt::Debug + for PinnedDetails { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "PinnedDetails", + "rel_block_num", + &self.rel_block_num, + "block_ref", + &self.block_ref, + "can_be_unpinned", + &&self.can_be_unpinned, + ) + } + } + /// All blocks reported will be wrapped in this. + pub struct BlockRef { + inner: Arc>, + } + #[automatically_derived] + impl ::core::fmt::Debug + for BlockRef { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "BlockRef", + "inner", + &&self.inner, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for BlockRef { + #[inline] + fn clone(&self) -> BlockRef { + BlockRef { + inner: ::core::clone::Clone::clone(&self.inner), + } + } + } + struct BlockRefInner { + hash: Hash, + unpin_flags: UnpinFlags, + } + #[automatically_derived] + impl ::core::fmt::Debug for BlockRefInner { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "BlockRefInner", + "hash", + &self.hash, + "unpin_flags", + &&self.unpin_flags, + ) + } + } + impl BlockRef { + /// Return the hash for this block. + pub fn hash(&self) -> Hash { + self.inner.hash + } + } + impl PartialEq for BlockRef { + fn eq(&self, other: &Self) -> bool { + self.inner.hash == other.inner.hash + } + } + impl PartialEq for BlockRef { + fn eq(&self, other: &Hash) -> bool { + &self.inner.hash == other + } + } + impl Drop for BlockRef { + fn drop(&mut self) { + if Arc::strong_count(&self.inner) == 2 { + if let Ok(mut unpin_flags) = self.inner.unpin_flags.lock() { + unpin_flags.insert(self.inner.hash); + } + } + } + } + } + mod storage_items { + use super::follow_stream_driver::FollowStreamDriverHandle; + use super::follow_stream_unpin::BlockRef; + use super::rpc_methods::{ + FollowEvent, MethodResponse, StorageQuery, StorageResult, + UnstableRpcMethods, + }; + use crate::config::Config; + use crate::error::{Error, RpcError}; + use futures::{FutureExt, Stream, StreamExt}; + use std::collections::VecDeque; + use std::future::Future; + use std::pin::Pin; + use std::sync::Arc; + use std::task::{Context, Poll}; + /// Obtain a stream of storage items given some query. this handles continuing + /// and stopping under the hood, and returns a stream of `StorageResult`s. + pub struct StorageItems { + done: bool, + operation_id: Arc, + buffered_responses: VecDeque, + continue_call: ContinueFutGetter, + continue_fut: Option, + follow_event_stream: FollowEventStream, + } + impl StorageItems { + pub async fn from_methods( + queries: impl Iterator>, + at: T::Hash, + follow_handle: &FollowStreamDriverHandle, + methods: UnstableRpcMethods, + ) -> Result { + let sub_id = super::get_subscription_id(follow_handle).await?; + let follow_events = follow_handle.subscribe().events(); + let status = methods + .chainhead_unstable_storage(&sub_id, at, queries, None) + .await?; + let operation_id: Arc = match status { + MethodResponse::LimitReached => { + return Err( + RpcError::request_rejected("limit reached").into(), + ); + } + MethodResponse::Started(s) => s.operation_id.into(), + }; + let continue_call: ContinueFutGetter = { + let operation_id = operation_id.clone(); + Box::new(move || { + let sub_id = sub_id.clone(); + let operation_id = operation_id.clone(); + let methods = methods.clone(); + Box::pin(async move { + methods + .chainhead_unstable_continue(&sub_id, &operation_id) + .await + }) + }) + }; + Ok( + StorageItems::new( + operation_id, + continue_call, + Box::pin(follow_events), + ), + ) + } + fn new( + operation_id: Arc, + continue_call: ContinueFutGetter, + follow_event_stream: FollowEventStream, + ) -> Self { + Self { + done: false, + buffered_responses: VecDeque::new(), + operation_id, + continue_call, + continue_fut: None, + follow_event_stream, + } + } + } + pub type FollowEventStream = Pin< + Box>> + Send + 'static>, + >; + pub type ContinueFutGetter = Box ContinueFut + Send + 'static>; + pub type ContinueFut = Pin< + Box> + Send + 'static>, + >; + impl Stream for StorageItems { + type Item = Result; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + loop { + if self.done { + return Poll::Ready(None); + } + if let Some(item) = self.buffered_responses.pop_front() { + return Poll::Ready(Some(Ok(item))); + } + if let Some(mut fut) = self.continue_fut.take() { + match fut.poll_unpin(cx) { + Poll::Pending => { + self.continue_fut = Some(fut); + return Poll::Pending; + } + Poll::Ready(Err(e)) => { + self.done = true; + return Poll::Ready(Some(Err(e))); + } + Poll::Ready(Ok(())) => {} + } + } + let ev = match self.follow_event_stream.poll_next_unpin(cx) { + Poll::Pending => return Poll::Pending, + Poll::Ready(None) => return Poll::Ready(None), + Poll::Ready(Some(ev)) => ev, + }; + match ev { + FollowEvent::OperationWaitingForContinue( + id, + ) if id.operation_id == *self.operation_id => { + self.continue_fut = Some((self.continue_call)()); + continue; + } + FollowEvent::OperationStorageDone( + id, + ) if id.operation_id == *self.operation_id => { + self.done = true; + return Poll::Ready(None); + } + FollowEvent::OperationStorageItems( + items, + ) if items.operation_id == *self.operation_id => { + self.buffered_responses = items.items; + continue; + } + _ => { + continue; + } + } + } + } + } + } + pub mod rpc_methods { + //! An interface to call the API methods. See + //! for details of the API + //! methods exposed here. + use crate::backend::rpc::{rpc_params, RpcClient, RpcSubscription}; + use crate::config::BlockHash; + use crate::{Config, Error}; + use derivative::Derivative; + use futures::{Stream, StreamExt}; + use serde::{Deserialize, Serialize}; + use std::collections::{HashMap, VecDeque}; + use std::task::Poll; + /// An interface to call the unstable RPC methods. This interface is instantiated with + /// some `T: Config` trait which determines some of the types that the RPC methods will + /// take or hand back. + #[derivative(Clone(bound = ""), Debug(bound = ""))] + pub struct UnstableRpcMethods { + client: RpcClient, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for UnstableRpcMethods { + fn clone(&self) -> Self { + match *self { + UnstableRpcMethods { + client: ref __arg_0, + _marker: ref __arg_1, + } => { + UnstableRpcMethods { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for UnstableRpcMethods { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + UnstableRpcMethods { + client: ref __arg_0, + _marker: ref __arg_1, + } => { + let mut __debug_trait_builder = __f + .debug_struct("UnstableRpcMethods"); + let _ = __debug_trait_builder.field("client", &&(*__arg_0)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + impl UnstableRpcMethods { + /// Instantiate the legacy RPC method interface. + pub fn new(client: RpcClient) -> Self { + UnstableRpcMethods { + client, + _marker: std::marker::PhantomData, + } + } + /// Subscribe to `chainHead_unstable_follow` to obtain all reported blocks by the chain. + /// + /// The subscription ID can be used to make queries for the + /// block's body ([`chainhead_unstable_body`](UnstableRpcMethods::chainhead_unstable_follow)), + /// block's header ([`chainhead_unstable_header`](UnstableRpcMethods::chainhead_unstable_header)), + /// block's storage ([`chainhead_unstable_storage`](UnstableRpcMethods::chainhead_unstable_storage)) and submitting + /// runtime API calls at this block ([`chainhead_unstable_call`](UnstableRpcMethods::chainhead_unstable_call)). + /// + /// # Note + /// + /// When the user is no longer interested in a block, the user is responsible + /// for calling the [`chainhead_unstable_unpin`](UnstableRpcMethods::chainhead_unstable_unpin) method. + /// Failure to do so will result in the subscription being stopped by generating the `Stop` event. + pub async fn chainhead_unstable_follow( + &self, + with_runtime: bool, + ) -> Result, Error> { + let sub = self + .client + .subscribe( + "chainHead_unstable_follow", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(with_runtime) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + "chainHead_unstable_unfollow", + ) + .await?; + Ok(FollowSubscription { + sub, + done: false, + }) + } + /// Resumes a storage fetch started with chainHead_unstable_storage after it has generated an + /// `operationWaitingForContinue` event. + /// + /// Has no effect if the operationId is invalid or refers to an operation that has emitted a + /// `{"event": "operationInaccessible"` event, or if the followSubscription is invalid or stale. + pub async fn chainhead_unstable_continue( + &self, + follow_subscription: &str, + operation_id: &str, + ) -> Result<(), Error> { + self.client + .request( + "chainHead_unstable_continue", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(follow_subscription) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(operation_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(()) + } + /// Stops an operation started with `chainHead_unstable_body`, `chainHead_unstable_call`, or + /// `chainHead_unstable_storage¦. If the operation was still in progress, this interrupts it. + /// If the operation was already finished, this call has no effect. + /// + /// Has no effect if the `followSubscription` is invalid or stale. + pub async fn chainhead_unstable_stop_operation( + &self, + follow_subscription: &str, + operation_id: &str, + ) -> Result<(), Error> { + self.client + .request( + "chainHead_unstable_stopOperation", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(follow_subscription) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(operation_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(()) + } + /// Call the `chainHead_unstable_body` method and return an operation ID to obtain the block's body. + /// + /// The response events are provided on the `chainHead_follow` subscription and identified by + /// the returned operation ID. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_body( + &self, + subscription_id: &str, + hash: T::Hash, + ) -> Result { + let response = self + .client + .request( + "chainHead_unstable_body", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(response) + } + /// Get the block's header using the `chainHead_unstable_header` method. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_header( + &self, + subscription_id: &str, + hash: T::Hash, + ) -> Result, Error> { + let header: Option = self + .client + .request( + "chainHead_unstable_header", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + let header = header + .map(|h| codec::Decode::decode(&mut &*h.0)) + .transpose()?; + Ok(header) + } + /// Call the `chainhead_unstable_storage` method and return an operation ID to obtain the block's storage. + /// + /// The response events are provided on the `chainHead_follow` subscription and identified by + /// the returned operation ID. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_storage( + &self, + subscription_id: &str, + hash: T::Hash, + items: impl IntoIterator>, + child_key: Option<&[u8]>, + ) -> Result { + let items: Vec> = items + .into_iter() + .map(|item| StorageQuery { + key: to_hex(item.key), + query_type: item.query_type, + }) + .collect(); + let response = self + .client + .request( + "chainHead_unstable_storage", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(items) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(child_key.map(to_hex)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(response) + } + /// Call the `chainhead_unstable_storage` method and return an operation ID to obtain the runtime API result. + /// + /// The response events are provided on the `chainHead_follow` subscription and identified by + /// the returned operation ID. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_call( + &self, + subscription_id: &str, + hash: T::Hash, + function: &str, + call_parameters: &[u8], + ) -> Result { + let response = self + .client + .request( + "chainHead_unstable_call", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(function) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(to_hex(call_parameters)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(response) + } + /// Unpin a block reported by the `chainHead_follow` subscription. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_unpin( + &self, + subscription_id: &str, + hash: T::Hash, + ) -> Result<(), Error> { + self.client + .request( + "chainHead_unstable_unpin", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(()) + } + /// Return the genesis hash. + pub async fn chainspec_v1_genesis_hash(&self) -> Result { + let hash = self + .client + .request( + "chainSpec_v1_genesisHash", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await?; + Ok(hash) + } + /// Return a string containing the human-readable name of the chain. + pub async fn chainspec_v1_chain_name(&self) -> Result { + let hash = self + .client + .request( + "chainSpec_v1_chainName", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await?; + Ok(hash) + } + /// Returns the JSON payload found in the chain specification under the key properties. + /// No guarantee is offered about the content of this object, and so it's up to the caller + /// to decide what to deserialize it into. + pub async fn chainspec_v1_properties( + &self, + ) -> Result { + self.client + .request( + "chainSpec_v1_properties", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Returns an array of strings indicating the names of all the JSON-RPC functions supported by + /// the JSON-RPC server. + pub async fn rpc_methods(&self) -> Result, Error> { + self.client + .request( + "rpc_methods", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Attempt to submit a transaction, returning events about its progress. + pub async fn transaction_unstable_submit_and_watch( + &self, + tx: &[u8], + ) -> Result, Error> { + let sub = self + .client + .subscribe( + "transactionWatch_unstable_submitAndWatch", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(tx)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + "transactionWatch_unstable_unwatch", + ) + .await?; + Ok(TransactionSubscription { + sub, + done: false, + }) + } + } + /// This represents events generated by the `follow` method. + /// + /// The block events are generated in the following order: + /// 1. Initialized - generated only once to signal the latest finalized block + /// 2. NewBlock - a new block was added. + /// 3. BestBlockChanged - indicate that the best block is now the one from this event. The block was + /// announced priorly with the `NewBlock` event. + /// 4. Finalized - State the finalized and pruned blocks. + /// + /// The following events are related to operations: + /// - OperationBodyDone: The response of the `chainHead_body` + /// - OperationCallDone: The response of the `chainHead_call` + /// - OperationStorageItems: Items produced by the `chianHead_storage` + /// - OperationWaitingForContinue: Generated after OperationStorageItems and requires the user to + /// call `chainHead_continue` + /// - OperationStorageDone: The `chainHead_storage` method has produced all the results + /// - OperationInaccessible: The server was unable to provide the result, retries might succeed in + /// the future + /// - OperationError: The server encountered an error, retries will not succeed + /// + /// The stop event indicates that the JSON-RPC server was unable to provide a consistent list of + /// the blocks at the head of the chain. + #[serde(rename_all = "camelCase")] + #[serde(tag = "event")] + pub enum FollowEvent { + /// The latest finalized block. + /// + /// This event is generated only once. + Initialized(Initialized), + /// A new non-finalized block was added. + NewBlock(NewBlock), + /// The best block of the chain. + BestBlockChanged(BestBlockChanged), + /// A list of finalized and pruned blocks. + Finalized(Finalized), + /// The response of the `chainHead_body` method. + OperationBodyDone(OperationBodyDone), + /// The response of the `chainHead_call` method. + OperationCallDone(OperationCallDone), + /// Yield one or more items found in the storage. + OperationStorageItems(OperationStorageItems), + /// Ask the user to call `chainHead_continue` to produce more events + /// regarding the operation id. + OperationWaitingForContinue(OperationId), + /// The responses of the `chainHead_storage` method have been produced. + OperationStorageDone(OperationId), + /// The RPC server was unable to provide the response of the following operation id. + /// + /// Repeating the same operation in the future might succeed. + OperationInaccessible(OperationId), + /// The RPC server encountered an error while processing an operation id. + /// + /// Repeating the same operation in the future will not succeed. + OperationError(OperationError), + /// The subscription is dropped and no further events + /// will be generated. + Stop, + } + #[automatically_derived] + impl ::core::fmt::Debug for FollowEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + FollowEvent::Initialized(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Initialized", + &__self_0, + ) + } + FollowEvent::NewBlock(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "NewBlock", + &__self_0, + ) + } + FollowEvent::BestBlockChanged(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "BestBlockChanged", + &__self_0, + ) + } + FollowEvent::Finalized(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Finalized", + &__self_0, + ) + } + FollowEvent::OperationBodyDone(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationBodyDone", + &__self_0, + ) + } + FollowEvent::OperationCallDone(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationCallDone", + &__self_0, + ) + } + FollowEvent::OperationStorageItems(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationStorageItems", + &__self_0, + ) + } + FollowEvent::OperationWaitingForContinue(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationWaitingForContinue", + &__self_0, + ) + } + FollowEvent::OperationStorageDone(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationStorageDone", + &__self_0, + ) + } + FollowEvent::OperationInaccessible(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationInaccessible", + &__self_0, + ) + } + FollowEvent::OperationError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationError", + &__self_0, + ) + } + FollowEvent::Stop => ::core::fmt::Formatter::write_str(f, "Stop"), + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for FollowEvent { + #[inline] + fn clone(&self) -> FollowEvent { + match self { + FollowEvent::Initialized(__self_0) => { + FollowEvent::Initialized( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::NewBlock(__self_0) => { + FollowEvent::NewBlock(::core::clone::Clone::clone(__self_0)) + } + FollowEvent::BestBlockChanged(__self_0) => { + FollowEvent::BestBlockChanged( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::Finalized(__self_0) => { + FollowEvent::Finalized(::core::clone::Clone::clone(__self_0)) + } + FollowEvent::OperationBodyDone(__self_0) => { + FollowEvent::OperationBodyDone( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationCallDone(__self_0) => { + FollowEvent::OperationCallDone( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationStorageItems(__self_0) => { + FollowEvent::OperationStorageItems( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationWaitingForContinue(__self_0) => { + FollowEvent::OperationWaitingForContinue( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationStorageDone(__self_0) => { + FollowEvent::OperationStorageDone( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationInaccessible(__self_0) => { + FollowEvent::OperationInaccessible( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationError(__self_0) => { + FollowEvent::OperationError( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::Stop => FollowEvent::Stop, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for FollowEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for FollowEvent { + #[inline] + fn eq(&self, other: &FollowEvent) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + FollowEvent::Initialized(__self_0), + FollowEvent::Initialized(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::NewBlock(__self_0), + FollowEvent::NewBlock(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::BestBlockChanged(__self_0), + FollowEvent::BestBlockChanged(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::Finalized(__self_0), + FollowEvent::Finalized(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationBodyDone(__self_0), + FollowEvent::OperationBodyDone(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationCallDone(__self_0), + FollowEvent::OperationCallDone(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationStorageItems(__self_0), + FollowEvent::OperationStorageItems(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationWaitingForContinue(__self_0), + FollowEvent::OperationWaitingForContinue(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationStorageDone(__self_0), + FollowEvent::OperationStorageDone(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationInaccessible(__self_0), + FollowEvent::OperationInaccessible(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationError(__self_0), + FollowEvent::OperationError(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for FollowEvent { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for FollowEvent + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __field6, + __field7, + __field8, + __field9, + __field10, + __field11, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + 5u64 => _serde::__private::Ok(__Field::__field5), + 6u64 => _serde::__private::Ok(__Field::__field6), + 7u64 => _serde::__private::Ok(__Field::__field7), + 8u64 => _serde::__private::Ok(__Field::__field8), + 9u64 => _serde::__private::Ok(__Field::__field9), + 10u64 => _serde::__private::Ok(__Field::__field10), + 11u64 => _serde::__private::Ok(__Field::__field11), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 12", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "initialized" => _serde::__private::Ok(__Field::__field0), + "newBlock" => _serde::__private::Ok(__Field::__field1), + "bestBlockChanged" => { + _serde::__private::Ok(__Field::__field2) + } + "finalized" => _serde::__private::Ok(__Field::__field3), + "operationBodyDone" => { + _serde::__private::Ok(__Field::__field4) + } + "operationCallDone" => { + _serde::__private::Ok(__Field::__field5) + } + "operationStorageItems" => { + _serde::__private::Ok(__Field::__field6) + } + "operationWaitingForContinue" => { + _serde::__private::Ok(__Field::__field7) + } + "operationStorageDone" => { + _serde::__private::Ok(__Field::__field8) + } + "operationInaccessible" => { + _serde::__private::Ok(__Field::__field9) + } + "operationError" => { + _serde::__private::Ok(__Field::__field10) + } + "stop" => _serde::__private::Ok(__Field::__field11), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"initialized" => _serde::__private::Ok(__Field::__field0), + b"newBlock" => _serde::__private::Ok(__Field::__field1), + b"bestBlockChanged" => { + _serde::__private::Ok(__Field::__field2) + } + b"finalized" => _serde::__private::Ok(__Field::__field3), + b"operationBodyDone" => { + _serde::__private::Ok(__Field::__field4) + } + b"operationCallDone" => { + _serde::__private::Ok(__Field::__field5) + } + b"operationStorageItems" => { + _serde::__private::Ok(__Field::__field6) + } + b"operationWaitingForContinue" => { + _serde::__private::Ok(__Field::__field7) + } + b"operationStorageDone" => { + _serde::__private::Ok(__Field::__field8) + } + b"operationInaccessible" => { + _serde::__private::Ok(__Field::__field9) + } + b"operationError" => { + _serde::__private::Ok(__Field::__field10) + } + b"stop" => _serde::__private::Ok(__Field::__field11), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "initialized", + "newBlock", + "bestBlockChanged", + "finalized", + "operationBodyDone", + "operationCallDone", + "operationStorageItems", + "operationWaitingForContinue", + "operationStorageDone", + "operationInaccessible", + "operationError", + "stop", + ]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::< + __Field, + >::new("event", "internally tagged enum FollowEvent"), + )?; + let __deserializer = _serde::__private::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::__private::Result::map( + as _serde::Deserialize>::deserialize(__deserializer), + FollowEvent::Initialized, + ) + } + __Field::__field1 => { + _serde::__private::Result::map( + as _serde::Deserialize>::deserialize(__deserializer), + FollowEvent::NewBlock, + ) + } + __Field::__field2 => { + _serde::__private::Result::map( + as _serde::Deserialize>::deserialize(__deserializer), + FollowEvent::BestBlockChanged, + ) + } + __Field::__field3 => { + _serde::__private::Result::map( + as _serde::Deserialize>::deserialize(__deserializer), + FollowEvent::Finalized, + ) + } + __Field::__field4 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationBodyDone, + ) + } + __Field::__field5 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationCallDone, + ) + } + __Field::__field6 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationStorageItems, + ) + } + __Field::__field7 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationWaitingForContinue, + ) + } + __Field::__field8 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationStorageDone, + ) + } + __Field::__field9 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationInaccessible, + ) + } + __Field::__field10 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationError, + ) + } + __Field::__field11 => { + _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::InternallyTaggedUnitVisitor::new( + "FollowEvent", + "Stop", + ), + )?; + _serde::__private::Ok(FollowEvent::Stop) + } + } + } + } + }; + /// Contain information about the latest finalized block. + /// + /// # Note + /// + /// This is the first event generated by the `follow` subscription + /// and is submitted only once. + #[serde(rename_all = "camelCase")] + pub struct Initialized { + /// The hash of the latest finalized block. + pub finalized_block_hash: Hash, + /// The runtime version of the finalized block. + /// + /// # Note + /// + /// This is present only if the `with_runtime` flag is set for + /// the `follow` subscription. + pub finalized_block_runtime: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug for Initialized { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Initialized", + "finalized_block_hash", + &self.finalized_block_hash, + "finalized_block_runtime", + &&self.finalized_block_runtime, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for Initialized { + #[inline] + fn clone(&self) -> Initialized { + Initialized { + finalized_block_hash: ::core::clone::Clone::clone( + &self.finalized_block_hash, + ), + finalized_block_runtime: ::core::clone::Clone::clone( + &self.finalized_block_runtime, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Initialized {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for Initialized { + #[inline] + fn eq(&self, other: &Initialized) -> bool { + self.finalized_block_hash == other.finalized_block_hash + && self.finalized_block_runtime == other.finalized_block_runtime + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Initialized { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for Initialized + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "finalizedBlockHash" => { + _serde::__private::Ok(__Field::__field0) + } + "finalizedBlockRuntime" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"finalizedBlockHash" => { + _serde::__private::Ok(__Field::__field0) + } + b"finalizedBlockRuntime" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = Initialized; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct Initialized", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Initialized with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Initialized with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(Initialized { + finalized_block_hash: __field0, + finalized_block_runtime: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + Option, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "finalizedBlockHash", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "finalizedBlockRuntime", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("finalizedBlockHash")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field( + "finalizedBlockRuntime", + )? + } + }; + _serde::__private::Ok(Initialized { + finalized_block_hash: __field0, + finalized_block_runtime: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "finalizedBlockHash", + "finalizedBlockRuntime", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Initialized", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The runtime event generated if the `follow` subscription + /// has set the `with_runtime` flag. + #[serde(rename_all = "camelCase")] + #[serde(tag = "type")] + pub enum RuntimeEvent { + /// The runtime version of this block. + Valid(RuntimeVersionEvent), + /// The runtime could not be obtained due to an error. + Invalid(ErrorEvent), + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + RuntimeEvent::Valid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Valid", + &__self_0, + ) + } + RuntimeEvent::Invalid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Invalid", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeEvent { + #[inline] + fn clone(&self) -> RuntimeEvent { + match self { + RuntimeEvent::Valid(__self_0) => { + RuntimeEvent::Valid(::core::clone::Clone::clone(__self_0)) + } + RuntimeEvent::Invalid(__self_0) => { + RuntimeEvent::Invalid(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeEvent { + #[inline] + fn eq(&self, other: &RuntimeEvent) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + RuntimeEvent::Valid(__self_0), + RuntimeEvent::Valid(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + RuntimeEvent::Invalid(__self_0), + RuntimeEvent::Invalid(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeEvent { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RuntimeEvent { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "valid" => _serde::__private::Ok(__Field::__field0), + "invalid" => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"valid" => _serde::__private::Ok(__Field::__field0), + b"invalid" => _serde::__private::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &["valid", "invalid"]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::< + __Field, + >::new("type", "internally tagged enum RuntimeEvent"), + )?; + let __deserializer = _serde::__private::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + RuntimeEvent::Valid, + ) + } + __Field::__field1 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + RuntimeEvent::Invalid, + ) + } + } + } + } + }; + /// The runtime specification of the current block. + /// + /// This event is generated for: + /// - the first announced block by the follow subscription + /// - blocks that suffered a change in runtime compared with their parents + #[serde(rename_all = "camelCase")] + pub struct RuntimeVersionEvent { + /// Details about this runtime. + pub spec: RuntimeSpec, + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeVersionEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "RuntimeVersionEvent", + "spec", + &&self.spec, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeVersionEvent { + #[inline] + fn clone(&self) -> RuntimeVersionEvent { + RuntimeVersionEvent { + spec: ::core::clone::Clone::clone(&self.spec), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeVersionEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeVersionEvent { + #[inline] + fn eq(&self, other: &RuntimeVersionEvent) -> bool { + self.spec == other.spec + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeVersionEvent { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RuntimeVersionEvent { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "spec" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"spec" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = RuntimeVersionEvent; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct RuntimeVersionEvent", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + RuntimeSpec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct RuntimeVersionEvent with 1 element", + ), + ); + } + }; + _serde::__private::Ok(RuntimeVersionEvent { + spec: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("spec"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + RuntimeSpec, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("spec")? + } + }; + _serde::__private::Ok(RuntimeVersionEvent { + spec: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["spec"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "RuntimeVersionEvent", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + RuntimeVersionEvent, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// This contains the runtime version information necessary to make transactions, and is obtained from + /// the "initialized" event of `chainHead_follow` if the `withRuntime` flag is set. + #[serde(rename_all = "camelCase")] + pub struct RuntimeSpec { + /// Opaque string indicating the name of the chain. + pub spec_name: String, + /// Opaque string indicating the name of the implementation of the chain. + pub impl_name: String, + /// Opaque integer. The JSON-RPC client can assume that the Runtime API call to `Metadata_metadata` + /// will always produce the same output as long as the specVersion is the same. + pub spec_version: u32, + /// Opaque integer. Whenever the runtime code changes in a backwards-compatible way, the implVersion + /// is modified while the specVersion is left untouched. + pub impl_version: u32, + /// Opaque integer. Necessary when building the bytes of a transaction. Transactions that have been + /// generated with a different `transaction_version` are incompatible. + pub transaction_version: u32, + /// Object containing a list of "entry point APIs" supported by the runtime. Each key is an opaque string + /// indicating the API, and each value is an integer version number. Before making a runtime call (using + /// chainHead_call), you should make sure that this list contains the entry point API corresponding to the + /// call and with a known version number. + /// + /// **Note:** In Substrate, the keys in the apis field consists of the hexadecimal-encoded 8-bytes blake2 + /// hash of the name of the API. For example, the `TaggedTransactionQueue` API is 0xd2bc9897eed08f15. + #[serde(with = "hashmap_as_tuple_list")] + pub apis: HashMap, + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeSpec { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "spec_name", + "impl_name", + "spec_version", + "impl_version", + "transaction_version", + "apis", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.spec_name, + &self.impl_name, + &self.spec_version, + &self.impl_version, + &self.transaction_version, + &&self.apis, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "RuntimeSpec", + names, + values, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeSpec { + #[inline] + fn clone(&self) -> RuntimeSpec { + RuntimeSpec { + spec_name: ::core::clone::Clone::clone(&self.spec_name), + impl_name: ::core::clone::Clone::clone(&self.impl_name), + spec_version: ::core::clone::Clone::clone(&self.spec_version), + impl_version: ::core::clone::Clone::clone(&self.impl_version), + transaction_version: ::core::clone::Clone::clone( + &self.transaction_version, + ), + apis: ::core::clone::Clone::clone(&self.apis), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeSpec {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeSpec { + #[inline] + fn eq(&self, other: &RuntimeSpec) -> bool { + self.spec_name == other.spec_name + && self.impl_name == other.impl_name + && self.spec_version == other.spec_version + && self.impl_version == other.impl_version + && self.transaction_version == other.transaction_version + && self.apis == other.apis + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeSpec { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RuntimeSpec { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + 5u64 => _serde::__private::Ok(__Field::__field5), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "specName" => _serde::__private::Ok(__Field::__field0), + "implName" => _serde::__private::Ok(__Field::__field1), + "specVersion" => _serde::__private::Ok(__Field::__field2), + "implVersion" => _serde::__private::Ok(__Field::__field3), + "transactionVersion" => { + _serde::__private::Ok(__Field::__field4) + } + "apis" => _serde::__private::Ok(__Field::__field5), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"specName" => _serde::__private::Ok(__Field::__field0), + b"implName" => _serde::__private::Ok(__Field::__field1), + b"specVersion" => _serde::__private::Ok(__Field::__field2), + b"implVersion" => _serde::__private::Ok(__Field::__field3), + b"transactionVersion" => { + _serde::__private::Ok(__Field::__field4) + } + b"apis" => _serde::__private::Ok(__Field::__field5), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = RuntimeSpec; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct RuntimeSpec", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field5 = match { + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: HashMap, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: hashmap_as_tuple_list::deserialize(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 5usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + _serde::__private::Ok(RuntimeSpec { + spec_name: __field0, + impl_name: __field1, + spec_version: __field2, + impl_version: __field3, + transaction_version: __field4, + apis: __field5, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option = _serde::__private::None; + let mut __field3: _serde::__private::Option = _serde::__private::None; + let mut __field4: _serde::__private::Option = _serde::__private::None; + let mut __field5: _serde::__private::Option< + HashMap, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "specName", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "implName", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "specVersion", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private::Option::is_some(&__field3) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "implVersion", + ), + ); + } + __field3 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private::Option::is_some(&__field4) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "transactionVersion", + ), + ); + } + __field4 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field5 => { + if _serde::__private::Option::is_some(&__field5) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("apis"), + ); + } + __field5 = _serde::__private::Some({ + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: HashMap, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: hashmap_as_tuple_list::deserialize(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + match _serde::de::MapAccess::next_value::< + __DeserializeWith<'de>, + >(&mut __map) { + _serde::__private::Ok(__wrapper) => __wrapper.value, + _serde::__private::Err(__err) => { + return _serde::__private::Err(__err); + } + } + }); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("specName")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("implName")? + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("specVersion")? + } + }; + let __field3 = match __field3 { + _serde::__private::Some(__field3) => __field3, + _serde::__private::None => { + _serde::__private::de::missing_field("implVersion")? + } + }; + let __field4 = match __field4 { + _serde::__private::Some(__field4) => __field4, + _serde::__private::None => { + _serde::__private::de::missing_field("transactionVersion")? + } + }; + let __field5 = match __field5 { + _serde::__private::Some(__field5) => __field5, + _serde::__private::None => { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::missing_field("apis"), + ); + } + }; + _serde::__private::Ok(RuntimeSpec { + spec_name: __field0, + impl_name: __field1, + spec_version: __field2, + impl_version: __field3, + transaction_version: __field4, + apis: __field5, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "specName", + "implName", + "specVersion", + "implVersion", + "transactionVersion", + "apis", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "RuntimeSpec", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The operation could not be processed due to an error. + #[serde(rename_all = "camelCase")] + pub struct ErrorEvent { + /// Reason of the error. + pub error: String, + } + #[automatically_derived] + impl ::core::fmt::Debug for ErrorEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "ErrorEvent", + "error", + &&self.error, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for ErrorEvent { + #[inline] + fn clone(&self) -> ErrorEvent { + ErrorEvent { + error: ::core::clone::Clone::clone(&self.error), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ErrorEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ErrorEvent { + #[inline] + fn eq(&self, other: &ErrorEvent) -> bool { + self.error == other.error + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ErrorEvent { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ErrorEvent { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ErrorEvent; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct ErrorEvent", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ErrorEvent with 1 element", + ), + ); + } + }; + _serde::__private::Ok(ErrorEvent { error: __field0 }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(ErrorEvent { error: __field0 }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["error"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ErrorEvent", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate a new non-finalized block. + #[serde(rename_all = "camelCase")] + pub struct NewBlock { + /// The hash of the new block. + pub block_hash: Hash, + /// The parent hash of the new block. + pub parent_block_hash: Hash, + /// The runtime version of the new block. + /// + /// # Note + /// + /// This is present only if the `with_runtime` flag is set for + /// the `follow` subscription. + pub new_runtime: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug for NewBlock { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "NewBlock", + "block_hash", + &self.block_hash, + "parent_block_hash", + &self.parent_block_hash, + "new_runtime", + &&self.new_runtime, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for NewBlock { + #[inline] + fn clone(&self) -> NewBlock { + NewBlock { + block_hash: ::core::clone::Clone::clone(&self.block_hash), + parent_block_hash: ::core::clone::Clone::clone( + &self.parent_block_hash, + ), + new_runtime: ::core::clone::Clone::clone(&self.new_runtime), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for NewBlock {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for NewBlock { + #[inline] + fn eq(&self, other: &NewBlock) -> bool { + self.block_hash == other.block_hash + && self.parent_block_hash == other.parent_block_hash + && self.new_runtime == other.new_runtime + } + } + #[automatically_derived] + impl ::core::cmp::Eq for NewBlock { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for NewBlock + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "blockHash" => _serde::__private::Ok(__Field::__field0), + "parentBlockHash" => { + _serde::__private::Ok(__Field::__field1) + } + "newRuntime" => _serde::__private::Ok(__Field::__field2), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"blockHash" => _serde::__private::Ok(__Field::__field0), + b"parentBlockHash" => { + _serde::__private::Ok(__Field::__field1) + } + b"newRuntime" => _serde::__private::Ok(__Field::__field2), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = NewBlock; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct NewBlock", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct NewBlock with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct NewBlock with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct NewBlock with 3 elements", + ), + ); + } + }; + _serde::__private::Ok(NewBlock { + block_hash: __field0, + parent_block_hash: __field1, + new_runtime: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option< + Option, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "blockHash", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "parentBlockHash", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "newRuntime", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("blockHash")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("parentBlockHash")? + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("newRuntime")? + } + }; + _serde::__private::Ok(NewBlock { + block_hash: __field0, + parent_block_hash: __field1, + new_runtime: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "blockHash", + "parentBlockHash", + "newRuntime", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "NewBlock", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate the block hash of the new best block. + #[serde(rename_all = "camelCase")] + pub struct BestBlockChanged { + /// The block hash of the new best block. + pub best_block_hash: Hash, + } + #[automatically_derived] + impl ::core::fmt::Debug + for BestBlockChanged { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "BestBlockChanged", + "best_block_hash", + &&self.best_block_hash, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for BestBlockChanged { + #[inline] + fn clone(&self) -> BestBlockChanged { + BestBlockChanged { + best_block_hash: ::core::clone::Clone::clone( + &self.best_block_hash, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BestBlockChanged {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for BestBlockChanged { + #[inline] + fn eq(&self, other: &BestBlockChanged) -> bool { + self.best_block_hash == other.best_block_hash + } + } + #[automatically_derived] + impl ::core::cmp::Eq for BestBlockChanged { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for BestBlockChanged + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "bestBlockHash" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"bestBlockHash" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + BestBlockChanged, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = BestBlockChanged; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct BestBlockChanged", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct BestBlockChanged with 1 element", + ), + ); + } + }; + _serde::__private::Ok(BestBlockChanged { + best_block_hash: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "bestBlockHash", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("bestBlockHash")? + } + }; + _serde::__private::Ok(BestBlockChanged { + best_block_hash: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["bestBlockHash"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "BestBlockChanged", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + BestBlockChanged, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate the finalized and pruned block hashes. + #[serde(rename_all = "camelCase")] + pub struct Finalized { + /// Block hashes that are finalized. + pub finalized_block_hashes: Vec, + /// Block hashes that are pruned (removed). + pub pruned_block_hashes: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for Finalized { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Finalized", + "finalized_block_hashes", + &self.finalized_block_hashes, + "pruned_block_hashes", + &&self.pruned_block_hashes, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for Finalized { + #[inline] + fn clone(&self) -> Finalized { + Finalized { + finalized_block_hashes: ::core::clone::Clone::clone( + &self.finalized_block_hashes, + ), + pruned_block_hashes: ::core::clone::Clone::clone( + &self.pruned_block_hashes, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Finalized {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for Finalized { + #[inline] + fn eq(&self, other: &Finalized) -> bool { + self.finalized_block_hashes == other.finalized_block_hashes + && self.pruned_block_hashes == other.pruned_block_hashes + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Finalized { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for Finalized + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "finalizedBlockHashes" => { + _serde::__private::Ok(__Field::__field0) + } + "prunedBlockHashes" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"finalizedBlockHashes" => { + _serde::__private::Ok(__Field::__field0) + } + b"prunedBlockHashes" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = Finalized; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct Finalized", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Finalized with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Finalized with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(Finalized { + finalized_block_hashes: __field0, + pruned_block_hashes: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option> = _serde::__private::None; + let mut __field1: _serde::__private::Option> = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "finalizedBlockHashes", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "prunedBlockHashes", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field( + "finalizedBlockHashes", + )? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("prunedBlockHashes")? + } + }; + _serde::__private::Ok(Finalized { + finalized_block_hashes: __field0, + pruned_block_hashes: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "finalizedBlockHashes", + "prunedBlockHashes", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Finalized", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate the operation id of the event. + #[serde(rename_all = "camelCase")] + pub struct OperationId { + /// The operation id of the event. + pub operation_id: String, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "OperationId", + "operation_id", + &&self.operation_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationId { + #[inline] + fn clone(&self) -> OperationId { + OperationId { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationId { + #[inline] + fn eq(&self, other: &OperationId) -> bool { + self.operation_id == other.operation_id + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationId; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationId", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationId with 1 element", + ), + ); + } + }; + _serde::__private::Ok(OperationId { + operation_id: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + _serde::__private::Ok(OperationId { + operation_id: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["operationId"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationId", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The response of the `chainHead_body` method. + #[serde(rename_all = "camelCase")] + pub struct OperationBodyDone { + /// The operation id of the event. + pub operation_id: String, + /// Array of hexadecimal-encoded scale-encoded extrinsics found in the block. + pub value: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationBodyDone { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "OperationBodyDone", + "operation_id", + &self.operation_id, + "value", + &&self.value, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationBodyDone { + #[inline] + fn clone(&self) -> OperationBodyDone { + OperationBodyDone { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + value: ::core::clone::Clone::clone(&self.value), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationBodyDone {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationBodyDone { + #[inline] + fn eq(&self, other: &OperationBodyDone) -> bool { + self.operation_id == other.operation_id && self.value == other.value + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationBodyDone { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationBodyDone { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "value" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"value" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationBodyDone; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationBodyDone", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationBodyDone with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct OperationBodyDone with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(OperationBodyDone { + operation_id: __field0, + value: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option> = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("value"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("value")? + } + }; + _serde::__private::Ok(OperationBodyDone { + operation_id: __field0, + value: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "value", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationBodyDone", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The response of the `chainHead_call` method. + #[serde(rename_all = "camelCase")] + pub struct OperationCallDone { + /// The operation id of the event. + pub operation_id: String, + /// Hexadecimal-encoded output of the runtime function call. + pub output: Bytes, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationCallDone { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "OperationCallDone", + "operation_id", + &self.operation_id, + "output", + &&self.output, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationCallDone { + #[inline] + fn clone(&self) -> OperationCallDone { + OperationCallDone { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + output: ::core::clone::Clone::clone(&self.output), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationCallDone {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationCallDone { + #[inline] + fn eq(&self, other: &OperationCallDone) -> bool { + self.operation_id == other.operation_id + && self.output == other.output + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationCallDone { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationCallDone { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "output" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"output" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationCallDone; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationCallDone", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationCallDone with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Bytes, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct OperationCallDone with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(OperationCallDone { + operation_id: __field0, + output: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("output"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("output")? + } + }; + _serde::__private::Ok(OperationCallDone { + operation_id: __field0, + output: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "output", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationCallDone", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The response of the `chainHead_call` method. + #[serde(rename_all = "camelCase")] + pub struct OperationStorageItems { + /// The operation id of the event. + pub operation_id: String, + /// The resulting items. + pub items: VecDeque, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationStorageItems { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "OperationStorageItems", + "operation_id", + &self.operation_id, + "items", + &&self.items, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationStorageItems { + #[inline] + fn clone(&self) -> OperationStorageItems { + OperationStorageItems { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + items: ::core::clone::Clone::clone(&self.items), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationStorageItems {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationStorageItems { + #[inline] + fn eq(&self, other: &OperationStorageItems) -> bool { + self.operation_id == other.operation_id && self.items == other.items + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationStorageItems { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationStorageItems { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "items" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"items" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData< + OperationStorageItems, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationStorageItems; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationStorageItems", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationStorageItems with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + VecDeque, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct OperationStorageItems with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(OperationStorageItems { + operation_id: __field0, + items: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + VecDeque, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("items"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + VecDeque, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("items")? + } + }; + _serde::__private::Ok(OperationStorageItems { + operation_id: __field0, + items: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "items", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationStorageItems", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + OperationStorageItems, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate a problem during the operation. + #[serde(rename_all = "camelCase")] + pub struct OperationError { + /// The operation id of the event. + pub operation_id: String, + /// The reason of the error. + pub error: String, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "OperationError", + "operation_id", + &self.operation_id, + "error", + &&self.error, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationError { + #[inline] + fn clone(&self) -> OperationError { + OperationError { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + error: ::core::clone::Clone::clone(&self.error), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationError { + #[inline] + fn eq(&self, other: &OperationError) -> bool { + self.operation_id == other.operation_id && self.error == other.error + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationError { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "error" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"error" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationError; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationError", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationError with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct OperationError with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(OperationError { + operation_id: __field0, + error: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(OperationError { + operation_id: __field0, + error: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "error", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationError", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The storage result. + #[serde(rename_all = "camelCase")] + pub struct StorageResult { + /// The hex-encoded key of the result. + pub key: Bytes, + /// The result of the query. + #[serde(flatten)] + pub result: StorageResultType, + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "StorageResult", + "key", + &self.key, + "result", + &&self.result, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageResult { + #[inline] + fn clone(&self) -> StorageResult { + StorageResult { + key: ::core::clone::Clone::clone(&self.key), + result: ::core::clone::Clone::clone(&self.result), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageResult {} + #[automatically_derived] + impl ::core::cmp::PartialEq for StorageResult { + #[inline] + fn eq(&self, other: &StorageResult) -> bool { + self.key == other.key && self.result == other.result + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageResult { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for StorageResult { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field<'de> { + __field0, + __other(_serde::__private::de::Content<'de>), + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field<'de>; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_bool<__E>( + self, + __value: bool, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::Bool(__value), + ), + ) + } + fn visit_i8<__E>( + self, + __value: i8, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I8(__value), + ), + ) + } + fn visit_i16<__E>( + self, + __value: i16, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I16(__value), + ), + ) + } + fn visit_i32<__E>( + self, + __value: i32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I32(__value), + ), + ) + } + fn visit_i64<__E>( + self, + __value: i64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I64(__value), + ), + ) + } + fn visit_u8<__E>( + self, + __value: u8, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U8(__value), + ), + ) + } + fn visit_u16<__E>( + self, + __value: u16, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U16(__value), + ), + ) + } + fn visit_u32<__E>( + self, + __value: u32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U32(__value), + ), + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U64(__value), + ), + ) + } + fn visit_f32<__E>( + self, + __value: f32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::F32(__value), + ), + ) + } + fn visit_f64<__E>( + self, + __value: f64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::F64(__value), + ), + ) + } + fn visit_char<__E>( + self, + __value: char, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::Char(__value), + ), + ) + } + fn visit_unit<__E>( + self, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other(_serde::__private::de::Content::Unit), + ) + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "key" => _serde::__private::Ok(__Field::__field0), + _ => { + let __value = _serde::__private::de::Content::String( + _serde::__private::ToString::to_string(__value), + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"key" => _serde::__private::Ok(__Field::__field0), + _ => { + let __value = _serde::__private::de::Content::ByteBuf( + __value.to_vec(), + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_borrowed_str<__E>( + self, + __value: &'de str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "key" => _serde::__private::Ok(__Field::__field0), + _ => { + let __value = _serde::__private::de::Content::Str(__value); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_borrowed_bytes<__E>( + self, + __value: &'de [u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"key" => _serde::__private::Ok(__Field::__field0), + _ => { + let __value = _serde::__private::de::Content::Bytes( + __value, + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field<'de> { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = StorageResult; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct StorageResult", + ) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __collect = _serde::__private::Vec::< + _serde::__private::Option< + ( + _serde::__private::de::Content, + _serde::__private::de::Content, + ), + >, + >::new(); + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("key"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__other(__name) => { + __collect + .push( + _serde::__private::Some(( + __name, + _serde::de::MapAccess::next_value(&mut __map)?, + )), + ); + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("key")? + } + }; + let __field1: StorageResultType = _serde::de::Deserialize::deserialize( + _serde::__private::de::FlatMapDeserializer( + &mut __collect, + _serde::__private::PhantomData, + ), + )?; + _serde::__private::Ok(StorageResult { + key: __field0, + result: __field1, + }) + } + } + _serde::Deserializer::deserialize_map( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The type of the storage query. + #[serde(rename_all = "camelCase")] + pub enum StorageResultType { + /// Fetch the value of the provided key. + Value(Bytes), + /// Fetch the hash of the value of the provided key. + Hash(Bytes), + /// Fetch the closest descendant merkle value. + ClosestDescendantMerkleValue(Bytes), + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageResultType { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + StorageResultType::Value(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Value", + &__self_0, + ) + } + StorageResultType::Hash(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Hash", + &__self_0, + ) + } + StorageResultType::ClosestDescendantMerkleValue(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ClosestDescendantMerkleValue", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageResultType { + #[inline] + fn clone(&self) -> StorageResultType { + match self { + StorageResultType::Value(__self_0) => { + StorageResultType::Value( + ::core::clone::Clone::clone(__self_0), + ) + } + StorageResultType::Hash(__self_0) => { + StorageResultType::Hash( + ::core::clone::Clone::clone(__self_0), + ) + } + StorageResultType::ClosestDescendantMerkleValue(__self_0) => { + StorageResultType::ClosestDescendantMerkleValue( + ::core::clone::Clone::clone(__self_0), + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageResultType {} + #[automatically_derived] + impl ::core::cmp::PartialEq for StorageResultType { + #[inline] + fn eq(&self, other: &StorageResultType) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + StorageResultType::Value(__self_0), + StorageResultType::Value(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + StorageResultType::Hash(__self_0), + StorageResultType::Hash(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + StorageResultType::ClosestDescendantMerkleValue(__self_0), + StorageResultType::ClosestDescendantMerkleValue(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageResultType { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for StorageResultType { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 3", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "value" => _serde::__private::Ok(__Field::__field0), + "hash" => _serde::__private::Ok(__Field::__field1), + "closestDescendantMerkleValue" => { + _serde::__private::Ok(__Field::__field2) + } + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"value" => _serde::__private::Ok(__Field::__field0), + b"hash" => _serde::__private::Ok(__Field::__field1), + b"closestDescendantMerkleValue" => { + _serde::__private::Ok(__Field::__field2) + } + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = StorageResultType; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "enum StorageResultType", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Bytes, + >(__variant), + StorageResultType::Value, + ) + } + (__Field::__field1, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Bytes, + >(__variant), + StorageResultType::Hash, + ) + } + (__Field::__field2, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Bytes, + >(__variant), + StorageResultType::ClosestDescendantMerkleValue, + ) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "value", + "hash", + "closestDescendantMerkleValue", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "StorageResultType", + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The method response of `chainHead_body`, `chainHead_call` and `chainHead_storage`. + #[serde(rename_all = "camelCase")] + #[serde(tag = "result")] + pub enum MethodResponse { + /// The method has started. + Started(MethodResponseStarted), + /// The RPC server cannot handle the request at the moment. + LimitReached, + } + #[automatically_derived] + impl ::core::fmt::Debug for MethodResponse { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + MethodResponse::Started(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Started", + &__self_0, + ) + } + MethodResponse::LimitReached => { + ::core::fmt::Formatter::write_str(f, "LimitReached") + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for MethodResponse { + #[inline] + fn clone(&self) -> MethodResponse { + match self { + MethodResponse::Started(__self_0) => { + MethodResponse::Started( + ::core::clone::Clone::clone(__self_0), + ) + } + MethodResponse::LimitReached => MethodResponse::LimitReached, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for MethodResponse {} + #[automatically_derived] + impl ::core::cmp::PartialEq for MethodResponse { + #[inline] + fn eq(&self, other: &MethodResponse) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + MethodResponse::Started(__self_0), + MethodResponse::Started(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for MethodResponse { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for MethodResponse { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "started" => _serde::__private::Ok(__Field::__field0), + "limitReached" => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"started" => _serde::__private::Ok(__Field::__field0), + b"limitReached" => _serde::__private::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "started", + "limitReached", + ]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::< + __Field, + >::new("result", "internally tagged enum MethodResponse"), + )?; + let __deserializer = _serde::__private::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + MethodResponse::Started, + ) + } + __Field::__field1 => { + _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::InternallyTaggedUnitVisitor::new( + "MethodResponse", + "LimitReached", + ), + )?; + _serde::__private::Ok(MethodResponse::LimitReached) + } + } + } + } + }; + /// The `started` result of a method. + #[serde(rename_all = "camelCase")] + pub struct MethodResponseStarted { + /// The operation id of the response. + pub operation_id: String, + /// The number of items from the back of the `chainHead_storage` that have been discarded. + pub discarded_items: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug for MethodResponseStarted { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "MethodResponseStarted", + "operation_id", + &self.operation_id, + "discarded_items", + &&self.discarded_items, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for MethodResponseStarted { + #[inline] + fn clone(&self) -> MethodResponseStarted { + MethodResponseStarted { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + discarded_items: ::core::clone::Clone::clone( + &self.discarded_items, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for MethodResponseStarted {} + #[automatically_derived] + impl ::core::cmp::PartialEq for MethodResponseStarted { + #[inline] + fn eq(&self, other: &MethodResponseStarted) -> bool { + self.operation_id == other.operation_id + && self.discarded_items == other.discarded_items + } + } + #[automatically_derived] + impl ::core::cmp::Eq for MethodResponseStarted { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for MethodResponseStarted { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "discardedItems" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"discardedItems" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData< + MethodResponseStarted, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = MethodResponseStarted; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct MethodResponseStarted", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct MethodResponseStarted with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct MethodResponseStarted with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(MethodResponseStarted { + operation_id: __field0, + discarded_items: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + Option, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "discardedItems", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("discardedItems")? + } + }; + _serde::__private::Ok(MethodResponseStarted { + operation_id: __field0, + discarded_items: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "discardedItems", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "MethodResponseStarted", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + MethodResponseStarted, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The storage item received as parameter. + #[serde(rename_all = "camelCase")] + pub struct StorageQuery { + /// The provided key. + pub key: Key, + /// The type of the storage query. + #[serde(rename = "type")] + pub query_type: StorageQueryType, + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageQuery { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "StorageQuery", + "key", + &self.key, + "query_type", + &&self.query_type, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageQuery { + #[inline] + fn clone(&self) -> StorageQuery { + StorageQuery { + key: ::core::clone::Clone::clone(&self.key), + query_type: ::core::clone::Clone::clone(&self.query_type), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageQuery {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for StorageQuery { + #[inline] + fn eq(&self, other: &StorageQuery) -> bool { + self.key == other.key && self.query_type == other.query_type + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageQuery { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for StorageQuery + where + Key: _serde::Serialize, + { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "StorageQuery", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key", + &self.key, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "type", + &self.query_type, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Key> _serde::Deserialize<'de> for StorageQuery + where + Key: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "key" => _serde::__private::Ok(__Field::__field0), + "type" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"key" => _serde::__private::Ok(__Field::__field0), + b"type" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Key> + where + Key: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Key> _serde::de::Visitor<'de> for __Visitor<'de, Key> + where + Key: _serde::Deserialize<'de>, + { + type Value = StorageQuery; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct StorageQuery", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Key, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct StorageQuery with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + StorageQueryType, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct StorageQuery with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(StorageQuery { + key: __field0, + query_type: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + StorageQueryType, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("key"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("type"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + StorageQueryType, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("key")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("type")? + } + }; + _serde::__private::Ok(StorageQuery { + key: __field0, + query_type: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["key", "type"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "StorageQuery", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The type of the storage query. + #[serde(rename_all = "camelCase")] + pub enum StorageQueryType { + /// Fetch the value of the provided key. + Value, + /// Fetch the hash of the value of the provided key. + Hash, + /// Fetch the closest descendant merkle value. + ClosestDescendantMerkleValue, + /// Fetch the values of all descendants of they provided key. + DescendantsValues, + /// Fetch the hashes of the values of all descendants of they provided key. + DescendantsHashes, + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageQueryType { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + StorageQueryType::Value => "Value", + StorageQueryType::Hash => "Hash", + StorageQueryType::ClosestDescendantMerkleValue => { + "ClosestDescendantMerkleValue" + } + StorageQueryType::DescendantsValues => "DescendantsValues", + StorageQueryType::DescendantsHashes => "DescendantsHashes", + }, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageQueryType { + #[inline] + fn clone(&self) -> StorageQueryType { + match self { + StorageQueryType::Value => StorageQueryType::Value, + StorageQueryType::Hash => StorageQueryType::Hash, + StorageQueryType::ClosestDescendantMerkleValue => { + StorageQueryType::ClosestDescendantMerkleValue + } + StorageQueryType::DescendantsValues => { + StorageQueryType::DescendantsValues + } + StorageQueryType::DescendantsHashes => { + StorageQueryType::DescendantsHashes + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageQueryType {} + #[automatically_derived] + impl ::core::cmp::PartialEq for StorageQueryType { + #[inline] + fn eq(&self, other: &StorageQueryType) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageQueryType { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for StorageQueryType { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + StorageQueryType::Value => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 0u32, + "value", + ) + } + StorageQueryType::Hash => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 1u32, + "hash", + ) + } + StorageQueryType::ClosestDescendantMerkleValue => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 2u32, + "closestDescendantMerkleValue", + ) + } + StorageQueryType::DescendantsValues => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 3u32, + "descendantsValues", + ) + } + StorageQueryType::DescendantsHashes => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 4u32, + "descendantsHashes", + ) + } + } + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for StorageQueryType { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 5", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "value" => _serde::__private::Ok(__Field::__field0), + "hash" => _serde::__private::Ok(__Field::__field1), + "closestDescendantMerkleValue" => { + _serde::__private::Ok(__Field::__field2) + } + "descendantsValues" => { + _serde::__private::Ok(__Field::__field3) + } + "descendantsHashes" => { + _serde::__private::Ok(__Field::__field4) + } + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"value" => _serde::__private::Ok(__Field::__field0), + b"hash" => _serde::__private::Ok(__Field::__field1), + b"closestDescendantMerkleValue" => { + _serde::__private::Ok(__Field::__field2) + } + b"descendantsValues" => { + _serde::__private::Ok(__Field::__field3) + } + b"descendantsHashes" => { + _serde::__private::Ok(__Field::__field4) + } + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = StorageQueryType; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "enum StorageQueryType", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(StorageQueryType::Value) + } + (__Field::__field1, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(StorageQueryType::Hash) + } + (__Field::__field2, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok( + StorageQueryType::ClosestDescendantMerkleValue, + ) + } + (__Field::__field3, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(StorageQueryType::DescendantsValues) + } + (__Field::__field4, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(StorageQueryType::DescendantsHashes) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "value", + "hash", + "closestDescendantMerkleValue", + "descendantsValues", + "descendantsHashes", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "StorageQueryType", + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// A subscription which returns follow events, and ends when a Stop event occurs. + pub struct FollowSubscription { + sub: RpcSubscription>, + done: bool, + } + impl FollowSubscription { + /// Fetch the next item in the stream. + pub async fn next(&mut self) -> Option<::Item> { + ::next(self).await + } + /// Fetch the subscription ID for the stream. + pub fn subscription_id(&self) -> Option<&str> { + self.sub.subscription_id() + } + } + impl Stream for FollowSubscription { + type Item = > as Stream>::Item; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + if self.done { + return Poll::Ready(None); + } + let res = self.sub.poll_next_unpin(cx); + if let Poll::Ready(Some(Ok(FollowEvent::Stop))) = &res { + self.done = true; + } + res + } + } + /// A subscription which returns transaction status events, stopping + /// when no more events will be sent. + pub struct TransactionSubscription { + sub: RpcSubscription>, + done: bool, + } + impl TransactionSubscription { + /// Fetch the next item in the stream. + pub async fn next(&mut self) -> Option<::Item> { + ::next(self).await + } + } + impl Stream for TransactionSubscription { + type Item = > as Stream>::Item; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + if self.done { + return Poll::Ready(None); + } + let res = self.sub.poll_next_unpin(cx); + if let Poll::Ready(Some(Ok(res))) = &res { + if match res { + TransactionStatus::Dropped { .. } + | TransactionStatus::Error { .. } + | TransactionStatus::Invalid { .. } + | TransactionStatus::Finalized { .. } => true, + _ => false, + } { + self.done = true; + } + } + res + } + } + /// Transaction progress events + #[serde(rename_all = "camelCase")] + #[serde(tag = "event")] + pub enum TransactionStatus { + /// Transaction is part of the future queue. + Validated, + /// The transaction has been broadcast to other nodes. + Broadcasted { + /// Number of peers it's been broadcast to. + num_peers: u32, + }, + /// Transaction has been included in block with given details. + /// Null is returned if the transaction is no longer in any block + /// of the best chain. + BestChainBlockIncluded { + /// Details of the block it's been seen in. + block: Option>, + }, + /// The transaction is in a block that's been finalized. + Finalized { + /// Details of the block it's been seen in. + block: TransactionBlockDetails, + }, + /// Something went wrong in the node. + Error { + /// Human readable message; what went wrong. + error: String, + }, + /// Transaction is invalid (bad nonce, signature etc). + Invalid { + /// Human readable message; why was it invalid. + error: String, + }, + /// The transaction was dropped. + Dropped { + /// Was the transaction broadcasted to other nodes before being dropped? + broadcasted: bool, + /// Human readable message; why was it dropped. + error: String, + }, + } + #[automatically_derived] + impl ::core::fmt::Debug + for TransactionStatus { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionStatus::Validated => { + ::core::fmt::Formatter::write_str(f, "Validated") + } + TransactionStatus::Broadcasted { num_peers: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Broadcasted", + "num_peers", + &__self_0, + ) + } + TransactionStatus::BestChainBlockIncluded { block: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "BestChainBlockIncluded", + "block", + &__self_0, + ) + } + TransactionStatus::Finalized { block: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Finalized", + "block", + &__self_0, + ) + } + TransactionStatus::Error { error: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Error", + "error", + &__self_0, + ) + } + TransactionStatus::Invalid { error: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Invalid", + "error", + &__self_0, + ) + } + TransactionStatus::Dropped { + broadcasted: __self_0, + error: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Dropped", + "broadcasted", + __self_0, + "error", + &__self_1, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone + for TransactionStatus { + #[inline] + fn clone(&self) -> TransactionStatus { + match self { + TransactionStatus::Validated => TransactionStatus::Validated, + TransactionStatus::Broadcasted { num_peers: __self_0 } => { + TransactionStatus::Broadcasted { + num_peers: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::BestChainBlockIncluded { block: __self_0 } => { + TransactionStatus::BestChainBlockIncluded { + block: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Finalized { block: __self_0 } => { + TransactionStatus::Finalized { + block: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Error { error: __self_0 } => { + TransactionStatus::Error { + error: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Invalid { error: __self_0 } => { + TransactionStatus::Invalid { + error: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Dropped { + broadcasted: __self_0, + error: __self_1, + } => { + TransactionStatus::Dropped { + broadcasted: ::core::clone::Clone::clone(__self_0), + error: ::core::clone::Clone::clone(__self_1), + } + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionStatus {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for TransactionStatus { + #[inline] + fn eq(&self, other: &TransactionStatus) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionStatus::Broadcasted { num_peers: __self_0 }, + TransactionStatus::Broadcasted { num_peers: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::BestChainBlockIncluded { + block: __self_0, + }, + TransactionStatus::BestChainBlockIncluded { + block: __arg1_0, + }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Finalized { block: __self_0 }, + TransactionStatus::Finalized { block: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Error { error: __self_0 }, + TransactionStatus::Error { error: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Invalid { error: __self_0 }, + TransactionStatus::Invalid { error: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Dropped { + broadcasted: __self_0, + error: __self_1, + }, + TransactionStatus::Dropped { + broadcasted: __arg1_0, + error: __arg1_1, + }, + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TransactionStatus { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq< + Option>, + >; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for TransactionStatus + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __field6, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + 5u64 => _serde::__private::Ok(__Field::__field5), + 6u64 => _serde::__private::Ok(__Field::__field6), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 7", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "validated" => _serde::__private::Ok(__Field::__field0), + "broadcasted" => _serde::__private::Ok(__Field::__field1), + "bestChainBlockIncluded" => { + _serde::__private::Ok(__Field::__field2) + } + "finalized" => _serde::__private::Ok(__Field::__field3), + "error" => _serde::__private::Ok(__Field::__field4), + "invalid" => _serde::__private::Ok(__Field::__field5), + "dropped" => _serde::__private::Ok(__Field::__field6), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"validated" => _serde::__private::Ok(__Field::__field0), + b"broadcasted" => _serde::__private::Ok(__Field::__field1), + b"bestChainBlockIncluded" => { + _serde::__private::Ok(__Field::__field2) + } + b"finalized" => _serde::__private::Ok(__Field::__field3), + b"error" => _serde::__private::Ok(__Field::__field4), + b"invalid" => _serde::__private::Ok(__Field::__field5), + b"dropped" => _serde::__private::Ok(__Field::__field6), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "validated", + "broadcasted", + "bestChainBlockIncluded", + "finalized", + "error", + "invalid", + "dropped", + ]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::< + __Field, + >::new("event", "internally tagged enum TransactionStatus"), + )?; + let __deserializer = _serde::__private::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::InternallyTaggedUnitVisitor::new( + "TransactionStatus", + "Validated", + ), + )?; + _serde::__private::Ok(TransactionStatus::Validated) + } + __Field::__field1 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "num_peers" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"num_peers" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Broadcasted", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Broadcasted with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Broadcasted { + num_peers: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "num_peers", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("num_peers")? + } + }; + _serde::__private::Ok(TransactionStatus::Broadcasted { + num_peers: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["num_peers"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field2 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "block" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"block" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::BestChainBlockIncluded", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Option>, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::BestChainBlockIncluded with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::BestChainBlockIncluded { + block: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option< + Option>, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("block"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option>, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("block")? + } + }; + _serde::__private::Ok(TransactionStatus::BestChainBlockIncluded { + block: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["block"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field3 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "block" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"block" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Finalized", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + TransactionBlockDetails, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Finalized with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Finalized { + block: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option< + TransactionBlockDetails, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("block"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + TransactionBlockDetails, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("block")? + } + }; + _serde::__private::Ok(TransactionStatus::Finalized { + block: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["block"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field4 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Error", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Error with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Error { + error: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(TransactionStatus::Error { + error: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["error"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field5 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Invalid", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Invalid with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Invalid { + error: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(TransactionStatus::Invalid { + error: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["error"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field6 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "broadcasted" => _serde::__private::Ok(__Field::__field0), + "error" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"broadcasted" => _serde::__private::Ok(__Field::__field0), + b"error" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Dropped", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + bool, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Dropped with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct variant TransactionStatus::Dropped with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Dropped { + broadcasted: __field0, + error: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "broadcasted", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("broadcasted")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(TransactionStatus::Dropped { + broadcasted: __field0, + error: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "broadcasted", + "error", + ]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + } + } + }; + /// Details of a block that a transaction is seen in. + pub struct TransactionBlockDetails { + /// The block hash. + pub hash: Hash, + /// The index of the transaction in the block. + #[serde(with = "unsigned_number_as_string")] + pub index: u64, + } + #[automatically_derived] + impl ::core::fmt::Debug + for TransactionBlockDetails { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "TransactionBlockDetails", + "hash", + &self.hash, + "index", + &&self.index, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for TransactionBlockDetails { + #[inline] + fn clone(&self) -> TransactionBlockDetails { + TransactionBlockDetails { + hash: ::core::clone::Clone::clone(&self.hash), + index: ::core::clone::Clone::clone(&self.index), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for TransactionBlockDetails {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for TransactionBlockDetails { + #[inline] + fn eq(&self, other: &TransactionBlockDetails) -> bool { + self.hash == other.hash && self.index == other.index + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for TransactionBlockDetails { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> + for TransactionBlockDetails + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "hash" => _serde::__private::Ok(__Field::__field0), + "index" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"hash" => _serde::__private::Ok(__Field::__field0), + b"index" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionBlockDetails, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionBlockDetails; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct TransactionBlockDetails", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct TransactionBlockDetails with 2 elements", + ), + ); + } + }; + let __field1 = match { + #[doc(hidden)] + struct __DeserializeWith<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + value: u64, + phantom: _serde::__private::PhantomData< + TransactionBlockDetails, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::Deserialize<'de> + for __DeserializeWith<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: unsigned_number_as_string::deserialize( + __deserializer, + )?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de, Hash>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct TransactionBlockDetails with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(TransactionBlockDetails { + hash: __field0, + index: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("hash"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("index"), + ); + } + __field1 = _serde::__private::Some({ + #[doc(hidden)] + struct __DeserializeWith<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + value: u64, + phantom: _serde::__private::PhantomData< + TransactionBlockDetails, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::Deserialize<'de> + for __DeserializeWith<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: unsigned_number_as_string::deserialize( + __deserializer, + )?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + match _serde::de::MapAccess::next_value::< + __DeserializeWith<'de, Hash>, + >(&mut __map) { + _serde::__private::Ok(__wrapper) => __wrapper.value, + _serde::__private::Err(__err) => { + return _serde::__private::Err(__err); + } + } + }); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("hash")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::missing_field("index"), + ); + } + }; + _serde::__private::Ok(TransactionBlockDetails { + hash: __field0, + index: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["hash", "index"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "TransactionBlockDetails", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionBlockDetails, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Hex-serialized shim for `Vec`. + pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec); + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Bytes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Bytes { + #[inline] + fn eq(&self, other: &Bytes) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Bytes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Bytes { + #[inline] + fn clone(&self) -> Bytes { + Bytes(::core::clone::Clone::clone(&self.0)) + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Bytes { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "Bytes", + { + #[doc(hidden)] + struct __SerializeWith<'__a> { + values: (&'__a Vec,), + phantom: _serde::__private::PhantomData, + } + impl<'__a> _serde::Serialize for __SerializeWith<'__a> { + fn serialize<__S>( + &self, + __s: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + impl_serde::serialize::serialize(self.values.0, __s) + } + } + &__SerializeWith { + values: (&self.0,), + phantom: _serde::__private::PhantomData::, + } + }, + ) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Bytes { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Bytes; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "tuple struct Bytes", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: Vec = impl_serde::serialize::deserialize( + __e, + )?; + _serde::__private::Ok(Bytes(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match { + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: Vec, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: impl_serde::serialize::deserialize(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct Bytes with 1 element", + ), + ); + } + }; + _serde::__private::Ok(Bytes(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "Bytes", + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::hash::Hash for Bytes { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Bytes { + #[inline] + fn partial_cmp( + &self, + other: &Bytes, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Bytes { + #[inline] + fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Bytes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Bytes", + &&self.0, + ) + } + } + impl std::ops::Deref for Bytes { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.0[..] + } + } + impl From> for Bytes { + fn from(s: Vec) -> Self { + Bytes(s) + } + } + fn to_hex(bytes: impl AsRef<[u8]>) -> String { + { + let res = ::alloc::fmt::format( + format_args!("0x{0}", hex::encode(bytes.as_ref())), + ); + res + } + } + /// Attempt to deserialize either a string or integer into an integer. + /// See + pub(crate) mod unsigned_number_as_string { + use serde::de::{Deserializer, Visitor}; + use std::fmt; + /// Deserialize a number from a string or number. + pub fn deserialize<'de, N: From, D>( + deserializer: D, + ) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(NumberVisitor(std::marker::PhantomData)) + } + struct NumberVisitor(std::marker::PhantomData); + impl<'de, N: From> Visitor<'de> for NumberVisitor { + type Value = N; + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .write_str("an unsigned integer or a string containing one") + } + fn visit_str( + self, + v: &str, + ) -> Result { + let n: u64 = v.parse().map_err(serde::de::Error::custom)?; + Ok(n.into()) + } + fn visit_u64( + self, + v: u64, + ) -> Result { + Ok(v.into()) + } + } + } + /// A temporary shim to decode "spec.apis" if it comes back as an array like: + /// + /// ```text + /// [["0xABC", 1], ["0xCDE", 2]] + /// ``` + /// + /// The expected format (which this also supports deserializing from) is: + /// + /// ```text + /// { "0xABC": 1, "0xCDE": 2 } + /// ``` + /// + /// We can delete this when the correct format is being returned. + /// + /// Adapted from + pub(crate) mod hashmap_as_tuple_list { + use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; + use std::collections::HashMap; + use std::fmt; + use std::hash::{BuildHasher, Hash}; + use std::marker::PhantomData; + /// Deserialize a [`HashMap`] from a list of tuples or object + pub fn deserialize<'de, K, V, BH, D>( + deserializer: D, + ) -> Result, D::Error> + where + D: Deserializer<'de>, + K: Eq + Hash + Deserialize<'de>, + V: Deserialize<'de>, + BH: BuildHasher + Default, + { + deserializer.deserialize_any(HashMapVisitor(PhantomData)) + } + #[allow(clippy::type_complexity)] + struct HashMapVisitor(PhantomData HashMap>); + impl<'de, K, V, BH> Visitor<'de> for HashMapVisitor + where + K: Deserialize<'de> + Eq + Hash, + V: Deserialize<'de>, + BH: BuildHasher + Default, + { + type Value = HashMap; + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a list of key-value pairs") + } + fn visit_map(self, mut m: A) -> Result + where + A: serde::de::MapAccess<'de>, + { + let mut map = HashMap::with_capacity_and_hasher( + m.size_hint().unwrap_or(0), + BH::default(), + ); + while let Some((key, value)) = m.next_entry()? { + map.insert(key, value); + } + Ok(map) + } + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let mut map = HashMap::with_capacity_and_hasher( + seq.size_hint().unwrap_or(0), + BH::default(), + ); + while let Some((key, value)) = seq.next_element()? { + map.insert(key, value); + } + Ok(map) + } + } + } + } + use self::rpc_methods::{ + FollowEvent, MethodResponse, RuntimeEvent, StorageQuery, StorageQueryType, + StorageResultType, + }; + use crate::backend::{ + rpc::RpcClient, Backend, BlockRef, BlockRefT, RuntimeVersion, + StorageResponse, StreamOf, StreamOfResults, TransactionStatus, + }; + use crate::config::BlockHash; + use crate::error::{Error, RpcError}; + use crate::Config; + use async_trait::async_trait; + use follow_stream_driver::{FollowStreamDriver, FollowStreamDriverHandle}; + use futures::{Stream, StreamExt}; + use std::collections::HashMap; + use std::sync::Arc; + use std::task::Poll; + use storage_items::StorageItems; + pub use rpc_methods::UnstableRpcMethods; + /// Configure and build an [`UnstableBackend`]. + pub struct UnstableBackendBuilder { + max_block_life: usize, + _marker: std::marker::PhantomData, + } + impl Default for UnstableBackendBuilder { + fn default() -> Self { + Self::new() + } + } + impl UnstableBackendBuilder { + /// Create a new [`UnstableBackendBuilder`]. + pub fn new() -> Self { + Self { + max_block_life: usize::MAX, + _marker: std::marker::PhantomData, + } + } + /// The age of a block is defined here as the difference between the current finalized block number + /// and the block number of a given block. Once the difference equals or exceeds the number given + /// here, the block is unpinned. + /// + /// By default, we will never automatically unpin blocks, but if the number of pinned blocks that we + /// keep hold of exceeds the number that the server can tolerate, then a `stop` event is generated and + /// we are forced to resubscribe, losing any pinned blocks. + pub fn max_block_life(mut self, max_block_life: usize) -> Self { + self.max_block_life = max_block_life; + self + } + /// Given an [`RpcClient`] to use to make requests, this returns a tuple of an [`UnstableBackend`], + /// which implements the [`Backend`] trait, and an [`UnstableBackendDriver`] which must be polled in + /// order for the backend to make progress. + pub fn build( + self, + client: RpcClient, + ) -> (UnstableBackend, UnstableBackendDriver) { + let rpc_methods = UnstableRpcMethods::new(client); + let follow_stream = follow_stream::FollowStream::< + T::Hash, + >::from_methods(rpc_methods.clone()); + let follow_stream_unpin = follow_stream_unpin::FollowStreamUnpin::< + T::Hash, + >::from_methods(follow_stream, rpc_methods.clone(), self.max_block_life); + let follow_stream_driver = FollowStreamDriver::new(follow_stream_unpin); + let backend = UnstableBackend { + methods: rpc_methods, + follow_handle: follow_stream_driver.handle(), + }; + let driver = UnstableBackendDriver { + driver: follow_stream_driver, + }; + (backend, driver) + } + } + /// Driver for the [`UnstableBackend`]. This must be polled in order for the + /// backend to make progress. + pub struct UnstableBackendDriver { + driver: FollowStreamDriver, + } + #[automatically_derived] + impl ::core::fmt::Debug + for UnstableBackendDriver + where + T::Hash: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "UnstableBackendDriver", + "driver", + &&self.driver, + ) + } + } + impl Stream for UnstableBackendDriver { + type Item = as Stream>::Item; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.driver.poll_next_unpin(cx) + } + } + /// The unstable backend. + pub struct UnstableBackend { + methods: UnstableRpcMethods, + follow_handle: FollowStreamDriverHandle, + } + #[automatically_derived] + impl ::core::fmt::Debug for UnstableBackend + where + T::Hash: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "UnstableBackend", + "methods", + &self.methods, + "follow_handle", + &&self.follow_handle, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for UnstableBackend + where + T::Hash: ::core::clone::Clone, + { + #[inline] + fn clone(&self) -> UnstableBackend { + UnstableBackend { + methods: ::core::clone::Clone::clone(&self.methods), + follow_handle: ::core::clone::Clone::clone(&self.follow_handle), + } + } + } + impl UnstableBackend { + /// Configure and construct an [`UnstableBackend`] and the associated [`UnstableBackendDriver`]. + pub fn builder() -> UnstableBackendBuilder { + UnstableBackendBuilder::new() + } + /// Stream block headers based on the provided filter fn + async fn stream_headers( + &self, + f: F, + ) -> Result)>, Error> + where + F: Fn(FollowEvent>) -> I + Copy + + Send + 'static, + I: IntoIterator> + Send + + 'static, + ::IntoIter: Send, + { + let sub_id = get_subscription_id(&self.follow_handle).await?; + let sub_id = Arc::new(sub_id); + let methods = self.methods.clone(); + let headers = self + .follow_handle + .subscribe() + .events() + .flat_map(move |ev| { + let sub_id = sub_id.clone(); + let methods = methods.clone(); + let block_refs = f(ev).into_iter(); + futures::stream::iter(block_refs) + .filter_map(move |block_ref| { + let sub_id = sub_id.clone(); + let methods = methods.clone(); + async move { + let res = methods + .chainhead_unstable_header(&sub_id, block_ref.hash()) + .await + .transpose()?; + let header = match res { + Ok(header) => header, + Err(e) => return Some(Err(e)), + }; + Some(Ok((header, block_ref.into()))) + } + }) + }); + Ok(StreamOf(Box::pin(headers))) + } + } + impl BlockRefT + for follow_stream_unpin::BlockRef {} + impl From> + for BlockRef { + fn from(b: follow_stream_unpin::BlockRef) -> Self { + BlockRef::new(b.hash(), b) + } + } + impl super::sealed::Sealed for UnstableBackend {} + impl Backend for UnstableBackend { + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_values<'life0, 'async_trait>( + &'life0 self, + keys: Vec>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let keys = keys; + let at = at; + let __ret: Result, Error> = { + let queries = keys + .iter() + .map(|key| StorageQuery { + key: &**key, + query_type: StorageQueryType::Value, + }); + let storage_items = StorageItems::from_methods( + queries, + at, + &__self.follow_handle, + __self.methods.clone(), + ) + .await?; + let storage_result_stream = storage_items + .filter_map(|val| async move { + let val = match val { + Ok(val) => val, + Err(e) => return Some(Err(e)), + }; + let StorageResultType::Value(result) = val.result else { + return None; + }; + Some( + Ok(StorageResponse { + key: val.key.0, + value: result.0, + }), + ) + }); + Ok(StreamOf(Box::pin(storage_result_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_descendant_keys<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>, Error>, + > { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result>, Error> = { + let query = StorageQuery { + key: &*key, + query_type: StorageQueryType::DescendantsHashes, + }; + let storage_items = StorageItems::from_methods( + std::iter::once(query), + at, + &__self.follow_handle, + __self.methods.clone(), + ) + .await?; + let storage_result_stream = storage_items + .map(|val| val.map(|v| v.key.0)); + Ok(StreamOf(Box::pin(storage_result_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_descendant_values<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result, Error> = { + let query = StorageQuery { + key: &*key, + query_type: StorageQueryType::DescendantsValues, + }; + let storage_items = StorageItems::from_methods( + std::iter::once(query), + at, + &__self.follow_handle, + __self.methods.clone(), + ) + .await?; + let storage_result_stream = storage_items + .filter_map(|val| async move { + let val = match val { + Ok(val) => val, + Err(e) => return Some(Err(e)), + }; + let StorageResultType::Value(result) = val.result else { + return None; + }; + Some( + Ok(StorageResponse { + key: val.key.0, + value: result.0, + }), + ) + }); + Ok(StreamOf(Box::pin(storage_result_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn genesis_hash<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let __ret: Result = { + __self.methods.chainspec_v1_genesis_hash().await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn block_header<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result, Error> = { + let sub_id = get_subscription_id(&__self.follow_handle).await?; + __self.methods.chainhead_unstable_header(&sub_id, at).await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn block_body<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>>, Error>, + > { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result>>, Error> = { + let sub_id = get_subscription_id(&__self.follow_handle).await?; + let follow_events = __self.follow_handle.subscribe().events(); + let status = __self + .methods + .chainhead_unstable_body(&sub_id, at) + .await?; + let operation_id = match status { + MethodResponse::LimitReached => { + return Err( + RpcError::request_rejected("limit reached").into(), + ); + } + MethodResponse::Started(s) => s.operation_id, + }; + let mut exts_stream = follow_events + .filter_map(|ev| { + let FollowEvent::OperationBodyDone(body) = ev else { + return std::future::ready(None); + }; + if body.operation_id != operation_id { + return std::future::ready(None); + } + let exts: Vec<_> = body + .value + .into_iter() + .map(|ext| ext.0) + .collect(); + std::future::ready(Some(exts)) + }); + Ok(exts_stream.next().await) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn latest_finalized_block_ref<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result, Error> = { + let next_ref: Option> = __self + .follow_handle + .subscribe() + .events() + .filter_map(|ev| { + let out = match ev { + FollowEvent::Initialized(init) => { + Some(init.finalized_block_hash.into()) + } + _ => None, + }; + std::future::ready(out) + }) + .next() + .await; + next_ref.ok_or_else(|| RpcError::SubscriptionDropped.into()) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn current_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let __ret: Result = { + let runtime_version = __self + .stream_runtime_version() + .await? + .next() + .await; + match runtime_version { + None => Err(Error::Rpc(RpcError::SubscriptionDropped)), + Some(Err(e)) => Err(e), + Some(Ok(version)) => Ok(version), + } + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result, Error> = { + let mut runtimes = HashMap::new(); + let runtime_stream = __self + .follow_handle + .subscribe() + .events() + .filter_map(move |ev| { + let output = match ev { + FollowEvent::Initialized(ev) => { + runtimes.remove(&ev.finalized_block_hash.hash()); + ev.finalized_block_runtime + } + FollowEvent::NewBlock(ev) => { + if let Some(runtime) = ev.new_runtime { + runtimes.insert(ev.block_hash.hash(), runtime); + } + None + } + FollowEvent::Finalized(ev) => { + let next_runtime = { + let mut it = ev + .finalized_block_hashes + .iter() + .rev() + .filter_map(|h| runtimes.get(&h.hash()).cloned()) + .peekable(); + let next = it.next(); + if it.peek().is_some() { + { + use ::tracing::__macro_support::Callsite as _; + static __CALLSITE: ::tracing::callsite::DefaultCallsite = { + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "event subxt/src/backend/unstable/mod.rs:377", + "subxt", + ::tracing::Level::WARN, + ::core::option::Option::Some( + "subxt/src/backend/unstable/mod.rs", + ), + ::core::option::Option::Some(377u32), + ::core::option::Option::Some("subxt::backend::unstable"), + ::tracing_core::field::FieldSet::new( + &["message"], + ::tracing_core::callsite::Identifier(&__CALLSITE), + ), + ::tracing::metadata::Kind::EVENT, + ) + }; + ::tracing::callsite::DefaultCallsite::new(&META) + }; + let enabled = ::tracing::Level::WARN + <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::WARN + <= ::tracing::level_filters::LevelFilter::current() + && { + let interest = __CALLSITE.interest(); + !interest.is_never() + && ::tracing::__macro_support::__is_enabled( + __CALLSITE.metadata(), + interest, + ) + }; + if enabled { + (|value_set: ::tracing::field::ValueSet| { + let meta = __CALLSITE.metadata(); + ::tracing::Event::dispatch(meta, &value_set); + })({ + #[allow(unused_imports)] + use ::tracing::field::{debug, display, Value}; + let mut iter = __CALLSITE.metadata().fields().iter(); + __CALLSITE + .metadata() + .fields() + .value_set( + &[ + ( + &::core::iter::Iterator::next(&mut iter) + .expect("FieldSet corrupted (this is a bug)"), + ::core::option::Option::Some( + &format_args!( + "Several runtime upgrades in the finalized blocks but only the latest runtime upgrade is returned" + ) as &dyn Value, + ), + ), + ], + ) + }); + } else { + } + }; + } + next + }; + for block in ev + .finalized_block_hashes + .iter() + .chain(ev.pruned_block_hashes.iter()) + { + runtimes.remove(&block.hash()); + } + next_runtime + } + _ => None, + }; + let runtime_event = match output { + None => return std::future::ready(None), + Some(ev) => ev, + }; + let runtime_details = match runtime_event { + RuntimeEvent::Invalid(err) => { + return std::future::ready( + Some(Err(Error::Other(err.error))), + ); + } + RuntimeEvent::Valid(ev) => ev, + }; + std::future::ready( + Some( + Ok(RuntimeVersion { + spec_version: runtime_details.spec.spec_version, + transaction_version: runtime_details + .spec + .transaction_version, + }), + ), + ) + }); + Ok(StreamOf(Box::pin(runtime_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_all_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + __self + .stream_headers(|ev| match ev { + FollowEvent::Initialized(ev) => { + Some(ev.finalized_block_hash) + } + FollowEvent::NewBlock(ev) => Some(ev.block_hash), + _ => None, + }) + .await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_best_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + __self + .stream_headers(|ev| match ev { + FollowEvent::Initialized(ev) => { + Some(ev.finalized_block_hash) + } + FollowEvent::BestBlockChanged(ev) => { + Some(ev.best_block_hash) + } + _ => None, + }) + .await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_finalized_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + __self + .stream_headers(|ev| match ev { + FollowEvent::Initialized(ev) => { + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ev.finalized_block_hash]), + ) + } + FollowEvent::Finalized(ev) => ev.finalized_block_hashes, + _ => ::alloc::vec::Vec::new(), + }) + .await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn submit_transaction<'life0, 'life1, 'async_trait>( + &'life0 self, + extrinsic: &'life1 [u8], + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults>, + Error, + > = { + enum SeenBlockMarker { + New, + Finalized, + } + let mut seen_blocks_sub = __self + .follow_handle + .subscribe() + .events(); + let mut tx_progress = __self + .methods + .transaction_unstable_submit_and_watch(extrinsic) + .await?; + let mut seen_blocks = HashMap::new(); + let mut done = false; + let mut finalized_hash: Option = None; + let start_instant = instant::Instant::now(); + let err_other = |s: &str| Some(Err(Error::Other(s.into()))); + let tx_stream = futures::stream::poll_fn(move |cx| { + loop { + if done { + return Poll::Ready(None); + } + if start_instant.elapsed().as_secs() > 240 { + return Poll::Ready( + err_other( + "Timeout waiting for the transaction to be finalized", + ), + ); + } + let follow_ev_poll = match seen_blocks_sub + .poll_next_unpin(cx) + { + Poll::Ready(None) => { + return Poll::Ready( + err_other("chainHead_follow stream ended unexpectedly"), + ); + } + Poll::Ready(Some(follow_ev)) => Poll::Ready(follow_ev), + Poll::Pending => Poll::Pending, + }; + let follow_ev_is_pending = follow_ev_poll.is_pending(); + if let Poll::Ready(follow_ev) = follow_ev_poll { + match follow_ev { + FollowEvent::NewBlock(ev) => { + if finalized_hash.is_none() { + seen_blocks + .insert( + ev.block_hash.hash(), + (SeenBlockMarker::New, ev.block_hash), + ); + } + } + FollowEvent::Finalized(ev) => { + for block_ref in ev.finalized_block_hashes { + seen_blocks + .insert( + block_ref.hash(), + (SeenBlockMarker::Finalized, block_ref), + ); + } + } + FollowEvent::Stop => { + return Poll::Ready( + err_other( + "chainHead_follow emitted 'stop' event during transaction submission", + ), + ); + } + _ => {} + } + continue; + } + if let Some(hash) = &finalized_hash { + if let Some((SeenBlockMarker::Finalized, block_ref)) + = seen_blocks.remove(hash) + { + done = true; + let ev = TransactionStatus::InFinalizedBlock { + hash: block_ref.into(), + }; + return Poll::Ready(Some(Ok(ev))); + } else { + seen_blocks.clear(); + if follow_ev_is_pending { + return Poll::Pending; + } else { + continue; + } + } + } + let tx_progress_ev = match tx_progress.poll_next_unpin(cx) { + Poll::Pending => return Poll::Pending, + Poll::Ready(None) => { + return Poll::Ready( + err_other( + "No more transaction progress events, but we haven't seen a Finalized one yet", + ), + ); + } + Poll::Ready(Some(Err(e))) => { + return Poll::Ready(Some(Err(e))); + } + Poll::Ready(Some(Ok(ev))) => ev, + }; + let tx_progress_ev = match tx_progress_ev { + rpc_methods::TransactionStatus::Finalized { block } => { + finalized_hash = Some(block.hash); + continue; + } + rpc_methods::TransactionStatus::BestChainBlockIncluded { + block: Some(block), + } => { + let block_ref = match seen_blocks.get(&block.hash) { + Some((_, block_ref)) => block_ref.clone().into(), + None => BlockRef::from_hash(block.hash), + }; + TransactionStatus::InBestBlock { + hash: block_ref, + } + } + rpc_methods::TransactionStatus::BestChainBlockIncluded { + block: None, + } => TransactionStatus::NoLongerInBestBlock, + rpc_methods::TransactionStatus::Broadcasted { + num_peers, + } => { + TransactionStatus::Broadcasted { + num_peers, + } + } + rpc_methods::TransactionStatus::Dropped { error, .. } => { + TransactionStatus::Dropped { + message: error, + } + } + rpc_methods::TransactionStatus::Error { error } => { + TransactionStatus::Dropped { + message: error, + } + } + rpc_methods::TransactionStatus::Invalid { error } => { + TransactionStatus::Invalid { + message: error, + } + } + rpc_methods::TransactionStatus::Validated => { + TransactionStatus::Validated + } + }; + return Poll::Ready(Some(Ok(tx_progress_ev))); + } + }); + Ok(StreamOf(Box::pin(tx_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn call<'life0, 'life1, 'life2, 'async_trait>( + &'life0 self, + method: &'life1 str, + call_parameters: Option<&'life2 [u8]>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + 'life2: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::, Error>> { + return __ret; + } + let __self = self; + let call_parameters = call_parameters; + let at = at; + let __ret: Result, Error> = { + let sub_id = get_subscription_id(&__self.follow_handle).await?; + let follow_events = __self.follow_handle.subscribe().events(); + let call_parameters = call_parameters.unwrap_or(&[]); + let status = __self + .methods + .chainhead_unstable_call( + &sub_id, + at, + method, + call_parameters, + ) + .await?; + let operation_id = match status { + MethodResponse::LimitReached => { + return Err( + RpcError::request_rejected("limit reached").into(), + ); + } + MethodResponse::Started(s) => s.operation_id, + }; + let mut call_data_stream = follow_events + .filter_map(|ev| { + let FollowEvent::OperationCallDone(body) = ev else { + return std::future::ready(None); + }; + if body.operation_id != operation_id { + return std::future::ready(None); + } + std::future::ready(Some(body.output.0)) + }); + call_data_stream + .next() + .await + .ok_or_else(|| RpcError::SubscriptionDropped.into()) + }; + #[allow(unreachable_code)] __ret + }) + } + } + /// A helper to obtain a subscription ID. + async fn get_subscription_id( + follow_handle: &FollowStreamDriverHandle, + ) -> Result { + let Some(sub_id) = follow_handle.subscribe().subscription_id().await else { + return Err(RpcError::SubscriptionDropped.into()); + }; + Ok(sub_id) + } + } + use crate::error::Error; + use crate::metadata::Metadata; + use crate::Config; + use async_trait::async_trait; + use codec::{Decode, Encode}; + use futures::{Stream, StreamExt}; + use std::pin::Pin; + use std::sync::Arc; + /// Prevent the backend trait being implemented externally. + #[doc(hidden)] + pub(crate) mod sealed { + pub trait Sealed {} + } + /// This trait exposes the interface that Subxt will use to communicate with + /// a backend. Its goal is to be as minimal as possible. + pub trait Backend: sealed::Sealed + Send + Sync + 'static { + /// Fetch values from storage. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn storage_fetch_values<'life0, 'async_trait>( + &'life0 self, + keys: Vec>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Fetch keys underneath the given key from storage. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn storage_fetch_descendant_keys<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Fetch values underneath the given key from storage. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn storage_fetch_descendant_values<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Fetch the genesis hash + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn genesis_hash<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Get a block header + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn block_header<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Return the extrinsics found in the block. Each extrinsic is represented + /// by a vector of bytes which has _not_ been SCALE decoded (in other words, the + /// first bytes in the vector will decode to the compact encoded length of the extrinsic) + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn block_body<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Get the most recent finalized block hash. + /// Note: needed only in blocks client for finalized block stream; can prolly be removed. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn latest_finalized_block_ref<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Get information about the current runtime. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn current_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// A stream of all new runtime versions as they occur. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn stream_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// A stream of all new block headers as they arrive. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn stream_all_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// A stream of best block headers. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn stream_best_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// A stream of finalized block headers. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn stream_finalized_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Submit a transaction. This will return a stream of events about it. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn submit_transaction<'life0, 'life1, 'async_trait>( + &'life0 self, + bytes: &'life1 [u8], + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + Self: 'async_trait; + /// Make a call to some runtime API. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn call<'life0, 'life1, 'life2, 'async_trait>( + &'life0 self, + method: &'life1 str, + call_parameters: Option<&'life2 [u8]>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + 'life2: 'async_trait, + Self: 'async_trait; + } + /// helpeful utility methods derived from those provided on [`Backend`] + pub trait BackendExt: Backend { + /// Fetch a single value from storage. + #[must_use] + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_value<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: ::core::marker::Sync + 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::>, Error>> { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result>, Error> = { + __self + .storage_fetch_values( + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([key]), + ), + at, + ) + .await? + .next() + .await + .transpose() + .map(|o| o.map(|s| s.value)) + }; + #[allow(unreachable_code)] __ret + }) + } + /// The same as a [`Backend::call()`], but it will also attempt to decode the + /// result into the given type, which is a fairly common operation. + #[must_use] + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn call_decoding<'life0, 'life1, 'life2, 'async_trait, D>( + &'life0 self, + method: &'life1 str, + call_parameters: Option<&'life2 [u8]>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + D: 'async_trait + codec::Decode, + 'life0: 'async_trait, + 'life1: 'async_trait, + 'life2: 'async_trait, + Self: ::core::marker::Sync + 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let call_parameters = call_parameters; + let at = at; + let __ret: Result = { + let bytes = __self.call(method, call_parameters, at).await?; + let res = D::decode(&mut &*bytes)?; + Ok(res) + }; + #[allow(unreachable_code)] __ret + }) + } + /// Return the metadata at some version. + #[must_use] + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn metadata_at_version<'life0, 'async_trait>( + &'life0 self, + version: u32, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: ::core::marker::Sync + 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let version = version; + let at = at; + let __ret: Result = { + let param = version.encode(); + let opaque: Option = __self + .call_decoding("Metadata_metadata_at_version", Some(¶m), at) + .await?; + let Some(opaque) = opaque else { + return Err(Error::Other("Metadata version not found".into())); + }; + let metadata: Metadata = Decode::decode(&mut &opaque.0[..])?; + Ok(metadata) + }; + #[allow(unreachable_code)] __ret + }) + } + /// Return V14 metadata from the legacy `Metadata_metadata` call. + #[must_use] + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn legacy_metadata<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: ::core::marker::Sync + 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result = { + let opaque: frame_metadata::OpaqueMetadata = __self + .call_decoding("Metadata_metadata", None, at) + .await?; + let metadata: Metadata = Decode::decode(&mut &opaque.0[..])?; + Ok(metadata) + }; + #[allow(unreachable_code)] __ret + }) + } + } + impl + ?Sized, T: Config> BackendExt for B {} + /// An opaque struct which, while alive, indicates that some references to a block + /// still exist. This gives the backend the opportunity to keep the corresponding block + /// details around for a while if it likes and is able to. No guarantees can be made about + /// how long the corresponding details might be available for, but if no references to a block + /// exist, then the backend is free to discard any details for it. + pub struct BlockRef { + hash: H, + _pointer: Option>, + } + #[automatically_derived] + impl ::core::clone::Clone for BlockRef { + #[inline] + fn clone(&self) -> BlockRef { + BlockRef { + hash: ::core::clone::Clone::clone(&self.hash), + _pointer: ::core::clone::Clone::clone(&self._pointer), + } + } + } + impl From for BlockRef { + fn from(value: H) -> Self { + BlockRef::from_hash(value) + } + } + impl PartialEq for BlockRef { + fn eq(&self, other: &Self) -> bool { + self.hash == other.hash + } + } + impl Eq for BlockRef {} + impl PartialOrd for BlockRef { + fn partial_cmp(&self, other: &Self) -> Option { + self.hash.partial_cmp(&other.hash) + } + } + impl Ord for BlockRef { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.hash.cmp(&other.hash) + } + } + impl std::fmt::Debug for BlockRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("BlockRef").field(&self.hash).finish() + } + } + impl std::hash::Hash for BlockRef { + fn hash(&self, state: &mut Hasher) { + self.hash.hash(state); + } + } + impl BlockRef { + /// A [`BlockRef`] that doesn't reference a given block, but does have an associated hash. + /// This is used in the legacy backend, which has no notion of pinning blocks. + pub fn from_hash(hash: H) -> Self { + Self { hash, _pointer: None } + } + /// Construct a [`BlockRef`] from an instance of the underlying trait. It's expected + /// that the [`Backend`] implementation will call this if it wants to track which blocks + /// are potentially in use. + pub fn new(hash: H, inner: P) -> Self { + Self { + hash, + _pointer: Some(Arc::new(inner)), + } + } + /// Return the hash of the referenced block. + pub fn hash(&self) -> H + where + H: Copy, + { + self.hash + } + } + /// A trait that a [`Backend`] can implement to know when some block + /// can be unpinned: when this is dropped, there are no remaining references + /// to the block that it's associated with. + pub trait BlockRefT: Send + Sync + 'static {} + /// A stream of some item. + pub struct StreamOf(Pin + Send + 'static>>); + impl Stream for StreamOf { + type Item = T; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.0.poll_next_unpin(cx) + } + } + impl std::fmt::Debug for StreamOf { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("StreamOf").field(&"").finish() + } + } + impl StreamOf { + /// Construct a new stream. + pub fn new(inner: Pin + Send + 'static>>) -> Self { + StreamOf(inner) + } + /// Returns the next item in the stream. This is just a wrapper around + /// [`StreamExt::next()`] so that you can avoid the extra import. + pub async fn next(&mut self) -> Option { + StreamExt::next(self).await + } + } + /// A stream of [`Result`]. + pub type StreamOfResults = StreamOf>; + /// Runtime version information needed to submit transactions. + pub struct RuntimeVersion { + /// Version of the runtime specification. A full-node will not attempt to use its native + /// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, + /// `spec_version` and `authoring_version` are the same between Wasm and native. + pub spec_version: u32, + /// All existing dispatches are fully compatible when this number doesn't change. If this + /// number changes, then `spec_version` must change, also. + /// + /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, + /// either through an alteration in its user-level semantics, a parameter + /// added/removed/changed, a dispatchable being removed, a module being removed, or a + /// dispatchable/module changing its index. + /// + /// It need *not* change when a new module is added or when a dispatchable is added. + pub transaction_version: u32, + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeVersion { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "RuntimeVersion", + "spec_version", + &self.spec_version, + "transaction_version", + &&self.transaction_version, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeVersion { + #[inline] + fn clone(&self) -> RuntimeVersion { + RuntimeVersion { + spec_version: ::core::clone::Clone::clone(&self.spec_version), + transaction_version: ::core::clone::Clone::clone( + &self.transaction_version, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeVersion {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeVersion { + #[inline] + fn eq(&self, other: &RuntimeVersion) -> bool { + self.spec_version == other.spec_version + && self.transaction_version == other.transaction_version + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeVersion { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + /// The status of the transaction. + /// + /// If the status is [`TransactionStatus::InFinalizedBlock`], [`TransactionStatus::Error`], + /// [`TransactionStatus::Invalid`] or [`TransactionStatus::Dropped`], then no future + /// events will be emitted. + pub enum TransactionStatus { + /// Transaction is part of the future queue. + Validated, + /// The transaction has been broadcast to other nodes. + Broadcasted { + /// Number of peers it's been broadcast to. + num_peers: u32, + }, + /// Transaction is no longer in a best block. + NoLongerInBestBlock, + /// Transaction has been included in block with given hash. + InBestBlock { + /// Block hash the transaction is in. + hash: BlockRef, + }, + /// Transaction has been finalized by a finality-gadget, e.g GRANDPA + InFinalizedBlock { + /// Block hash the transaction is in. + hash: BlockRef, + }, + /// Something went wrong in the node. + Error { + /// Human readable message; what went wrong. + message: String, + }, + /// Transaction is invalid (bad nonce, signature etc). + Invalid { + /// Human readable message; why was it invalid. + message: String, + }, + /// The transaction was dropped. + Dropped { + /// Human readable message; why was it dropped. + message: String, + }, + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionStatus { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionStatus::Validated => { + ::core::fmt::Formatter::write_str(f, "Validated") + } + TransactionStatus::Broadcasted { num_peers: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Broadcasted", + "num_peers", + &__self_0, + ) + } + TransactionStatus::NoLongerInBestBlock => { + ::core::fmt::Formatter::write_str(f, "NoLongerInBestBlock") + } + TransactionStatus::InBestBlock { hash: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "InBestBlock", + "hash", + &__self_0, + ) + } + TransactionStatus::InFinalizedBlock { hash: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "InFinalizedBlock", + "hash", + &__self_0, + ) + } + TransactionStatus::Error { message: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Error", + "message", + &__self_0, + ) + } + TransactionStatus::Invalid { message: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Invalid", + "message", + &__self_0, + ) + } + TransactionStatus::Dropped { message: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Dropped", + "message", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for TransactionStatus { + #[inline] + fn clone(&self) -> TransactionStatus { + match self { + TransactionStatus::Validated => TransactionStatus::Validated, + TransactionStatus::Broadcasted { num_peers: __self_0 } => { + TransactionStatus::Broadcasted { + num_peers: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::NoLongerInBestBlock => { + TransactionStatus::NoLongerInBestBlock + } + TransactionStatus::InBestBlock { hash: __self_0 } => { + TransactionStatus::InBestBlock { + hash: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::InFinalizedBlock { hash: __self_0 } => { + TransactionStatus::InFinalizedBlock { + hash: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Error { message: __self_0 } => { + TransactionStatus::Error { + message: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Invalid { message: __self_0 } => { + TransactionStatus::Invalid { + message: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Dropped { message: __self_0 } => { + TransactionStatus::Dropped { + message: ::core::clone::Clone::clone(__self_0), + } + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionStatus {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for TransactionStatus { + #[inline] + fn eq(&self, other: &TransactionStatus) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionStatus::Broadcasted { num_peers: __self_0 }, + TransactionStatus::Broadcasted { num_peers: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::InBestBlock { hash: __self_0 }, + TransactionStatus::InBestBlock { hash: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::InFinalizedBlock { hash: __self_0 }, + TransactionStatus::InFinalizedBlock { hash: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Error { message: __self_0 }, + TransactionStatus::Error { message: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Invalid { message: __self_0 }, + TransactionStatus::Invalid { message: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Dropped { message: __self_0 }, + TransactionStatus::Dropped { message: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TransactionStatus { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + } + } + /// A response from calls like [`Backend::storage_fetch_values`] or + /// [`Backend::storage_fetch_descendant_values`]. + pub struct StorageResponse { + /// The key. + pub key: Vec, + /// The associated value. + pub value: Vec, + } +} +pub mod blocks { + //! This module exposes the necessary functionality for working with events. + mod block_types { + use crate::{ + backend::BlockRef, + blocks::{extrinsic_types::ExtrinsicPartTypeIds, Extrinsics}, + client::{OfflineClientT, OnlineClientT}, + config::{Config, Header}, + error::{BlockError, DecodeError, Error}, + events, runtime_api::RuntimeApi, storage::Storage, + }; + use codec::{Decode, Encode}; + use futures::lock::Mutex as AsyncMutex; + use std::sync::Arc; + /// A representation of a block. + pub struct Block { + header: T::Header, + block_ref: BlockRef, + client: C, + cached_events: CachedEvents, + } + pub(crate) type CachedEvents = Arc>>>; + impl Block + where + T: Config, + C: OfflineClientT, + { + pub(crate) fn new( + header: T::Header, + block_ref: BlockRef, + client: C, + ) -> Self { + Block { + header, + block_ref, + client, + cached_events: Default::default(), + } + } + /// Return a reference to the given block. While this reference is kept alive, + /// the backend will (if possible) endeavour to keep hold of the block. + pub fn reference(&self) -> BlockRef { + self.block_ref.clone() + } + /// Return the block hash. + pub fn hash(&self) -> T::Hash { + self.block_ref.hash() + } + /// Return the block number. + pub fn number(&self) -> ::Number { + self.header().number() + } + /// Return the entire block header. + pub fn header(&self) -> &T::Header { + &self.header + } + } + impl Block + where + T: Config, + C: OnlineClientT, + { + /// Return the events associated with the block, fetching them from the node if necessary. + pub async fn events(&self) -> Result, Error> { + get_events(&self.client, self.header.hash(), &self.cached_events).await + } + /// Fetch and return the extrinsics in the block body. + pub async fn extrinsics(&self) -> Result, Error> { + let ids = ExtrinsicPartTypeIds::new(&self.client.metadata())?; + let block_hash = self.header.hash(); + let Some(extrinsics) = self + .client + .backend() + .block_body(block_hash) + .await? else { return Err(BlockError::not_found(block_hash).into()); + }; + Ok( + Extrinsics::new( + self.client.clone(), + extrinsics, + self.cached_events.clone(), + ids, + block_hash, + ), + ) + } + /// Work with storage. + pub fn storage(&self) -> Storage { + Storage::new(self.client.clone(), self.block_ref.clone()) + } + /// Execute a runtime API call at this block. + pub async fn runtime_api(&self) -> Result, Error> { + Ok(RuntimeApi::new(self.client.clone(), self.block_ref.clone())) + } + /// Get the account nonce for a given account ID at this block. + pub async fn account_nonce( + &self, + account_id: &T::AccountId, + ) -> Result { + get_account_nonce(&self.client, account_id, self.hash()).await + } + } + pub(crate) async fn get_events( + client: &C, + block_hash: T::Hash, + cached_events: &AsyncMutex>>, + ) -> Result, Error> + where + T: Config, + C: OnlineClientT, + { + let mut lock = cached_events.lock().await; + let events = match &*lock { + Some(events) => events.clone(), + None => { + let events = events::EventsClient::new(client.clone()) + .at(block_hash) + .await?; + lock.replace(events.clone()); + events + } + }; + Ok(events) + } + pub(crate) async fn get_account_nonce( + client: &C, + account_id: &T::AccountId, + block_hash: T::Hash, + ) -> Result + where + C: OnlineClientT, + T: Config, + { + let account_nonce_bytes = client + .backend() + .call( + "AccountNonceApi_account_nonce", + Some(&account_id.encode()), + block_hash, + ) + .await?; + let cursor = &mut &account_nonce_bytes[..]; + let account_nonce: u64 = match account_nonce_bytes.len() { + 2 => u16::decode(cursor)?.into(), + 4 => u32::decode(cursor)?.into(), + 8 => u64::decode(cursor)?, + _ => { + return Err( + Error::Decode( + DecodeError::custom_string({ + let res = ::alloc::fmt::format( + format_args!( + "state call AccountNonceApi_account_nonce returned an unexpected number of bytes: {0} (expected 2, 4 or 8)", + account_nonce_bytes.len() + ), + ); + res + }), + ), + ); + } + }; + Ok(account_nonce) + } + } + mod blocks_client { + use super::Block; + use crate::{ + backend::{BlockRef, StreamOfResults}, + client::OnlineClientT, config::Config, error::{BlockError, Error}, + utils::PhantomDataSendSync, + }; + use derivative::Derivative; + use futures::StreamExt; + use std::future::Future; + type BlockStream = StreamOfResults; + type BlockStreamRes = Result, Error>; + /// A client for working with blocks. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct BlocksClient { + client: Client, + _marker: PhantomDataSendSync, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for BlocksClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + BlocksClient { client: ref __arg_0, _marker: ref __arg_1 } => { + BlocksClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl BlocksClient { + /// Create a new [`BlocksClient`]. + pub fn new(client: Client) -> Self { + Self { + client, + _marker: PhantomDataSendSync::new(), + } + } + } + impl BlocksClient + where + T: Config, + Client: OnlineClientT, + { + /// Obtain block details given the provided block hash. + /// + /// # Warning + /// + /// This call only supports blocks produced since the most recent + /// runtime upgrade. You can attempt to retrieve older blocks, + /// but may run into errors attempting to work with them. + pub fn at( + &self, + block_ref: impl Into>, + ) -> impl Future, Error>> + Send + 'static { + self.at_or_latest(Some(block_ref.into())) + } + /// Obtain block details of the latest block hash. + pub fn at_latest( + &self, + ) -> impl Future, Error>> + Send + 'static { + self.at_or_latest(None) + } + /// Obtain block details given the provided block hash, or the latest block if `None` is + /// provided. + fn at_or_latest( + &self, + block_ref: Option>, + ) -> impl Future, Error>> + Send + 'static { + let client = self.client.clone(); + async move { + let block_ref = match block_ref { + Some(r) => r, + None => client.backend().latest_finalized_block_ref().await?, + }; + let block_header = match client + .backend() + .block_header(block_ref.hash()) + .await? + { + Some(header) => header, + None => { + return Err(BlockError::not_found(block_ref.hash()).into()); + } + }; + Ok(Block::new(block_header, block_ref, client)) + } + } + /// Subscribe to all new blocks imported by the node. + /// + /// **Note:** You probably want to use [`Self::subscribe_finalized()`] most of + /// the time. + pub fn subscribe_all( + &self, + ) -> impl Future< + Output = Result>, Error>, + > + Send + 'static + where + Client: Send + Sync + 'static, + { + let client = self.client.clone(); + header_sub_fut_to_block_sub( + self.clone(), + async move { + let sub = client.backend().stream_all_block_headers().await?; + BlockStreamRes::Ok(sub) + }, + ) + } + /// Subscribe to all new blocks imported by the node onto the current best fork. + /// + /// **Note:** You probably want to use [`Self::subscribe_finalized()`] most of + /// the time. + pub fn subscribe_best( + &self, + ) -> impl Future< + Output = Result>, Error>, + > + Send + 'static + where + Client: Send + Sync + 'static, + { + let client = self.client.clone(); + header_sub_fut_to_block_sub( + self.clone(), + async move { + let sub = client.backend().stream_best_block_headers().await?; + BlockStreamRes::Ok(sub) + }, + ) + } + /// Subscribe to finalized blocks. + pub fn subscribe_finalized( + &self, + ) -> impl Future< + Output = Result>, Error>, + > + Send + 'static + where + Client: Send + Sync + 'static, + { + let client = self.client.clone(); + header_sub_fut_to_block_sub( + self.clone(), + async move { + let sub = client + .backend() + .stream_finalized_block_headers() + .await?; + BlockStreamRes::Ok(sub) + }, + ) + } + } + /// Take a promise that will return a subscription to some block headers, + /// and return a subscription to some blocks based on this. + async fn header_sub_fut_to_block_sub( + blocks_client: BlocksClient, + sub: S, + ) -> Result>, Error> + where + T: Config, + S: Future< + Output = Result)>, Error>, + > + Send + 'static, + Client: OnlineClientT + Send + Sync + 'static, + { + let sub = sub + .await? + .then(move |header_and_ref| { + let client = blocks_client.client.clone(); + async move { + let (header, block_ref) = match header_and_ref { + Ok(header_and_ref) => header_and_ref, + Err(e) => return Err(e), + }; + Ok(Block::new(header, block_ref, client)) + } + }); + BlockStreamRes::Ok(StreamOfResults::new(Box::pin(sub))) + } + } + mod extrinsic_types { + use crate::{ + blocks::block_types::{get_events, CachedEvents}, + client::{OfflineClientT, OnlineClientT}, + config::{Config, Hasher}, + error::{BlockError, Error, MetadataError}, + events, metadata::types::PalletMetadata, Metadata, + }; + use crate::config::signed_extensions::{ + ChargeAssetTxPayment, ChargeTransactionPayment, CheckNonce, + }; + use crate::config::SignedExtension; + use crate::dynamic::DecodedValue; + use crate::utils::strip_compact_prefix; + use codec::Decode; + use derivative::Derivative; + use scale_decode::{DecodeAsFields, DecodeAsType}; + use std::sync::Arc; + /// Trait to uniquely identify the extrinsic's identity from the runtime metadata. + /// + /// Generated API structures that represent an extrinsic implement this trait. + /// + /// The trait is utilized to decode emitted extrinsics from a block, via obtaining the + /// form of the `Extrinsic` from the metadata. + pub trait StaticExtrinsic: DecodeAsFields { + /// Pallet name. + const PALLET: &'static str; + /// Call name. + const CALL: &'static str; + /// Returns true if the given pallet and call names match this extrinsic. + fn is_extrinsic(pallet: &str, call: &str) -> bool { + Self::PALLET == pallet && Self::CALL == call + } + } + /// The body of a block. + pub struct Extrinsics { + client: C, + extrinsics: Vec>, + cached_events: CachedEvents, + ids: ExtrinsicPartTypeIds, + hash: T::Hash, + } + impl Extrinsics + where + T: Config, + C: OfflineClientT, + { + pub(crate) fn new( + client: C, + extrinsics: Vec>, + cached_events: CachedEvents, + ids: ExtrinsicPartTypeIds, + hash: T::Hash, + ) -> Self { + Self { + client, + extrinsics, + cached_events, + ids, + hash, + } + } + /// The number of extrinsics. + pub fn len(&self) -> usize { + self.extrinsics.len() + } + /// Are there no extrinsics in this block? + pub fn is_empty(&self) -> bool { + self.extrinsics.is_empty() + } + /// Return the block hash that these extrinsics are from. + pub fn block_hash(&self) -> T::Hash { + self.hash + } + /// Returns an iterator over the extrinsics in the block body. + pub fn iter( + &self, + ) -> impl Iterator< + Item = Result, Error>, + > + Send + Sync + 'static { + let extrinsics = self.extrinsics.clone(); + let num_extrinsics = self.extrinsics.len(); + let client = self.client.clone(); + let hash = self.hash; + let cached_events = self.cached_events.clone(); + let ids = self.ids; + let mut index = 0; + std::iter::from_fn(move || { + if index == num_extrinsics { + None + } else { + match ExtrinsicDetails::decode_from( + index as u32, + &extrinsics[index], + client.clone(), + hash, + cached_events.clone(), + ids, + ) { + Ok(extrinsic_details) => { + index += 1; + Some(Ok(extrinsic_details)) + } + Err(e) => { + index = num_extrinsics; + Some(Err(e)) + } + } + } + }) + } + /// Iterate through the extrinsics using metadata to dynamically decode and skip + /// them, and return only those which should decode to the provided `E` type. + /// If an error occurs, all subsequent iterations return `None`. + pub fn find( + &self, + ) -> impl Iterator, Error>> + '_ { + self.iter() + .filter_map(|res| match res { + Err(err) => Some(Err(err)), + Ok(details) => { + match details.as_extrinsic::() { + Err(err) => Some(Err(err)), + Ok(None) => None, + Ok(Some(value)) => { + Some(Ok(FoundExtrinsic { details, value })) + } + } + } + }) + } + /// Iterate through the extrinsics using metadata to dynamically decode and skip + /// them, and return the first extrinsic found which decodes to the provided `E` type. + pub fn find_first( + &self, + ) -> Result>, Error> { + self.find::().next().transpose() + } + /// Iterate through the extrinsics using metadata to dynamically decode and skip + /// them, and return the last extrinsic found which decodes to the provided `Ev` type. + pub fn find_last( + &self, + ) -> Result>, Error> { + self.find::().last().transpose() + } + /// Find an extrinsics that decodes to the type provided. Returns true if it was found. + pub fn has(&self) -> Result { + Ok(self.find::().next().transpose()?.is_some()) + } + } + /// A single extrinsic in a block. + pub struct ExtrinsicDetails { + /// The index of the extrinsic in the block. + index: u32, + /// Extrinsic bytes. + bytes: Arc<[u8]>, + /// Some if the extrinsic payload is signed. + signed_details: Option, + /// The start index in the `bytes` from which the call is encoded. + call_start_idx: usize, + /// The pallet index. + pallet_index: u8, + /// The variant index. + variant_index: u8, + /// The block hash of this extrinsic (needed to fetch events). + block_hash: T::Hash, + /// Subxt client. + client: C, + /// Cached events. + cached_events: CachedEvents, + /// Subxt metadata to fetch the extrinsic metadata. + metadata: Metadata, + _marker: std::marker::PhantomData, + } + /// Details only available in signed extrinsics. + pub struct SignedExtrinsicDetails { + /// start index of the range in `bytes` of `ExtrinsicDetails` that encodes the address. + address_start_idx: usize, + /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the address. Equivalent to signature_start_idx. + address_end_idx: usize, + /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the signature. Equivalent to extra_start_idx. + signature_end_idx: usize, + /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the signature. + extra_end_idx: usize, + } + impl ExtrinsicDetails + where + T: Config, + C: OfflineClientT, + { + pub(crate) fn decode_from( + index: u32, + extrinsic_bytes: &[u8], + client: C, + block_hash: T::Hash, + cached_events: CachedEvents, + ids: ExtrinsicPartTypeIds, + ) -> Result, Error> { + const SIGNATURE_MASK: u8 = 0b1000_0000; + const VERSION_MASK: u8 = 0b0111_1111; + const LATEST_EXTRINSIC_VERSION: u8 = 4; + let metadata = client.metadata(); + let bytes: Arc<[u8]> = strip_compact_prefix(extrinsic_bytes)?.1.into(); + let first_byte: u8 = Decode::decode(&mut &bytes[..])?; + let version = first_byte & VERSION_MASK; + if version != LATEST_EXTRINSIC_VERSION { + return Err(BlockError::UnsupportedVersion(version).into()); + } + let is_signed = first_byte & SIGNATURE_MASK != 0; + let cursor = &mut &bytes[1..]; + let signed_details = is_signed + .then(|| -> Result { + let address_start_idx = bytes.len() - cursor.len(); + scale_decode::visitor::decode_with_visitor( + cursor, + ids.address, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(scale_decode::Error::from)?; + let address_end_idx = bytes.len() - cursor.len(); + scale_decode::visitor::decode_with_visitor( + cursor, + ids.signature, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(scale_decode::Error::from)?; + let signature_end_idx = bytes.len() - cursor.len(); + scale_decode::visitor::decode_with_visitor( + cursor, + ids.extra, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(scale_decode::Error::from)?; + let extra_end_idx = bytes.len() - cursor.len(); + Ok(SignedExtrinsicDetails { + address_start_idx, + address_end_idx, + signature_end_idx, + extra_end_idx, + }) + }) + .transpose()?; + let call_start_idx = bytes.len() - cursor.len(); + let cursor = &mut &bytes[call_start_idx..]; + let pallet_index: u8 = Decode::decode(cursor)?; + let variant_index: u8 = Decode::decode(cursor)?; + Ok(ExtrinsicDetails { + index, + bytes, + signed_details, + call_start_idx, + pallet_index, + variant_index, + block_hash, + client, + cached_events, + metadata, + _marker: std::marker::PhantomData, + }) + } + /// Is the extrinsic signed? + pub fn is_signed(&self) -> bool { + self.signed_details.is_some() + } + /// The index of the extrinsic in the block. + pub fn index(&self) -> u32 { + self.index + } + /// Return _all_ of the bytes representing this extrinsic, which include, in order: + /// - First byte: abbbbbbb (a = 0 for unsigned, 1 for signed, b = version) + /// - SignatureType (if the payload is signed) + /// - Address + /// - Signature + /// - Extra fields + /// - Extrinsic call bytes + pub fn bytes(&self) -> &[u8] { + &self.bytes + } + /// Return only the bytes representing this extrinsic call: + /// - First byte is the pallet index + /// - Second byte is the variant (call) index + /// - Followed by field bytes. + /// + /// # Note + /// + /// Please use [`Self::bytes`] if you want to get all extrinsic bytes. + pub fn call_bytes(&self) -> &[u8] { + &self.bytes[self.call_start_idx..] + } + /// Return the bytes representing the fields stored in this extrinsic. + /// + /// # Note + /// + /// This is a subset of [`Self::call_bytes`] that does not include the + /// first two bytes that denote the pallet index and the variant index. + pub fn field_bytes(&self) -> &[u8] { + &self.call_bytes()[2..] + } + /// Return only the bytes of the address that signed this extrinsic. + /// + /// # Note + /// + /// Returns `None` if the extrinsic is not signed. + pub fn address_bytes(&self) -> Option<&[u8]> { + self.signed_details + .as_ref() + .map(|e| &self.bytes[e.address_start_idx..e.address_end_idx]) + } + /// Returns Some(signature_bytes) if the extrinsic was signed otherwise None is returned. + pub fn signature_bytes(&self) -> Option<&[u8]> { + self.signed_details + .as_ref() + .map(|e| &self.bytes[e.address_end_idx..e.signature_end_idx]) + } + /// Returns the signed extension `extra` bytes of the extrinsic. + /// Each signed extension has an `extra` type (May be zero-sized). + /// These bytes are the scale encoded `extra` fields of each signed extension in order of the signed extensions. + /// They do *not* include the `additional` signed bytes that are used as part of the payload that is signed. + /// + /// Note: Returns `None` if the extrinsic is not signed. + pub fn signed_extensions_bytes(&self) -> Option<&[u8]> { + self.signed_details + .as_ref() + .map(|e| &self.bytes[e.signature_end_idx..e.extra_end_idx]) + } + /// Returns `None` if the extrinsic is not signed. + pub fn signed_extensions(&self) -> Option> { + let signed = self.signed_details.as_ref()?; + let extra_bytes = &self + .bytes[signed.signature_end_idx..signed.extra_end_idx]; + Some(ExtrinsicSignedExtensions { + bytes: extra_bytes, + metadata: &self.metadata, + _marker: std::marker::PhantomData, + }) + } + /// The index of the pallet that the extrinsic originated from. + pub fn pallet_index(&self) -> u8 { + self.pallet_index + } + /// The index of the extrinsic variant that the extrinsic originated from. + pub fn variant_index(&self) -> u8 { + self.variant_index + } + /// The name of the pallet from whence the extrinsic originated. + pub fn pallet_name(&self) -> Result<&str, Error> { + Ok(self.extrinsic_metadata()?.pallet.name()) + } + /// The name of the call (ie the name of the variant that it corresponds to). + pub fn variant_name(&self) -> Result<&str, Error> { + Ok(&self.extrinsic_metadata()?.variant.name) + } + /// Fetch the metadata for this extrinsic. + pub fn extrinsic_metadata(&self) -> Result { + let pallet = self.metadata.pallet_by_index_err(self.pallet_index())?; + let variant = pallet + .call_variant_by_index(self.variant_index()) + .ok_or_else(|| MetadataError::VariantIndexNotFound( + self.variant_index(), + ))?; + Ok(ExtrinsicMetadataDetails { + pallet, + variant, + }) + } + /// Decode and provide the extrinsic fields back in the form of a [`scale_value::Composite`] + /// type which represents the named or unnamed fields that were present in the extrinsic. + pub fn field_values( + &self, + ) -> Result, Error> { + let bytes = &mut self.field_bytes(); + let extrinsic_metadata = self.extrinsic_metadata()?; + let mut fields = extrinsic_metadata + .variant + .fields + .iter() + .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); + let decoded = >::decode_as_fields(bytes, &mut fields, self.metadata.types())?; + Ok(decoded) + } + /// Attempt to decode these [`ExtrinsicDetails`] into a type representing the extrinsic fields. + /// Such types are exposed in the codegen as `pallet_name::calls::types::CallName` types. + pub fn as_extrinsic(&self) -> Result, Error> { + let extrinsic_metadata = self.extrinsic_metadata()?; + if extrinsic_metadata.pallet.name() == E::PALLET + && extrinsic_metadata.variant.name == E::CALL + { + let mut fields = extrinsic_metadata + .variant + .fields + .iter() + .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); + let decoded = E::decode_as_fields( + &mut self.field_bytes(), + &mut fields, + self.metadata.types(), + )?; + Ok(Some(decoded)) + } else { + Ok(None) + } + } + /// Attempt to decode these [`ExtrinsicDetails`] into an outer call enum type (which includes + /// the pallet and extrinsic enum variants as well as the extrinsic fields). A compatible + /// type for this is exposed via static codegen as a root level `Call` type. + pub fn as_root_extrinsic(&self) -> Result { + let decoded = E::decode_as_type( + &mut &self.call_bytes()[..], + self.metadata.outer_enums().call_enum_ty(), + self.metadata.types(), + )?; + Ok(decoded) + } + } + impl ExtrinsicDetails + where + T: Config, + C: OnlineClientT, + { + /// The events associated with the extrinsic. + pub async fn events(&self) -> Result, Error> { + let events = get_events( + &self.client, + self.block_hash, + &self.cached_events, + ) + .await?; + let ext_hash = T::Hasher::hash_of(&self.bytes); + Ok(ExtrinsicEvents::new(ext_hash, self.index, events)) + } + } + /// A Static Extrinsic found in a block coupled with it's details. + pub struct FoundExtrinsic { + pub details: ExtrinsicDetails, + pub value: E, + } + /// Details for the given extrinsic plucked from the metadata. + pub struct ExtrinsicMetadataDetails<'a> { + pub pallet: PalletMetadata<'a>, + pub variant: &'a scale_info::Variant, + } + /// The type IDs extracted from the metadata that represent the + /// generic type parameters passed to the `UncheckedExtrinsic` from + /// the substrate-based chain. + pub(crate) struct ExtrinsicPartTypeIds { + /// The address (source) of the extrinsic. + address: u32, + /// The extrinsic call type. + _call: u32, + /// The signature of the extrinsic. + signature: u32, + /// The extra parameters of the extrinsic. + extra: u32, + } + #[automatically_derived] + impl ::core::fmt::Debug for ExtrinsicPartTypeIds { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "ExtrinsicPartTypeIds", + "address", + &self.address, + "_call", + &self._call, + "signature", + &self.signature, + "extra", + &&self.extra, + ) + } + } + #[automatically_derived] + impl ::core::marker::Copy for ExtrinsicPartTypeIds {} + #[automatically_derived] + impl ::core::clone::Clone for ExtrinsicPartTypeIds { + #[inline] + fn clone(&self) -> ExtrinsicPartTypeIds { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + impl ExtrinsicPartTypeIds { + /// Extract the generic type parameters IDs from the extrinsic type. + pub(crate) fn new(metadata: &Metadata) -> Result { + Ok(ExtrinsicPartTypeIds { + address: metadata.extrinsic().address_ty(), + _call: metadata.extrinsic().call_ty(), + signature: metadata.extrinsic().signature_ty(), + extra: metadata.extrinsic().extra_ty(), + }) + } + } + /// The events associated with a given extrinsic. + #[derivative(Debug(bound = ""))] + pub struct ExtrinsicEvents { + ext_hash: T::Hash, + idx: u32, + events: events::Events, + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for ExtrinsicEvents { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + ExtrinsicEvents { + ext_hash: ref __arg_0, + idx: ref __arg_1, + events: ref __arg_2, + } => { + let mut __debug_trait_builder = __f + .debug_struct("ExtrinsicEvents"); + let _ = __debug_trait_builder.field("ext_hash", &&(*__arg_0)); + let _ = __debug_trait_builder.field("idx", &&(*__arg_1)); + let _ = __debug_trait_builder.field("events", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + impl ExtrinsicEvents { + pub(crate) fn new( + ext_hash: T::Hash, + idx: u32, + events: events::Events, + ) -> Self { + Self { ext_hash, idx, events } + } + /// Return the hash of the block that the extrinsic is in. + pub fn block_hash(&self) -> T::Hash { + self.events.block_hash() + } + /// The index of the extrinsic that these events are produced from. + pub fn extrinsic_index(&self) -> u32 { + self.idx + } + /// Return the hash of the extrinsic. + pub fn extrinsic_hash(&self) -> T::Hash { + self.ext_hash + } + /// Return all of the events in the block that the extrinsic is in. + pub fn all_events_in_block(&self) -> &events::Events { + &self.events + } + /// Iterate over all of the raw events associated with this transaction. + /// + /// This works in the same way that [`events::Events::iter()`] does, with the + /// exception that it filters out events not related to the submitted extrinsic. + pub fn iter( + &self, + ) -> impl Iterator, Error>> + '_ { + self.events + .iter() + .filter(|ev| { + ev.as_ref() + .map(|ev| { + ev.phase() == events::Phase::ApplyExtrinsic(self.idx) + }) + .unwrap_or(true) + }) + } + /// Find all of the transaction events matching the event type provided as a generic parameter. + /// + /// This works in the same way that [`events::Events::find()`] does, with the + /// exception that it filters out events not related to the submitted extrinsic. + pub fn find( + &self, + ) -> impl Iterator> + '_ { + self.iter() + .filter_map(|ev| { + ev.and_then(|ev| ev.as_event::().map_err(Into::into)) + .transpose() + }) + } + /// Iterate through the transaction events using metadata to dynamically decode and skip + /// them, and return the first event found which decodes to the provided `Ev` type. + /// + /// This works in the same way that [`events::Events::find_first()`] does, with the + /// exception that it ignores events not related to the submitted extrinsic. + pub fn find_first( + &self, + ) -> Result, Error> { + self.find::().next().transpose() + } + /// Iterate through the transaction events using metadata to dynamically decode and skip + /// them, and return the last event found which decodes to the provided `Ev` type. + /// + /// This works in the same way that [`events::Events::find_last()`] does, with the + /// exception that it ignores events not related to the submitted extrinsic. + pub fn find_last( + &self, + ) -> Result, Error> { + self.find::().last().transpose() + } + /// Find an event in those associated with this transaction. Returns true if it was found. + /// + /// This works in the same way that [`events::Events::has()`] does, with the + /// exception that it ignores events not related to the submitted extrinsic. + pub fn has(&self) -> Result { + Ok(self.find::().next().transpose()?.is_some()) + } + } + /// The signed extensions of an extrinsic. + pub struct ExtrinsicSignedExtensions<'a, T: Config> { + bytes: &'a [u8], + metadata: &'a Metadata, + _marker: std::marker::PhantomData, + } + #[automatically_derived] + impl<'a, T: ::core::fmt::Debug + Config> ::core::fmt::Debug + for ExtrinsicSignedExtensions<'a, T> { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "ExtrinsicSignedExtensions", + "bytes", + &self.bytes, + "metadata", + &self.metadata, + "_marker", + &&self._marker, + ) + } + } + #[automatically_derived] + impl<'a, T: ::core::clone::Clone + Config> ::core::clone::Clone + for ExtrinsicSignedExtensions<'a, T> { + #[inline] + fn clone(&self) -> ExtrinsicSignedExtensions<'a, T> { + ExtrinsicSignedExtensions { + bytes: ::core::clone::Clone::clone(&self.bytes), + metadata: ::core::clone::Clone::clone(&self.metadata), + _marker: ::core::clone::Clone::clone(&self._marker), + } + } + } + impl<'a, T: Config> ExtrinsicSignedExtensions<'a, T> { + /// Returns an iterator over each of the signed extension details of the extrinsic. + /// If the decoding of any signed extension fails, an error item is yielded and the iterator stops. + pub fn iter( + &self, + ) -> impl Iterator, Error>> { + let signed_extension_types = self + .metadata + .extrinsic() + .signed_extensions(); + let num_signed_extensions = signed_extension_types.len(); + let bytes = self.bytes; + let mut index = 0; + let mut byte_start_idx = 0; + let metadata = &self.metadata; + std::iter::from_fn(move || { + if index == num_signed_extensions { + return None; + } + let extension = &signed_extension_types[index]; + let ty_id = extension.extra_ty(); + let cursor = &mut &bytes[byte_start_idx..]; + if let Err(err) + = scale_decode::visitor::decode_with_visitor( + cursor, + ty_id, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(|e| Error::Decode(e.into())) + { + index = num_signed_extensions; + return Some(Err(err)); + } + let byte_end_idx = bytes.len() - cursor.len(); + let bytes = &bytes[byte_start_idx..byte_end_idx]; + byte_start_idx = byte_end_idx; + index += 1; + Some( + Ok(ExtrinsicSignedExtension { + bytes, + ty_id, + identifier: extension.identifier(), + metadata, + _marker: std::marker::PhantomData, + }), + ) + }) + } + /// Searches through all signed extensions to find a specific one. + /// If the Signed Extension is not found `Ok(None)` is returned. + /// If the Signed Extension is found but decoding failed `Err(_)` is returned. + pub fn find>( + &self, + ) -> Result, Error> { + for ext in self.iter() { + let ext = ext?; + match ext.as_signed_extension::() { + Ok(Some(e)) => return Ok(Some(e)), + Ok(None) => continue, + Err(e) => return Err(e), + } + } + Ok(None) + } + /// The tip of an extrinsic, extracted from the ChargeTransactionPayment or ChargeAssetTxPayment + /// signed extension, depending on which is present. + /// + /// Returns `None` if `tip` was not found or decoding failed. + pub fn tip(&self) -> Option { + self.find::() + .ok() + .flatten() + .map(|e| e.tip()) + .or_else(|| { + self.find::>() + .ok() + .flatten() + .map(|e| e.tip()) + }) + } + /// The nonce of the account that submitted the extrinsic, extracted from the CheckNonce signed extension. + /// + /// Returns `None` if `nonce` was not found or decoding failed. + pub fn nonce(&self) -> Option { + self.find::().ok()? + } + } + /// A single signed extension + pub struct ExtrinsicSignedExtension<'a, T: Config> { + bytes: &'a [u8], + ty_id: u32, + identifier: &'a str, + metadata: &'a Metadata, + _marker: std::marker::PhantomData, + } + #[automatically_derived] + impl<'a, T: ::core::fmt::Debug + Config> ::core::fmt::Debug + for ExtrinsicSignedExtension<'a, T> { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "ExtrinsicSignedExtension", + "bytes", + &self.bytes, + "ty_id", + &self.ty_id, + "identifier", + &self.identifier, + "metadata", + &self.metadata, + "_marker", + &&self._marker, + ) + } + } + #[automatically_derived] + impl<'a, T: ::core::clone::Clone + Config> ::core::clone::Clone + for ExtrinsicSignedExtension<'a, T> { + #[inline] + fn clone(&self) -> ExtrinsicSignedExtension<'a, T> { + ExtrinsicSignedExtension { + bytes: ::core::clone::Clone::clone(&self.bytes), + ty_id: ::core::clone::Clone::clone(&self.ty_id), + identifier: ::core::clone::Clone::clone(&self.identifier), + metadata: ::core::clone::Clone::clone(&self.metadata), + _marker: ::core::clone::Clone::clone(&self._marker), + } + } + } + impl<'a, T: Config> ExtrinsicSignedExtension<'a, T> { + /// The bytes representing this signed extension. + pub fn bytes(&self) -> &'a [u8] { + self.bytes + } + /// The name of the signed extension. + pub fn name(&self) -> &'a str { + self.identifier + } + /// The type id of the signed extension. + pub fn type_id(&self) -> u32 { + self.ty_id + } + /// Signed Extension as a [`scale_value::Value`] + pub fn value(&self) -> Result { + self.as_type() + } + /// Decodes the bytes of this Signed Extension into its associated `Decoded` type. + /// Returns `Ok(None)` if the data we have doesn't match the Signed Extension we're asking to + /// decode with. + pub fn as_signed_extension>( + &self, + ) -> Result, Error> { + if !S::matches(self.identifier, self.ty_id, self.metadata.types()) { + return Ok(None); + } + self.as_type::().map(Some) + } + fn as_type(&self) -> Result { + let value = E::decode_as_type( + &mut &self.bytes[..], + self.ty_id, + self.metadata.types(), + )?; + Ok(value) + } + } + } + /// A reference to a block. + pub use crate::backend::BlockRef; + pub use block_types::Block; + pub use blocks_client::BlocksClient; + pub use extrinsic_types::{ + ExtrinsicDetails, ExtrinsicEvents, ExtrinsicSignedExtension, + ExtrinsicSignedExtensions, Extrinsics, StaticExtrinsic, + }; + pub(crate) use block_types::get_account_nonce; +} +pub mod client { + //! This module provides two clients that can be used to work with + //! transactions, storage and events. The [`OfflineClient`] works + //! entirely offline and can be passed to any function that doesn't + //! require network access. The [`OnlineClient`] requires network + //! access. + mod offline_client { + use crate::custom_values::CustomValuesClient; + use crate::{ + backend::RuntimeVersion, blocks::BlocksClient, constants::ConstantsClient, + events::EventsClient, runtime_api::RuntimeApiClient, storage::StorageClient, + tx::TxClient, Config, Metadata, + }; + use derivative::Derivative; + use std::sync::Arc; + /// A trait representing a client that can perform + /// offline-only actions. + pub trait OfflineClientT: Clone + Send + Sync + 'static { + /// Return the provided [`Metadata`]. + fn metadata(&self) -> Metadata; + /// Return the provided genesis hash. + fn genesis_hash(&self) -> T::Hash; + /// Return the provided [`RuntimeVersion`]. + fn runtime_version(&self) -> RuntimeVersion; + /// Work with transactions. + fn tx(&self) -> TxClient { + TxClient::new(self.clone()) + } + /// Work with events. + fn events(&self) -> EventsClient { + EventsClient::new(self.clone()) + } + /// Work with storage. + fn storage(&self) -> StorageClient { + StorageClient::new(self.clone()) + } + /// Access constants. + fn constants(&self) -> ConstantsClient { + ConstantsClient::new(self.clone()) + } + /// Work with blocks. + fn blocks(&self) -> BlocksClient { + BlocksClient::new(self.clone()) + } + /// Work with runtime API. + fn runtime_api(&self) -> RuntimeApiClient { + RuntimeApiClient::new(self.clone()) + } + /// Work this custom types. + fn custom_values(&self) -> CustomValuesClient { + CustomValuesClient::new(self.clone()) + } + } + /// A client that is capable of performing offline-only operations. + /// Can be constructed as long as you can populate the required fields. + #[derivative(Debug(bound = ""), Clone(bound = ""))] + pub struct OfflineClient { + inner: Arc>, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for OfflineClient { + fn clone(&self) -> Self { + match *self { + OfflineClient { inner: ref __arg_0 } => { + OfflineClient { + inner: (*__arg_0).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for OfflineClient { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + OfflineClient { inner: ref __arg_0 } => { + let mut __debug_trait_builder = __f + .debug_struct("OfflineClient"); + let _ = __debug_trait_builder.field("inner", &&(*__arg_0)); + __debug_trait_builder.finish() + } + } + } + } + #[derivative(Debug(bound = ""), Clone(bound = ""))] + struct Inner { + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: Metadata, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Inner { + fn clone(&self) -> Self { + match *self { + Inner { + genesis_hash: ref __arg_0, + runtime_version: ref __arg_1, + metadata: ref __arg_2, + } => { + Inner { + genesis_hash: (*__arg_0).clone(), + runtime_version: (*__arg_1).clone(), + metadata: (*__arg_2).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Inner { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Inner { + genesis_hash: ref __arg_0, + runtime_version: ref __arg_1, + metadata: ref __arg_2, + } => { + let mut __debug_trait_builder = __f.debug_struct("Inner"); + let _ = __debug_trait_builder + .field("genesis_hash", &&(*__arg_0)); + let _ = __debug_trait_builder + .field("runtime_version", &&(*__arg_1)); + let _ = __debug_trait_builder.field("metadata", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + impl OfflineClient { + /// Construct a new [`OfflineClient`], providing + /// the necessary runtime and compile-time arguments. + pub fn new( + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: impl Into, + ) -> OfflineClient { + OfflineClient { + inner: Arc::new(Inner { + genesis_hash, + runtime_version, + metadata: metadata.into(), + }), + } + } + /// Return the genesis hash. + pub fn genesis_hash(&self) -> T::Hash { + self.inner.genesis_hash + } + /// Return the runtime version. + pub fn runtime_version(&self) -> RuntimeVersion { + self.inner.runtime_version.clone() + } + /// Return the [`Metadata`] used in this client. + pub fn metadata(&self) -> Metadata { + self.inner.metadata.clone() + } + /// Work with transactions. + pub fn tx(&self) -> TxClient { + >::tx(self) + } + /// Work with events. + pub fn events(&self) -> EventsClient { + >::events(self) + } + /// Work with storage. + pub fn storage(&self) -> StorageClient { + >::storage(self) + } + /// Access constants. + pub fn constants(&self) -> ConstantsClient { + >::constants(self) + } + /// Access custom types + pub fn custom_values(&self) -> CustomValuesClient { + >::custom_values(self) + } + } + impl OfflineClientT for OfflineClient { + fn genesis_hash(&self) -> T::Hash { + self.genesis_hash() + } + fn runtime_version(&self) -> RuntimeVersion { + self.runtime_version() + } + fn metadata(&self) -> Metadata { + self.metadata() + } + } + impl<'a, T: Config> From<&'a OfflineClient> for OfflineClient { + fn from(c: &'a OfflineClient) -> Self { + c.clone() + } + } + } + mod online_client { + use super::{OfflineClient, OfflineClientT}; + use crate::custom_values::CustomValuesClient; + use crate::{ + backend::{ + legacy::LegacyBackend, rpc::RpcClient, Backend, BackendExt, + RuntimeVersion, StreamOfResults, + }, + blocks::{BlockRef, BlocksClient}, + constants::ConstantsClient, error::Error, events::EventsClient, + runtime_api::RuntimeApiClient, storage::StorageClient, tx::TxClient, Config, + Metadata, + }; + use derivative::Derivative; + use futures::future; + use std::sync::{Arc, RwLock}; + /// A trait representing a client that can perform + /// online actions. + pub trait OnlineClientT: OfflineClientT { + /// Return a backend that can be used to communicate with a node. + fn backend(&self) -> &dyn Backend; + } + /// A client that can be used to perform API calls (that is, either those + /// requiring an [`OfflineClientT`] or those requiring an [`OnlineClientT`]). + #[derivative(Clone(bound = ""))] + pub struct OnlineClient { + inner: Arc>>, + backend: Arc>, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for OnlineClient { + fn clone(&self) -> Self { + match *self { + OnlineClient { inner: ref __arg_0, backend: ref __arg_1 } => { + OnlineClient { + inner: (*__arg_0).clone(), + backend: (*__arg_1).clone(), + } + } + } + } + } + #[derivative(Debug(bound = ""))] + struct Inner { + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: Metadata, + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Inner { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Inner { + genesis_hash: ref __arg_0, + runtime_version: ref __arg_1, + metadata: ref __arg_2, + } => { + let mut __debug_trait_builder = __f.debug_struct("Inner"); + let _ = __debug_trait_builder + .field("genesis_hash", &&(*__arg_0)); + let _ = __debug_trait_builder + .field("runtime_version", &&(*__arg_1)); + let _ = __debug_trait_builder.field("metadata", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + impl std::fmt::Debug for OnlineClient { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Client") + .field("rpc", &"RpcClient") + .field("inner", &self.inner) + .finish() + } + } + #[cfg(feature = "jsonrpsee")] + impl OnlineClient { + /// Construct a new [`OnlineClient`] using default settings which + /// point to a locally running node on `ws://127.0.0.1:9944`. + pub async fn new() -> Result, Error> { + let url = "ws://127.0.0.1:9944"; + OnlineClient::from_url(url).await + } + /// Construct a new [`OnlineClient`], providing a URL to connect to. + pub async fn from_url( + url: impl AsRef, + ) -> Result, Error> { + crate::utils::validate_url_is_secure(url.as_ref())?; + OnlineClient::from_insecure_url(url).await + } + /// Construct a new [`OnlineClient`], providing a URL to connect to. + /// + /// Allows insecure URLs without SSL encryption, e.g. (http:// and ws:// URLs). + pub async fn from_insecure_url( + url: impl AsRef, + ) -> Result, Error> { + let client = RpcClient::from_insecure_url(url).await?; + let backend = LegacyBackend::new(client); + OnlineClient::from_backend(Arc::new(backend)).await + } + } + impl OnlineClient { + /// Construct a new [`OnlineClient`] by providing an [`RpcClient`] to drive the connection. + /// This will use the current default [`Backend`], which may change in future releases. + pub async fn from_rpc_client( + rpc_client: RpcClient, + ) -> Result, Error> { + let backend = Arc::new(LegacyBackend::new(rpc_client)); + OnlineClient::from_backend(backend).await + } + /// Construct a new [`OnlineClient`] by providing an RPC client along with the other + /// necessary details. This will use the current default [`Backend`], which may change + /// in future releases. + /// + /// # Warning + /// + /// This is considered the most primitive and also error prone way to + /// instantiate a client; the genesis hash, metadata and runtime version provided will + /// entirely determine which node and blocks this client will be able to interact with, + /// and whether it will be able to successfully do things like submit transactions. + /// + /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate + /// a client. + pub fn from_rpc_client_with( + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: impl Into, + rpc_client: RpcClient, + ) -> Result, Error> { + let backend = Arc::new(LegacyBackend::new(rpc_client)); + OnlineClient::from_backend_with( + genesis_hash, + runtime_version, + metadata, + backend, + ) + } + /// Construct a new [`OnlineClient`] by providing an underlying [`Backend`] + /// implementation to power it. Other details will be obtained from the chain. + pub async fn from_backend>( + backend: Arc, + ) -> Result, Error> { + let latest_block = backend.latest_finalized_block_ref().await?; + let (genesis_hash, runtime_version, metadata) = future::join3( + backend.genesis_hash(), + backend.current_runtime_version(), + OnlineClient::fetch_metadata(&*backend, latest_block.hash()), + ) + .await; + OnlineClient::from_backend_with( + genesis_hash?, + runtime_version?, + metadata?, + backend, + ) + } + /// Construct a new [`OnlineClient`] by providing all of the underlying details needed + /// to make it work. + /// + /// # Warning + /// + /// This is considered the most primitive and also error prone way to + /// instantiate a client; the genesis hash, metadata and runtime version provided will + /// entirely determine which node and blocks this client will be able to interact with, + /// and whether it will be able to successfully do things like submit transactions. + /// + /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate + /// a client. + pub fn from_backend_with>( + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: impl Into, + backend: Arc, + ) -> Result, Error> { + Ok(OnlineClient { + inner: Arc::new( + RwLock::new(Inner { + genesis_hash, + runtime_version, + metadata: metadata.into(), + }), + ), + backend, + }) + } + /// Fetch the metadata from substrate using the runtime API. + async fn fetch_metadata( + backend: &dyn Backend, + block_hash: T::Hash, + ) -> Result { + #[cfg(not(feature = "unstable-metadata"))] + OnlineClient::fetch_latest_stable_metadata(backend, block_hash).await + } + /// Fetch the latest stable metadata from the node. + async fn fetch_latest_stable_metadata( + backend: &dyn Backend, + block_hash: T::Hash, + ) -> Result { + const V15_METADATA_VERSION: u32 = 15; + if let Ok(bytes) + = backend.metadata_at_version(V15_METADATA_VERSION, block_hash).await + { + return Ok(bytes); + } + backend.legacy_metadata(block_hash).await + } + /// Create an object which can be used to keep the runtime up to date + /// in a separate thread. + /// + /// # Example + /// + /// ```no_run + /// # #[tokio::main] + /// # async fn main() { + /// use subxt::{ OnlineClient, PolkadotConfig }; + /// + /// let client = OnlineClient::::new().await.unwrap(); + /// + /// // high level API. + /// + /// let update_task = client.updater(); + /// tokio::spawn(async move { + /// update_task.perform_runtime_updates().await; + /// }); + /// + /// + /// // low level API. + /// + /// let updater = client.updater(); + /// tokio::spawn(async move { + /// let mut update_stream = updater.runtime_updates().await.unwrap(); + /// + /// while let Some(Ok(update)) = update_stream.next().await { + /// let version = update.runtime_version().spec_version; + /// + /// match updater.apply_update(update) { + /// Ok(()) => { + /// println!("Upgrade to version: {} successful", version) + /// } + /// Err(e) => { + /// println!("Upgrade to version {} failed {:?}", version, e); + /// } + /// }; + /// } + /// }); + /// # } + /// ``` + pub fn updater(&self) -> ClientRuntimeUpdater { + ClientRuntimeUpdater(self.clone()) + } + /// Return the [`Metadata`] used in this client. + pub fn metadata(&self) -> Metadata { + let inner = self.inner.read().expect("shouldn't be poisoned"); + inner.metadata.clone() + } + /// Change the [`Metadata`] used in this client. + /// + /// # Warning + /// + /// Setting custom metadata may leave Subxt unable to work with certain blocks, + /// subscribe to latest blocks or submit valid transactions. + pub fn set_metadata(&self, metadata: impl Into) { + let mut inner = self.inner.write().expect("shouldn't be poisoned"); + inner.metadata = metadata.into(); + } + /// Return the genesis hash. + pub fn genesis_hash(&self) -> T::Hash { + let inner = self.inner.read().expect("shouldn't be poisoned"); + inner.genesis_hash + } + /// Change the genesis hash used in this client. + /// + /// # Warning + /// + /// Setting a custom genesis hash may leave Subxt unable to + /// submit valid transactions. + pub fn set_genesis_hash(&self, genesis_hash: T::Hash) { + let mut inner = self.inner.write().expect("shouldn't be poisoned"); + inner.genesis_hash = genesis_hash; + } + /// Return the runtime version. + pub fn runtime_version(&self) -> RuntimeVersion { + let inner = self.inner.read().expect("shouldn't be poisoned"); + inner.runtime_version.clone() + } + /// Change the [`RuntimeVersion`] used in this client. + /// + /// # Warning + /// + /// Setting a custom runtime version may leave Subxt unable to + /// submit valid transactions. + pub fn set_runtime_version(&self, runtime_version: RuntimeVersion) { + let mut inner = self.inner.write().expect("shouldn't be poisoned"); + inner.runtime_version = runtime_version; + } + /// Return an RPC client to make raw requests with. + pub fn backend(&self) -> &dyn Backend { + &*self.backend + } + /// Return an offline client with the same configuration as this. + pub fn offline(&self) -> OfflineClient { + let inner = self.inner.read().expect("shouldn't be poisoned"); + OfflineClient::new( + inner.genesis_hash, + inner.runtime_version.clone(), + inner.metadata.clone(), + ) + } + /// Work with transactions. + pub fn tx(&self) -> TxClient { + >::tx(self) + } + /// Work with events. + pub fn events(&self) -> EventsClient { + >::events(self) + } + /// Work with storage. + pub fn storage(&self) -> StorageClient { + >::storage(self) + } + /// Access constants. + pub fn constants(&self) -> ConstantsClient { + >::constants(self) + } + /// Access custom types. + pub fn custom_values(&self) -> CustomValuesClient { + >::custom_values(self) + } + /// Work with blocks. + pub fn blocks(&self) -> BlocksClient { + >::blocks(self) + } + /// Work with runtime API. + pub fn runtime_api(&self) -> RuntimeApiClient { + >::runtime_api(self) + } + } + impl OfflineClientT for OnlineClient { + fn metadata(&self) -> Metadata { + self.metadata() + } + fn genesis_hash(&self) -> T::Hash { + self.genesis_hash() + } + fn runtime_version(&self) -> RuntimeVersion { + self.runtime_version() + } + } + impl OnlineClientT for OnlineClient { + fn backend(&self) -> &dyn Backend { + &*self.backend + } + } + /// Client wrapper for performing runtime updates. See [`OnlineClient::updater()`] + /// for example usage. + pub struct ClientRuntimeUpdater(OnlineClient); + impl ClientRuntimeUpdater { + fn is_runtime_version_different(&self, new: &RuntimeVersion) -> bool { + let curr = self.0.inner.read().expect("shouldn't be poisoned"); + &curr.runtime_version != new + } + fn do_update(&self, update: Update) { + let mut writable = self.0.inner.write().expect("shouldn't be poisoned"); + writable.metadata = update.metadata; + writable.runtime_version = update.runtime_version; + } + /// Tries to apply a new update. + pub fn apply_update(&self, update: Update) -> Result<(), UpgradeError> { + if !self.is_runtime_version_different(&update.runtime_version) { + return Err(UpgradeError::SameVersion); + } + self.do_update(update); + Ok(()) + } + /// Performs runtime updates indefinitely unless encountering an error. + /// + /// *Note:* This will run indefinitely until it errors, so the typical usage + /// would be to run it in a separate background task. + pub async fn perform_runtime_updates(&self) -> Result<(), Error> { + let mut runtime_version_stream = self.runtime_updates().await?; + while let Some(update) = runtime_version_stream.next().await { + let update = update?; + let _ = self.apply_update(update); + } + Ok(()) + } + /// Low-level API to get runtime updates as a stream but it's doesn't check if the + /// runtime version is newer or updates the runtime. + /// + /// Instead that's up to the user of this API to decide when to update and + /// to perform the actual updating. + pub async fn runtime_updates( + &self, + ) -> Result, Error> { + let stream = self.0.backend().stream_runtime_version().await?; + Ok(RuntimeUpdaterStream { + stream, + client: self.0.clone(), + }) + } + } + /// Stream to perform runtime upgrades. + pub struct RuntimeUpdaterStream { + stream: StreamOfResults, + client: OnlineClient, + } + impl RuntimeUpdaterStream { + /// Wait for the next runtime update. + pub async fn next(&mut self) -> Option> { + let runtime_version = match self.stream.next().await? { + Ok(runtime_version) => runtime_version, + Err(err) => return Some(Err(err)), + }; + let at = match wait_runtime_upgrade_in_finalized_block( + &self.client, + &runtime_version, + ) + .await? + { + Ok(at) => at, + Err(err) => return Some(Err(err)), + }; + let metadata = match OnlineClient::fetch_metadata( + self.client.backend(), + at.hash(), + ) + .await + { + Ok(metadata) => metadata, + Err(err) => return Some(Err(err)), + }; + Some( + Ok(Update { + metadata, + runtime_version, + }), + ) + } + } + /// Error that can occur during upgrade. + #[non_exhaustive] + pub enum UpgradeError { + /// The version is the same as the current version. + SameVersion, + } + #[automatically_derived] + impl ::core::fmt::Debug for UpgradeError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "SameVersion") + } + } + #[automatically_derived] + impl ::core::clone::Clone for UpgradeError { + #[inline] + fn clone(&self) -> UpgradeError { + UpgradeError::SameVersion + } + } + /// Represents the state when a runtime upgrade occurred. + pub struct Update { + runtime_version: RuntimeVersion, + metadata: Metadata, + } + impl Update { + /// Get the runtime version. + pub fn runtime_version(&self) -> &RuntimeVersion { + &self.runtime_version + } + /// Get the metadata. + pub fn metadata(&self) -> &Metadata { + &self.metadata + } + } + /// Helper to wait until the runtime upgrade is applied on at finalized block. + async fn wait_runtime_upgrade_in_finalized_block( + client: &OnlineClient, + runtime_version: &RuntimeVersion, + ) -> Option, Error>> { + use scale_value::At; + let mut block_sub = match client + .backend() + .stream_finalized_block_headers() + .await + { + Ok(s) => s, + Err(err) => return Some(Err(err)), + }; + let block_ref = loop { + let (_, block_ref) = match block_sub.next().await? { + Ok(n) => n, + Err(err) => return Some(Err(err)), + }; + let key: Vec = ::alloc::vec::Vec::new(); + let addr = crate::dynamic::storage("System", "LastRuntimeUpgrade", key); + let chunk = match client + .storage() + .at(block_ref.hash()) + .fetch(&addr) + .await + { + Ok(Some(v)) => v, + Ok(None) => { + ::core::panicking::panic_fmt( + format_args!( + "internal error: entered unreachable code: {0}", + format_args!("The storage item `system::lastRuntimeUpgrade` should always exist") + ), + ); + } + Err(e) => return Some(Err(e)), + }; + let scale_val = match chunk.to_value() { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + let Some(Ok(spec_version)) = scale_val + .at("spec_version") + .and_then(|v| v.as_u128()) + .map(u32::try_from) else { + return Some( + Err( + Error::Other( + "Decoding `RuntimeVersion::spec_version` as u32 failed" + .to_string(), + ), + ), + ); + }; + if spec_version == runtime_version.spec_version { + break block_ref; + } + }; + Some(Ok(block_ref)) + } + } + pub use offline_client::{OfflineClient, OfflineClientT}; + pub use online_client::{ + ClientRuntimeUpdater, OnlineClient, OnlineClientT, RuntimeUpdaterStream, Update, + UpgradeError, + }; +} +pub mod config { + //! This module provides a [`Config`] type, which is used to define various + //! types that are important in order to speak to a particular chain. + //! [`SubstrateConfig`] provides a default set of these types suitable for the + //! default Substrate node implementation, and [`PolkadotConfig`] for a + //! Polkadot node. + mod default_extrinsic_params { + use super::{signed_extensions, ExtrinsicParams}; + use super::{Config, Header}; + /// The default [`super::ExtrinsicParams`] implementation understands common signed extensions + /// and how to apply them to a given chain. + pub type DefaultExtrinsicParams = signed_extensions::AnyOf< + T, + ( + signed_extensions::CheckSpecVersion, + signed_extensions::CheckTxVersion, + signed_extensions::CheckNonce, + signed_extensions::CheckGenesis, + signed_extensions::CheckMortality, + signed_extensions::ChargeAssetTxPayment, + signed_extensions::ChargeTransactionPayment, + ), + >; + /// A builder that outputs the set of [`super::ExtrinsicParams::OtherParams`] required for + /// [`DefaultExtrinsicParams`]. This may expose methods that aren't applicable to the current + /// chain; such values will simply be ignored if so. + pub struct DefaultExtrinsicParamsBuilder { + /// `None` means the tx will be immortal. + mortality: Option>, + /// `None` means we'll use the native token. + tip_of_asset_id: Option, + tip: u128, + tip_of: u128, + } + struct Mortality { + /// Block hash that mortality starts from + checkpoint_hash: Hash, + /// Block number that mortality starts from (must + checkpoint_number: u64, + /// How many blocks the tx is mortal for + period: u64, + } + impl Default for DefaultExtrinsicParamsBuilder { + fn default() -> Self { + Self { + mortality: None, + tip: 0, + tip_of: 0, + tip_of_asset_id: None, + } + } + } + impl DefaultExtrinsicParamsBuilder { + /// Configure new extrinsic params. We default to providing no tip + /// and using an immortal transaction unless otherwise configured + pub fn new() -> Self { + Default::default() + } + /// Make the transaction mortal, given a block header that it should be mortal from, + /// and the number of blocks (roughly; it'll be rounded to a power of two) that it will + /// be mortal for. + pub fn mortal(mut self, from_block: &T::Header, for_n_blocks: u64) -> Self { + self + .mortality = Some(Mortality { + checkpoint_hash: from_block.hash(), + checkpoint_number: from_block.number().into(), + period: for_n_blocks, + }); + self + } + /// Make the transaction mortal, given a block number and block hash (which must both point to + /// the same block) that it should be mortal from, and the number of blocks (roughly; it'll be + /// rounded to a power of two) that it will be mortal for. + /// + /// Prefer to use [`DefaultExtrinsicParamsBuilder::mortal()`], which ensures that the block hash + /// and number align. + pub fn mortal_unchecked( + mut self, + from_block_number: u64, + from_block_hash: T::Hash, + for_n_blocks: u64, + ) -> Self { + self + .mortality = Some(Mortality { + checkpoint_hash: from_block_hash, + checkpoint_number: from_block_number, + period: for_n_blocks, + }); + self + } + /// Provide a tip to the block author in the chain's native token. + pub fn tip(mut self, tip: u128) -> Self { + self.tip = tip; + self.tip_of = tip; + self.tip_of_asset_id = None; + self + } + /// Provide a tip to the block author using the token denominated by the `asset_id` provided. This + /// is not applicable on chains which don't use the `ChargeAssetTxPayment` signed extension; in this + /// case, no tip will be given. + pub fn tip_of(mut self, tip: u128, asset_id: T::AssetId) -> Self { + self.tip = 0; + self.tip_of = tip; + self.tip_of_asset_id = Some(asset_id); + self + } + /// Build the extrinsic parameters. + pub fn build( + self, + ) -> as ExtrinsicParams>::OtherParams { + let check_mortality_params = if let Some(mortality) = self.mortality { + signed_extensions::CheckMortalityParams::mortal( + mortality.period, + mortality.checkpoint_number, + mortality.checkpoint_hash, + ) + } else { + signed_extensions::CheckMortalityParams::immortal() + }; + let charge_asset_tx_params = if let Some(asset_id) = self.tip_of_asset_id + { + signed_extensions::ChargeAssetTxPaymentParams::tip_of( + self.tip, + asset_id, + ) + } else { + signed_extensions::ChargeAssetTxPaymentParams::tip(self.tip) + }; + let charge_transaction_params = signed_extensions::ChargeTransactionPaymentParams::tip( + self.tip, + ); + ( + (), + (), + (), + (), + check_mortality_params, + charge_asset_tx_params, + charge_transaction_params, + ) + } + } + } + mod extrinsic_params { + //! This module contains a trait which controls the parameters that must + //! be provided in order to successfully construct an extrinsic. + //! [`crate::config::DefaultExtrinsicParams`] provides a general-purpose + //! implementation of this that will work in many cases. + use crate::{client::OfflineClientT, Config}; + use core::fmt::Debug; + /// An error that can be emitted when trying to construct an instance of [`ExtrinsicParams`], + /// encode data from the instance, or match on signed extensions. + #[non_exhaustive] + pub enum ExtrinsicParamsError { + /// Cannot find a type id in the metadata. The context provides some additional + /// information about the source of the error (eg the signed extension name). + #[error( + "Cannot find type id '{type_id} in the metadata (context: {context})" + )] + MissingTypeId { + /// Type ID. + type_id: u32, + /// Some arbitrary context to help narrow the source of the error. + context: &'static str, + }, + /// A signed extension in use on some chain was not provided. + #[error( + "The chain expects a signed extension with the name {0}, but we did not provide one" + )] + UnknownSignedExtension(String), + /// Some custom error. + #[error("Error constructing extrinsic parameters: {0}")] + Custom(CustomExtrinsicParamsError), + } + #[allow(unused_qualifications)] + impl std::error::Error for ExtrinsicParamsError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for ExtrinsicParamsError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + ExtrinsicParamsError::MissingTypeId { type_id, context } => { + __formatter + .write_fmt( + format_args!( + "Cannot find type id \'{0} in the metadata (context: {1})", + type_id.as_display(), context.as_display() + ), + ) + } + ExtrinsicParamsError::UnknownSignedExtension(_0) => { + __formatter + .write_fmt( + format_args!( + "The chain expects a signed extension with the name {0}, but we did not provide one", + _0.as_display() + ), + ) + } + ExtrinsicParamsError::Custom(_0) => { + __formatter + .write_fmt( + format_args!( + "Error constructing extrinsic parameters: {0}", _0 + .as_display() + ), + ) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ExtrinsicParamsError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ExtrinsicParamsError::MissingTypeId { + type_id: __self_0, + context: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "MissingTypeId", + "type_id", + __self_0, + "context", + &__self_1, + ) + } + ExtrinsicParamsError::UnknownSignedExtension(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "UnknownSignedExtension", + &__self_0, + ) + } + ExtrinsicParamsError::Custom(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Custom", + &__self_0, + ) + } + } + } + } + /// A custom error. + pub type CustomExtrinsicParamsError = Box< + dyn std::error::Error + Send + Sync + 'static, + >; + impl From for ExtrinsicParamsError { + fn from(value: std::convert::Infallible) -> Self { + match value {} + } + } + impl From for ExtrinsicParamsError { + fn from(value: CustomExtrinsicParamsError) -> Self { + ExtrinsicParamsError::Custom(value) + } + } + /// This trait allows you to configure the "signed extra" and + /// "additional" parameters that are a part of the transaction payload + /// or the signer payload respectively. + pub trait ExtrinsicParams: ExtrinsicParamsEncoder + Sized + 'static { + /// These parameters can be provided to the constructor along with + /// some default parameters that `subxt` understands, in order to + /// help construct your [`ExtrinsicParams`] object. + type OtherParams; + /// Construct a new instance of our [`ExtrinsicParams`]. + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result; + } + /// This trait is expected to be implemented for any [`ExtrinsicParams`], and + /// defines how to encode the "additional" and "extra" params. Both functions + /// are optional and will encode nothing by default. + pub trait ExtrinsicParamsEncoder: 'static { + /// This is expected to SCALE encode the "signed extra" parameters + /// to some buffer that has been provided. These are the parameters + /// which are sent along with the transaction, as well as taken into + /// account when signing the transaction. + fn encode_extra_to(&self, _v: &mut Vec) {} + /// This is expected to SCALE encode the "additional" parameters + /// to some buffer that has been provided. These parameters are _not_ + /// sent along with the transaction, but are taken into account when + /// signing it, meaning the client and node must agree on their values. + fn encode_additional_to(&self, _v: &mut Vec) {} + } + } + pub mod polkadot { + //! Polkadot specific configuration + use super::{Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder}; + pub use crate::utils::{AccountId32, MultiAddress, MultiSignature}; + use crate::SubstrateConfig; + pub use primitive_types::{H256, U256}; + /// Default set of commonly used types by Polkadot nodes. + pub enum PolkadotConfig {} + impl Config for PolkadotConfig { + type Hash = ::Hash; + type AccountId = ::AccountId; + type Address = MultiAddress; + type Signature = ::Signature; + type Hasher = ::Hasher; + type Header = ::Header; + type ExtrinsicParams = PolkadotExtrinsicParams; + type AssetId = u32; + } + /// A struct representing the signed extra and additional parameters required + /// to construct a transaction for a polkadot node. + pub type PolkadotExtrinsicParams = DefaultExtrinsicParams; + /// A builder which leads to [`PolkadotExtrinsicParams`] being constructed. + /// This is what you provide to methods like `sign_and_submit()`. + pub type PolkadotExtrinsicParamsBuilder = DefaultExtrinsicParamsBuilder; + } + pub mod signed_extensions { + //! This module contains implementations for common signed extensions, each + //! of which implements [`SignedExtension`], and can be used in conjunction with + //! [`AnyOf`] to configure the set of signed extensions which are known about + //! when interacting with a chain. + use super::extrinsic_params::{ + ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, + }; + use crate::utils::Era; + use crate::{client::OfflineClientT, Config}; + use codec::{Compact, Encode}; + use core::fmt::Debug; + use derivative::Derivative; + use scale_decode::DecodeAsType; + use scale_info::PortableRegistry; + use std::collections::HashMap; + /// A single [`SignedExtension`] has a unique name, but is otherwise the + /// same as [`ExtrinsicParams`] in describing how to encode the extra and + /// additional data. + pub trait SignedExtension: ExtrinsicParams { + /// The type representing the `extra` bytes of a signed extension. + /// Decoding from this type should be symmetrical to the respective + /// `ExtrinsicParamsEncoder::encode_extra_to()` implementation of this signed extension. + type Decoded: DecodeAsType; + /// This should return true if the signed extension matches the details given. + /// Often, this will involve just checking that the identifier given matches that of the + /// extension in question. + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool; + } + /// The [`CheckSpecVersion`] signed extension. + pub struct CheckSpecVersion(u32); + impl ExtrinsicParams for CheckSpecVersion { + type OtherParams = (); + fn new>( + _nonce: u64, + client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CheckSpecVersion(client.runtime_version().spec_version)) + } + } + impl ExtrinsicParamsEncoder for CheckSpecVersion { + fn encode_additional_to(&self, v: &mut Vec) { + self.0.encode_to(v); + } + } + impl SignedExtension for CheckSpecVersion { + type Decoded = (); + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckSpecVersion" + } + } + /// The [`CheckNonce`] signed extension. + pub struct CheckNonce(Compact); + impl ExtrinsicParams for CheckNonce { + type OtherParams = (); + fn new>( + nonce: u64, + _client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CheckNonce(Compact(nonce))) + } + } + impl ExtrinsicParamsEncoder for CheckNonce { + fn encode_extra_to(&self, v: &mut Vec) { + self.0.encode_to(v); + } + } + impl SignedExtension for CheckNonce { + type Decoded = u64; + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckNonce" + } + } + /// The [`CheckTxVersion`] signed extension. + pub struct CheckTxVersion(u32); + impl ExtrinsicParams for CheckTxVersion { + type OtherParams = (); + fn new>( + _nonce: u64, + client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CheckTxVersion(client.runtime_version().transaction_version)) + } + } + impl ExtrinsicParamsEncoder for CheckTxVersion { + fn encode_additional_to(&self, v: &mut Vec) { + self.0.encode_to(v); + } + } + impl SignedExtension for CheckTxVersion { + type Decoded = (); + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckTxVersion" + } + } + /// The [`CheckGenesis`] signed extension. + pub struct CheckGenesis(T::Hash); + impl ExtrinsicParams for CheckGenesis { + type OtherParams = (); + fn new>( + _nonce: u64, + client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CheckGenesis(client.genesis_hash())) + } + } + impl ExtrinsicParamsEncoder for CheckGenesis { + fn encode_additional_to(&self, v: &mut Vec) { + self.0.encode_to(v); + } + } + impl SignedExtension for CheckGenesis { + type Decoded = (); + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckGenesis" + } + } + /// The [`CheckMortality`] signed extension. + pub struct CheckMortality { + era: Era, + checkpoint: T::Hash, + } + /// Parameters to configure the [`CheckMortality`] signed extension. + pub struct CheckMortalityParams { + era: Era, + checkpoint: Option, + } + impl Default for CheckMortalityParams { + fn default() -> Self { + Self { + era: Default::default(), + checkpoint: Default::default(), + } + } + } + impl CheckMortalityParams { + /// Configure a mortal transaction. The `period` is (roughly) how many + /// blocks the transaction will be valid for. The `block_number` and + /// `block_hash` should both point to the same block, and are the block that + /// the transaction is mortal from. + pub fn mortal(period: u64, block_number: u64, block_hash: T::Hash) -> Self { + CheckMortalityParams { + era: Era::mortal(period, block_number), + checkpoint: Some(block_hash), + } + } + /// An immortal transaction. + pub fn immortal() -> Self { + CheckMortalityParams { + era: Era::Immortal, + checkpoint: None, + } + } + } + impl ExtrinsicParams for CheckMortality { + type OtherParams = CheckMortalityParams; + fn new>( + _nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + Ok(CheckMortality { + era: other_params.era, + checkpoint: other_params.checkpoint.unwrap_or(client.genesis_hash()), + }) + } + } + impl ExtrinsicParamsEncoder for CheckMortality { + fn encode_extra_to(&self, v: &mut Vec) { + self.era.encode_to(v); + } + fn encode_additional_to(&self, v: &mut Vec) { + self.checkpoint.encode_to(v); + } + } + impl SignedExtension for CheckMortality { + type Decoded = Era; + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckMortality" + } + } + /// The [`ChargeAssetTxPayment`] signed extension. + #[derivative( + Clone(bound = "T::AssetId: Clone"), + Debug(bound = "T::AssetId: Debug") + )] + #[decode_as_type(trait_bounds = "T::AssetId: DecodeAsType")] + pub struct ChargeAssetTxPayment { + tip: Compact, + asset_id: Option, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for ChargeAssetTxPayment + where + T::AssetId: Clone, + { + fn clone(&self) -> Self { + match *self { + ChargeAssetTxPayment { tip: ref __arg_0, asset_id: ref __arg_1 } => { + ChargeAssetTxPayment { + tip: (*__arg_0).clone(), + asset_id: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for ChargeAssetTxPayment + where + T::AssetId: Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + ChargeAssetTxPayment { tip: ref __arg_0, asset_id: ref __arg_1 } => { + let mut __debug_trait_builder = __f + .debug_struct("ChargeAssetTxPayment"); + let _ = __debug_trait_builder.field("tip", &&(*__arg_0)); + let _ = __debug_trait_builder.field("asset_id", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<(T,)>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for ChargeAssetTxPayment + where + T::AssetId: DecodeAsType, + { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor + where + T::AssetId: DecodeAsType, + { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = ChargeAssetTxPayment; + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.has_unnamed_fields() { + return self.visit_tuple(&mut value.as_tuple(), type_id); + } + let vals: ::scale_decode::BTreeMap, _> = value + .map(|res| res.map(|item| (item.name(), item))) + .collect::>()?; + Ok(ChargeAssetTxPayment { + tip: { + let val = *vals + .get(&Some("tip")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "tip".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("tip"))? + }, + asset_id: { + let val = *vals + .get(&Some("asset_id")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "asset_id".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("asset_id"))? + }, + }) + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 2usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: value.remaining(), + expected_len: 2usize, + }), + ); + } + let vals = value; + Ok(ChargeAssetTxPayment { + tip: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("tip"))? + }, + asset_id: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("asset_id"))? + }, + }) + } + } + impl ::scale_decode::DecodeAsFields for ChargeAssetTxPayment + where + T::AssetId: DecodeAsType, + { + fn decode_as_fields<'info>( + input: &mut &[u8], + fields: &mut dyn ::scale_decode::FieldIter<'info>, + types: &'info ::scale_decode::PortableRegistry, + ) -> Result { + let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; + let mut composite = ::scale_decode::visitor::types::Composite::new( + input, + path, + fields, + types, + false, + ); + use ::scale_decode::{Visitor, IntoVisitor}; + let val = >::into_visitor() + .visit_composite( + &mut composite, + ::scale_decode::visitor::TypeId(0), + ); + composite.skip_decoding()?; + *input = composite.bytes_from_undecoded(); + val.map_err(From::from) + } + } + }; + impl ChargeAssetTxPayment { + /// Tip to the extrinsic author in the native chain token. + pub fn tip(&self) -> u128 { + self.tip.0 + } + /// Tip to the extrinsic author using the asset ID given. + pub fn asset_id(&self) -> Option<&T::AssetId> { + self.asset_id.as_ref() + } + } + /// Parameters to configure the [`ChargeAssetTxPayment`] signed extension. + pub struct ChargeAssetTxPaymentParams { + tip: u128, + asset_id: Option, + } + impl Default for ChargeAssetTxPaymentParams { + fn default() -> Self { + ChargeAssetTxPaymentParams { + tip: Default::default(), + asset_id: Default::default(), + } + } + } + impl ChargeAssetTxPaymentParams { + /// Don't provide a tip to the extrinsic author. + pub fn no_tip() -> Self { + ChargeAssetTxPaymentParams { + tip: 0, + asset_id: None, + } + } + /// Tip the extrinsic author in the native chain token. + pub fn tip(tip: u128) -> Self { + ChargeAssetTxPaymentParams { + tip, + asset_id: None, + } + } + /// Tip the extrinsic author using the asset ID given. + pub fn tip_of(tip: u128, asset_id: T::AssetId) -> Self { + ChargeAssetTxPaymentParams { + tip, + asset_id: Some(asset_id), + } + } + } + impl ExtrinsicParams for ChargeAssetTxPayment { + type OtherParams = ChargeAssetTxPaymentParams; + fn new>( + _nonce: u64, + _client: Client, + other_params: Self::OtherParams, + ) -> Result { + Ok(ChargeAssetTxPayment { + tip: Compact(other_params.tip), + asset_id: other_params.asset_id, + }) + } + } + impl ExtrinsicParamsEncoder for ChargeAssetTxPayment { + fn encode_extra_to(&self, v: &mut Vec) { + (self.tip, &self.asset_id).encode_to(v); + } + } + impl SignedExtension for ChargeAssetTxPayment { + type Decoded = Self; + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "ChargeAssetTxPayment" + } + } + /// The [`ChargeTransactionPayment`] signed extension. + pub struct ChargeTransactionPayment { + tip: Compact, + } + #[automatically_derived] + impl ::core::clone::Clone for ChargeTransactionPayment { + #[inline] + fn clone(&self) -> ChargeTransactionPayment { + ChargeTransactionPayment { + tip: ::core::clone::Clone::clone(&self.tip), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ChargeTransactionPayment { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "ChargeTransactionPayment", + "tip", + &&self.tip, + ) + } + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for ChargeTransactionPayment { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = ChargeTransactionPayment; + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.has_unnamed_fields() { + return self.visit_tuple(&mut value.as_tuple(), type_id); + } + let vals: ::scale_decode::BTreeMap, _> = value + .map(|res| res.map(|item| (item.name(), item))) + .collect::>()?; + Ok(ChargeTransactionPayment { + tip: { + let val = *vals + .get(&Some("tip")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "tip".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("tip"))? + }, + }) + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: value.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = value; + Ok(ChargeTransactionPayment { + tip: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("tip"))? + }, + }) + } + } + impl ::scale_decode::DecodeAsFields for ChargeTransactionPayment { + fn decode_as_fields<'info>( + input: &mut &[u8], + fields: &mut dyn ::scale_decode::FieldIter<'info>, + types: &'info ::scale_decode::PortableRegistry, + ) -> Result { + let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; + let mut composite = ::scale_decode::visitor::types::Composite::new( + input, + path, + fields, + types, + false, + ); + use ::scale_decode::{Visitor, IntoVisitor}; + let val = ::into_visitor() + .visit_composite( + &mut composite, + ::scale_decode::visitor::TypeId(0), + ); + composite.skip_decoding()?; + *input = composite.bytes_from_undecoded(); + val.map_err(From::from) + } + } + }; + impl ChargeTransactionPayment { + /// Tip to the extrinsic author in the native chain token. + pub fn tip(&self) -> u128 { + self.tip.0 + } + } + /// Parameters to configure the [`ChargeTransactionPayment`] signed extension. + pub struct ChargeTransactionPaymentParams { + tip: u128, + } + #[automatically_derived] + impl ::core::default::Default for ChargeTransactionPaymentParams { + #[inline] + fn default() -> ChargeTransactionPaymentParams { + ChargeTransactionPaymentParams { + tip: ::core::default::Default::default(), + } + } + } + impl ChargeTransactionPaymentParams { + /// Don't provide a tip to the extrinsic author. + pub fn no_tip() -> Self { + ChargeTransactionPaymentParams { + tip: 0, + } + } + /// Tip the extrinsic author in the native chain token. + pub fn tip(tip: u128) -> Self { + ChargeTransactionPaymentParams { + tip, + } + } + } + impl ExtrinsicParams for ChargeTransactionPayment { + type OtherParams = ChargeTransactionPaymentParams; + fn new>( + _nonce: u64, + _client: Client, + other_params: Self::OtherParams, + ) -> Result { + Ok(ChargeTransactionPayment { + tip: Compact(other_params.tip), + }) + } + } + impl ExtrinsicParamsEncoder for ChargeTransactionPayment { + fn encode_extra_to(&self, v: &mut Vec) { + self.tip.encode_to(v); + } + } + impl SignedExtension for ChargeTransactionPayment { + type Decoded = Self; + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "ChargeTransactionPayment" + } + } + /// This accepts a tuple of [`SignedExtension`]s, and will dynamically make use of whichever + /// ones are actually required for the chain in the correct order, ignoring the rest. This + /// is a sensible default, and allows for a single configuration to work across multiple chains. + pub struct AnyOf { + params: Vec>, + _marker: std::marker::PhantomData<(T, Params)>, + } + #[rustfmt::skip] + const _: () = { + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + { + type OtherParams = (A::OtherParams,); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + { + type OtherParams = (A::OtherParams, B::OtherParams); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + { + type OtherParams = (A::OtherParams, B::OtherParams, C::OtherParams); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + > ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + R::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if R::matches(e.identifier(), e.extra_ty(), types) { + let ext = R::new(nonce, client.clone(), other_params.17)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + > ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + R::OtherParams, + S::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if R::matches(e.identifier(), e.extra_ty(), types) { + let ext = R::new(nonce, client.clone(), other_params.17)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if S::matches(e.identifier(), e.extra_ty(), types) { + let ext = S::new(nonce, client.clone(), other_params.18)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + U, + > ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + U: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + R::OtherParams, + S::OtherParams, + U::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if R::matches(e.identifier(), e.extra_ty(), types) { + let ext = R::new(nonce, client.clone(), other_params.17)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if S::matches(e.identifier(), e.extra_ty(), types) { + let ext = S::new(nonce, client.clone(), other_params.18)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if U::matches(e.identifier(), e.extra_ty(), types) { + let ext = U::new(nonce, client.clone(), other_params.19)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + U, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + U: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + U, + V, + > ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + U: SignedExtension, + V: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + R::OtherParams, + S::OtherParams, + U::OtherParams, + V::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if R::matches(e.identifier(), e.extra_ty(), types) { + let ext = R::new(nonce, client.clone(), other_params.17)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if S::matches(e.identifier(), e.extra_ty(), types) { + let ext = S::new(nonce, client.clone(), other_params.18)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if U::matches(e.identifier(), e.extra_ty(), types) { + let ext = U::new(nonce, client.clone(), other_params.19)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if V::matches(e.identifier(), e.extra_ty(), types) { + let ext = V::new(nonce, client.clone(), other_params.20)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + U, + V, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + U: SignedExtension, + V: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + }; + /// Checks to see whether the type being given is empty, ie would require + /// 0 bytes to encode. + fn is_type_empty(type_id: u32, types: &scale_info::PortableRegistry) -> bool { + let Some(ty) = types.resolve(type_id) else { return false; + }; + use scale_info::TypeDef; + match &ty.type_def { + TypeDef::Composite(c) => { + c.fields.iter().all(|f| is_type_empty(f.ty.id, types)) + } + TypeDef::Array(a) => a.len == 0 || is_type_empty(a.type_param.id, types), + TypeDef::Tuple(t) => t.fields.iter().all(|f| is_type_empty(f.id, types)), + TypeDef::BitSequence(_) + | TypeDef::Variant(_) + | TypeDef::Sequence(_) + | TypeDef::Compact(_) + | TypeDef::Primitive(_) => false, + } + } + } + pub mod substrate { + //! Substrate specific configuration + use super::{ + Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, Hasher, Header, + }; + use codec::{Decode, Encode}; + use serde::{Deserialize, Serialize}; + pub use crate::utils::{AccountId32, MultiAddress, MultiSignature}; + pub use primitive_types::{H256, U256}; + /// Default set of commonly used types by Substrate runtimes. + pub enum SubstrateConfig {} + impl Config for SubstrateConfig { + type Hash = H256; + type AccountId = AccountId32; + type Address = MultiAddress; + type Signature = MultiSignature; + type Hasher = BlakeTwo256; + type Header = SubstrateHeader; + type ExtrinsicParams = SubstrateExtrinsicParams; + type AssetId = u32; + } + /// A struct representing the signed extra and additional parameters required + /// to construct a transaction for the default substrate node. + pub type SubstrateExtrinsicParams = DefaultExtrinsicParams; + /// A builder which leads to [`SubstrateExtrinsicParams`] being constructed. + /// This is what you provide to methods like `sign_and_submit()`. + pub type SubstrateExtrinsicParamsBuilder = DefaultExtrinsicParamsBuilder; + /// A type that can hash values using the blaks2_256 algorithm. + pub struct BlakeTwo256; + #[automatically_derived] + impl ::core::fmt::Debug for BlakeTwo256 { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "BlakeTwo256") + } + } + #[automatically_derived] + impl ::core::clone::Clone for BlakeTwo256 { + #[inline] + fn clone(&self) -> BlakeTwo256 { + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for BlakeTwo256 {} + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BlakeTwo256 {} + #[automatically_derived] + impl ::core::cmp::PartialEq for BlakeTwo256 { + #[inline] + fn eq(&self, other: &BlakeTwo256) -> bool { + true + } + } + #[automatically_derived] + impl ::core::cmp::Eq for BlakeTwo256 { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for BlakeTwo256 { + fn size_hint(&self) -> usize { + 0_usize + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) {} + } + #[automatically_derived] + impl ::codec::EncodeLike for BlakeTwo256 {} + }; + impl Hasher for BlakeTwo256 { + type Output = H256; + fn hash(s: &[u8]) -> Self::Output { + sp_core_hashing::blake2_256(s).into() + } + } + /// A generic Substrate header type, adapted from `sp_runtime::generic::Header`. + /// The block number and hasher can be configured to adapt this for other nodes. + #[serde(rename_all = "camelCase")] + pub struct SubstrateHeader + TryFrom, H: Hasher> { + /// The parent hash. + pub parent_hash: H::Output, + /// The block number. + #[serde( + serialize_with = "serialize_number", + deserialize_with = "deserialize_number" + )] + #[codec(compact)] + pub number: N, + /// The state trie merkle root + pub state_root: H::Output, + /// The merkle root of the extrinsics. + pub extrinsics_root: H::Output, + /// A chain-specific digest of data useful for light clients or referencing auxiliary data. + pub digest: Digest, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl + TryFrom, H: Hasher> ::codec::Encode + for SubstrateHeader + where + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + N: ::codec::HasCompact, + { + fn size_hint(&self) -> usize { + 0_usize + .saturating_add(::codec::Encode::size_hint(&self.parent_hash)) + .saturating_add( + ::codec::Encode::size_hint( + &<::Type as ::codec::EncodeAsRef< + '_, + N, + >>::RefType::from(&self.number), + ), + ) + .saturating_add(::codec::Encode::size_hint(&self.state_root)) + .saturating_add( + ::codec::Encode::size_hint(&self.extrinsics_root), + ) + .saturating_add(::codec::Encode::size_hint(&self.digest)) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&self.parent_hash, __codec_dest_edqy); + { + ::codec::Encode::encode_to( + &<::Type as ::codec::EncodeAsRef< + '_, + N, + >>::RefType::from(&self.number), + __codec_dest_edqy, + ); + } + ::codec::Encode::encode_to(&self.state_root, __codec_dest_edqy); + ::codec::Encode::encode_to(&self.extrinsics_root, __codec_dest_edqy); + ::codec::Encode::encode_to(&self.digest, __codec_dest_edqy); + } + } + #[automatically_derived] + impl + TryFrom, H: Hasher> ::codec::EncodeLike + for SubstrateHeader + where + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + N: ::codec::HasCompact, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl + TryFrom, H: Hasher> ::codec::Decode + for SubstrateHeader + where + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + N: ::codec::HasCompact, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(SubstrateHeader:: { + parent_hash: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `SubstrateHeader::parent_hash`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + number: { + let __codec_res_edqy = <::Type as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `SubstrateHeader::number`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy.into() + } + } + }, + state_root: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `SubstrateHeader::state_root`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + extrinsics_root: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e + .chain( + "Could not decode `SubstrateHeader::extrinsics_root`", + ), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + digest: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `SubstrateHeader::digest`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + #[automatically_derived] + impl< + N: ::core::fmt::Debug + Copy + Into + TryFrom, + H: ::core::fmt::Debug + Hasher, + > ::core::fmt::Debug for SubstrateHeader + where + H::Output: ::core::fmt::Debug, + H::Output: ::core::fmt::Debug, + H::Output: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "SubstrateHeader", + "parent_hash", + &self.parent_hash, + "number", + &self.number, + "state_root", + &self.state_root, + "extrinsics_root", + &self.extrinsics_root, + "digest", + &&self.digest, + ) + } + } + #[automatically_derived] + impl< + N: Copy + Into + TryFrom, + H: Hasher, + > ::core::marker::StructuralPartialEq for SubstrateHeader {} + #[automatically_derived] + impl< + N: ::core::cmp::PartialEq + Copy + Into + TryFrom, + H: ::core::cmp::PartialEq + Hasher, + > ::core::cmp::PartialEq for SubstrateHeader + where + H::Output: ::core::cmp::PartialEq, + H::Output: ::core::cmp::PartialEq, + H::Output: ::core::cmp::PartialEq, + { + #[inline] + fn eq(&self, other: &SubstrateHeader) -> bool { + self.parent_hash == other.parent_hash && self.number == other.number + && self.state_root == other.state_root + && self.extrinsics_root == other.extrinsics_root + && self.digest == other.digest + } + } + #[automatically_derived] + impl< + N: ::core::cmp::Eq + Copy + Into + TryFrom, + H: ::core::cmp::Eq + Hasher, + > ::core::cmp::Eq for SubstrateHeader + where + H::Output: ::core::cmp::Eq, + H::Output: ::core::cmp::Eq, + H::Output: ::core::cmp::Eq, + { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl< + N: ::core::clone::Clone + Copy + Into + TryFrom, + H: ::core::clone::Clone + Hasher, + > ::core::clone::Clone for SubstrateHeader + where + H::Output: ::core::clone::Clone, + H::Output: ::core::clone::Clone, + H::Output: ::core::clone::Clone, + { + #[inline] + fn clone(&self) -> SubstrateHeader { + SubstrateHeader { + parent_hash: ::core::clone::Clone::clone(&self.parent_hash), + number: ::core::clone::Clone::clone(&self.number), + state_root: ::core::clone::Clone::clone(&self.state_root), + extrinsics_root: ::core::clone::Clone::clone(&self.extrinsics_root), + digest: ::core::clone::Clone::clone(&self.digest), + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl + TryFrom, H: Hasher> _serde::Serialize + for SubstrateHeader + where + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "SubstrateHeader", + false as usize + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "parentHash", + &self.parent_hash, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "number", + { + #[doc(hidden)] + struct __SerializeWith< + '__a, + N: Copy + Into + TryFrom + '__a, + H: Hasher + '__a, + > + where + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + { + values: (&'__a N,), + phantom: _serde::__private::PhantomData< + SubstrateHeader, + >, + } + impl< + '__a, + N: Copy + Into + TryFrom + '__a, + H: Hasher + '__a, + > _serde::Serialize for __SerializeWith<'__a, N, H> + where + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + { + fn serialize<__S>( + &self, + __s: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + serialize_number(self.values.0, __s) + } + } + &__SerializeWith { + values: (&self.number,), + phantom: _serde::__private::PhantomData::< + SubstrateHeader, + >, + } + }, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "stateRoot", + &self.state_root, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "extrinsicsRoot", + &self.extrinsics_root, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "digest", + &self.digest, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > _serde::Deserialize<'de> for SubstrateHeader + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "parentHash" => _serde::__private::Ok(__Field::__field0), + "number" => _serde::__private::Ok(__Field::__field1), + "stateRoot" => _serde::__private::Ok(__Field::__field2), + "extrinsicsRoot" => _serde::__private::Ok(__Field::__field3), + "digest" => _serde::__private::Ok(__Field::__field4), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"parentHash" => _serde::__private::Ok(__Field::__field0), + b"number" => _serde::__private::Ok(__Field::__field1), + b"stateRoot" => _serde::__private::Ok(__Field::__field2), + b"extrinsicsRoot" => { + _serde::__private::Ok(__Field::__field3) + } + b"digest" => _serde::__private::Ok(__Field::__field4), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > _serde::de::Visitor<'de> for __Visitor<'de, N, H> + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + type Value = SubstrateHeader; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct SubstrateHeader", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + H::Output, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + let __field1 = match { + #[doc(hidden)] + struct __DeserializeWith< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + value: N, + phantom: _serde::__private::PhantomData< + SubstrateHeader, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > _serde::Deserialize<'de> for __DeserializeWith<'de, N, H> + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: deserialize_number(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de, N, H>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + H::Output, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + H::Output, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + Digest, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + _serde::__private::Ok(SubstrateHeader { + parent_hash: __field0, + number: __field1, + state_root: __field2, + extrinsics_root: __field3, + digest: __field4, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option = _serde::__private::None; + let mut __field3: _serde::__private::Option = _serde::__private::None; + let mut __field4: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "parentHash", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("number"), + ); + } + __field1 = _serde::__private::Some({ + #[doc(hidden)] + struct __DeserializeWith< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + value: N, + phantom: _serde::__private::PhantomData< + SubstrateHeader, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > _serde::Deserialize<'de> for __DeserializeWith<'de, N, H> + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: deserialize_number(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + match _serde::de::MapAccess::next_value::< + __DeserializeWith<'de, N, H>, + >(&mut __map) { + _serde::__private::Ok(__wrapper) => __wrapper.value, + _serde::__private::Err(__err) => { + return _serde::__private::Err(__err); + } + } + }); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "stateRoot", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private::Option::is_some(&__field3) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "extrinsicsRoot", + ), + ); + } + __field3 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private::Option::is_some(&__field4) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("digest"), + ); + } + __field4 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("parentHash")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::missing_field("number"), + ); + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("stateRoot")? + } + }; + let __field3 = match __field3 { + _serde::__private::Some(__field3) => __field3, + _serde::__private::None => { + _serde::__private::de::missing_field("extrinsicsRoot")? + } + }; + let __field4 = match __field4 { + _serde::__private::Some(__field4) => __field4, + _serde::__private::None => { + _serde::__private::de::missing_field("digest")? + } + }; + _serde::__private::Ok(SubstrateHeader { + parent_hash: __field0, + number: __field1, + state_root: __field2, + extrinsics_root: __field3, + digest: __field4, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "parentHash", + "number", + "stateRoot", + "extrinsicsRoot", + "digest", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SubstrateHeader", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + SubstrateHeader, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + impl Header for SubstrateHeader + where + N: Copy + Into + Into + TryFrom + Encode, + H: Hasher + Encode, + SubstrateHeader: Encode + Decode, + { + type Number = N; + type Hasher = H; + fn number(&self) -> Self::Number { + self.number + } + } + /// Generic header digest. From `sp_runtime::generic::digest`. + pub struct Digest { + /// A list of digest items. + pub logs: Vec, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for Digest { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.logs) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&&self.logs, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.logs) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.logs, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike for Digest {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for Digest { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(Digest { + logs: { + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `Digest::logs`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for Digest { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Digest", + "logs", + &&self.logs, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Digest {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Digest { + #[inline] + fn eq(&self, other: &Digest) -> bool { + self.logs == other.logs + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Digest { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Digest { + #[inline] + fn clone(&self) -> Digest { + Digest { + logs: ::core::clone::Clone::clone(&self.logs), + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Digest { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Digest", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "logs", + &self.logs, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Digest { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "logs" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"logs" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Digest; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct Digest", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Digest with 1 element", + ), + ); + } + }; + _serde::__private::Ok(Digest { logs: __field0 }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option< + Vec, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("logs"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Vec, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("logs")? + } + }; + _serde::__private::Ok(Digest { logs: __field0 }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["logs"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Digest", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::default::Default for Digest { + #[inline] + fn default() -> Digest { + Digest { + logs: ::core::default::Default::default(), + } + } + } + /// Digest item that is able to encode/decode 'system' digest items and + /// provide opaque access to other items. From `sp_runtime::generic::digest`. + pub enum DigestItem { + /// A pre-runtime digest. + /// + /// These are messages from the consensus engine to the runtime, although + /// the consensus engine can (and should) read them itself to avoid + /// code and state duplication. It is erroneous for a runtime to produce + /// these, but this is not (yet) checked. + /// + /// NOTE: the runtime is not allowed to panic or fail in an `on_initialize` + /// call if an expected `PreRuntime` digest is not present. It is the + /// responsibility of a external block verifier to check this. Runtime API calls + /// will initialize the block without pre-runtime digests, so initialization + /// cannot fail when they are missing. + PreRuntime(ConsensusEngineId, Vec), + /// A message from the runtime to the consensus engine. This should *never* + /// be generated by the native code of any consensus engine, but this is not + /// checked (yet). + Consensus(ConsensusEngineId, Vec), + /// Put a Seal on it. This is only used by native code, and is never seen + /// by runtimes. + Seal(ConsensusEngineId, Vec), + /// Some other thing. Unsupported and experimental. + Other(Vec), + /// An indication for the light clients that the runtime execution + /// environment is updated. + /// + /// Currently this is triggered when: + /// 1. Runtime code blob is changed or + /// 2. `heap_pages` value is changed. + RuntimeEnvironmentUpdated, + } + #[automatically_derived] + impl ::core::fmt::Debug for DigestItem { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + DigestItem::PreRuntime(__self_0, __self_1) => { + ::core::fmt::Formatter::debug_tuple_field2_finish( + f, + "PreRuntime", + __self_0, + &__self_1, + ) + } + DigestItem::Consensus(__self_0, __self_1) => { + ::core::fmt::Formatter::debug_tuple_field2_finish( + f, + "Consensus", + __self_0, + &__self_1, + ) + } + DigestItem::Seal(__self_0, __self_1) => { + ::core::fmt::Formatter::debug_tuple_field2_finish( + f, + "Seal", + __self_0, + &__self_1, + ) + } + DigestItem::Other(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Other", + &__self_0, + ) + } + DigestItem::RuntimeEnvironmentUpdated => { + ::core::fmt::Formatter::write_str(f, "RuntimeEnvironmentUpdated") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DigestItem {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DigestItem { + #[inline] + fn eq(&self, other: &DigestItem) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + DigestItem::PreRuntime(__self_0, __self_1), + DigestItem::PreRuntime(__arg1_0, __arg1_1), + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + ( + DigestItem::Consensus(__self_0, __self_1), + DigestItem::Consensus(__arg1_0, __arg1_1), + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + ( + DigestItem::Seal(__self_0, __self_1), + DigestItem::Seal(__arg1_0, __arg1_1), + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + (DigestItem::Other(__self_0), DigestItem::Other(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DigestItem { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for DigestItem { + #[inline] + fn clone(&self) -> DigestItem { + match self { + DigestItem::PreRuntime(__self_0, __self_1) => { + DigestItem::PreRuntime( + ::core::clone::Clone::clone(__self_0), + ::core::clone::Clone::clone(__self_1), + ) + } + DigestItem::Consensus(__self_0, __self_1) => { + DigestItem::Consensus( + ::core::clone::Clone::clone(__self_0), + ::core::clone::Clone::clone(__self_1), + ) + } + DigestItem::Seal(__self_0, __self_1) => { + DigestItem::Seal( + ::core::clone::Clone::clone(__self_0), + ::core::clone::Clone::clone(__self_1), + ) + } + DigestItem::Other(__self_0) => { + DigestItem::Other(::core::clone::Clone::clone(__self_0)) + } + DigestItem::RuntimeEnvironmentUpdated => { + DigestItem::RuntimeEnvironmentUpdated + } + } + } + } + #[repr(u32)] + enum DigestItemType { + Other = 0u32, + Consensus = 4u32, + Seal = 5u32, + PreRuntime = 6u32, + RuntimeEnvironmentUpdated = 8u32, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for DigestItemType { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + DigestItemType::Other => 0_usize, + DigestItemType::Consensus => 0_usize, + DigestItemType::Seal => 0_usize, + DigestItemType::PreRuntime => 0_usize, + DigestItemType::RuntimeEnvironmentUpdated => 0_usize, + _ => 0_usize, + } + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + match *self { + DigestItemType::Other => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(0u32 as ::core::primitive::u8); + } + DigestItemType::Consensus => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(4u32 as ::core::primitive::u8); + } + DigestItemType::Seal => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(5u32 as ::core::primitive::u8); + } + DigestItemType::PreRuntime => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(6u32 as ::core::primitive::u8); + } + DigestItemType::RuntimeEnvironmentUpdated => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(8u32 as ::core::primitive::u8); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::codec::EncodeLike for DigestItemType {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for DigestItemType { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `DigestItemType`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(DigestItemType::Other) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 4u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(DigestItemType::Consensus) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 5u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(DigestItemType::Seal) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 6u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(DigestItemType::PreRuntime) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 8u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + DigestItemType::RuntimeEnvironmentUpdated, + ) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `DigestItemType`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + impl Encode for DigestItem { + fn encode(&self) -> Vec { + let mut v = Vec::new(); + match self { + Self::Consensus(val, data) => { + DigestItemType::Consensus.encode_to(&mut v); + (val, data).encode_to(&mut v); + } + Self::Seal(val, sig) => { + DigestItemType::Seal.encode_to(&mut v); + (val, sig).encode_to(&mut v); + } + Self::PreRuntime(val, data) => { + DigestItemType::PreRuntime.encode_to(&mut v); + (val, data).encode_to(&mut v); + } + Self::Other(val) => { + DigestItemType::Other.encode_to(&mut v); + val.encode_to(&mut v); + } + Self::RuntimeEnvironmentUpdated => { + DigestItemType::RuntimeEnvironmentUpdated.encode_to(&mut v); + } + } + v + } + } + impl Decode for DigestItem { + fn decode(input: &mut I) -> Result { + let item_type: DigestItemType = Decode::decode(input)?; + match item_type { + DigestItemType::PreRuntime => { + let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; + Ok(Self::PreRuntime(vals.0, vals.1)) + } + DigestItemType::Consensus => { + let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; + Ok(Self::Consensus(vals.0, vals.1)) + } + DigestItemType::Seal => { + let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; + Ok(Self::Seal(vals.0, vals.1)) + } + DigestItemType::Other => Ok(Self::Other(Decode::decode(input)?)), + DigestItemType::RuntimeEnvironmentUpdated => { + Ok(Self::RuntimeEnvironmentUpdated) + } + } + } + } + /// Consensus engine unique ID. From `sp_runtime::ConsensusEngineId`. + pub type ConsensusEngineId = [u8; 4]; + impl serde::Serialize for DigestItem { + fn serialize(&self, seq: S) -> Result + where + S: serde::Serializer, + { + self.using_encoded(|bytes| impl_serde::serialize::serialize(bytes, seq)) + } + } + impl<'a> serde::Deserialize<'a> for DigestItem { + fn deserialize(de: D) -> Result + where + D: serde::Deserializer<'a>, + { + let r = impl_serde::serialize::deserialize(de)?; + Decode::decode(&mut &r[..]) + .map_err(|e| serde::de::Error::custom({ + let res = ::alloc::fmt::format( + format_args!("Decode error: {0}", e), + ); + res + })) + } + } + fn serialize_number>( + val: &T, + s: S, + ) -> Result + where + S: serde::Serializer, + { + let u256: U256 = (*val).into(); + serde::Serialize::serialize(&u256, s) + } + fn deserialize_number<'a, D, T: TryFrom>(d: D) -> Result + where + D: serde::Deserializer<'a>, + { + use crate::backend::legacy::rpc_methods::NumberOrHex; + let number_or_hex = NumberOrHex::deserialize(d)?; + let u256 = number_or_hex.into_u256(); + TryFrom::try_from(u256) + .map_err(|_| serde::de::Error::custom("Try from failed")) + } + } + use crate::macros::cfg_substrate_compat; + use codec::{Decode, Encode}; + use core::fmt::Debug; + use scale_decode::DecodeAsType; + use scale_encode::EncodeAsType; + use serde::{de::DeserializeOwned, Serialize}; + pub use default_extrinsic_params::{ + DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, + }; + pub use extrinsic_params::{ + ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, + }; + pub use polkadot::{ + PolkadotConfig, PolkadotExtrinsicParams, PolkadotExtrinsicParamsBuilder, + }; + pub use signed_extensions::SignedExtension; + pub use substrate::{ + SubstrateConfig, SubstrateExtrinsicParams, SubstrateExtrinsicParamsBuilder, + }; + /// Runtime types. + pub trait Config: Sized + Send + Sync + 'static { + /// The output of the `Hasher` function. + type Hash: BlockHash; + /// The account ID type. + type AccountId: Debug + Clone + Encode; + /// The address type. + type Address: Debug + Encode + From; + /// The signature type. + type Signature: Debug + Encode; + /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). + type Hasher: Debug + Hasher; + /// The block header. + type Header: Debug + + Header + + Sync + + Send + + DeserializeOwned; + /// This type defines the extrinsic extra and additional parameters. + type ExtrinsicParams: ExtrinsicParams; + /// This is used to identify an asset in the `ChargeAssetTxPayment` signed extension. + type AssetId: Debug + Clone + Encode + DecodeAsType + EncodeAsType; + } + /// given some [`Config`], this return the other params needed for its `ExtrinsicParams`. + pub type OtherParamsFor = <::ExtrinsicParams as ExtrinsicParams< + T, + >>::OtherParams; + /// Block hashes must conform to a bunch of things to be used in Subxt. + pub trait BlockHash: Debug + Copy + Send + Sync + Decode + AsRef< + [u8], + > + Serialize + DeserializeOwned + Encode + PartialEq + Eq + std::hash::Hash {} + impl BlockHash for T + where + T: Debug + Copy + Send + Sync + Decode + AsRef<[u8]> + Serialize + + DeserializeOwned + Encode + PartialEq + Eq + std::hash::Hash, + {} + /// This represents the hasher used by a node to hash things like block headers + /// and extrinsics. + pub trait Hasher { + /// The type given back from the hash operation + type Output; + /// Hash some bytes to the given output type. + fn hash(s: &[u8]) -> Self::Output; + /// Hash some SCALE encodable type to the given output type. + fn hash_of(s: &S) -> Self::Output { + let out = s.encode(); + Self::hash(&out) + } + } + /// This represents the block header type used by a node. + pub trait Header: Sized + Encode + Decode { + /// The block number type for this header. + type Number: Into; + /// The hasher used to hash this header. + type Hasher: Hasher; + /// Return the block number of this header. + fn number(&self) -> Self::Number; + /// Hash this header. + fn hash(&self) -> ::Output { + Self::Hasher::hash_of(self) + } + } +} +pub mod constants { + //! Types associated with accessing constants. + mod constant_address { + use crate::{dynamic::DecodedValueThunk, metadata::DecodeWithMetadata}; + use derivative::Derivative; + use std::borrow::Cow; + /// This represents a constant address. Anything implementing this trait + /// can be used to fetch constants. + pub trait ConstantAddress { + /// The target type of the value that lives at this address. + type Target: DecodeWithMetadata; + /// The name of the pallet that the constant lives under. + fn pallet_name(&self) -> &str; + /// The name of the constant in a given pallet. + fn constant_name(&self) -> &str; + /// An optional hash which, if present, will be checked against + /// the node metadata to confirm that the return type matches what + /// we are expecting. + fn validation_hash(&self) -> Option<[u8; 32]> { + None + } + } + /// This represents the address of a constant. + #[derivative( + Clone(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + Ord(bound = ""), + PartialEq(bound = "") + )] + pub struct Address { + pallet_name: Cow<'static, str>, + constant_name: Cow<'static, str>, + constant_hash: Option<[u8; 32]>, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Address { + fn clone(&self) -> Self { + match *self { + Address { + pallet_name: ref __arg_0, + constant_name: ref __arg_1, + constant_hash: ref __arg_2, + _marker: ref __arg_3, + } => { + Address { + pallet_name: (*__arg_0).clone(), + constant_name: (*__arg_1).clone(), + constant_hash: (*__arg_2).clone(), + _marker: (*__arg_3).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Address { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Address { + pallet_name: ref __arg_0, + constant_name: ref __arg_1, + constant_hash: ref __arg_2, + _marker: ref __arg_3, + } => { + let mut __debug_trait_builder = __f.debug_struct("Address"); + let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); + let _ = __debug_trait_builder + .field("constant_name", &&(*__arg_1)); + let _ = __debug_trait_builder + .field("constant_hash", &&(*__arg_2)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_3)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for Address {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for Address { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + Address { + pallet_name: ref __self_0, + constant_name: ref __self_1, + constant_hash: ref __self_2, + _marker: ref __self_3, + } => { + match *other { + Address { + pallet_name: ref __other_0, + constant_name: ref __other_1, + constant_hash: ref __other_2, + _marker: ref __other_3, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + && &(*__self_3) == &(*__other_3) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::Ord for Address { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + Address { + pallet_name: ref __self_0, + constant_name: ref __self_1, + constant_hash: ref __self_2, + _marker: ref __self_3, + } => { + match *other { + Address { + pallet_name: ref __other_0, + constant_name: ref __other_1, + constant_hash: ref __other_2, + _marker: ref __other_3, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + impl PartialOrd for Address { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + /// The type of address typically used to return dynamic constant values. + pub type DynamicAddress = Address; + impl Address { + /// Create a new [`Address`] to use to look up a constant. + pub fn new( + pallet_name: impl Into, + constant_name: impl Into, + ) -> Self { + Self { + pallet_name: Cow::Owned(pallet_name.into()), + constant_name: Cow::Owned(constant_name.into()), + constant_hash: None, + _marker: std::marker::PhantomData, + } + } + /// Create a new [`Address`] that will be validated + /// against node metadata using the hash given. + #[doc(hidden)] + pub fn new_static( + pallet_name: &'static str, + constant_name: &'static str, + hash: [u8; 32], + ) -> Self { + Self { + pallet_name: Cow::Borrowed(pallet_name), + constant_name: Cow::Borrowed(constant_name), + constant_hash: Some(hash), + _marker: std::marker::PhantomData, + } + } + /// Do not validate this constant prior to accessing it. + pub fn unvalidated(self) -> Self { + Self { + pallet_name: self.pallet_name, + constant_name: self.constant_name, + constant_hash: None, + _marker: self._marker, + } + } + } + impl ConstantAddress for Address { + type Target = ReturnTy; + fn pallet_name(&self) -> &str { + &self.pallet_name + } + fn constant_name(&self) -> &str { + &self.constant_name + } + fn validation_hash(&self) -> Option<[u8; 32]> { + self.constant_hash + } + } + /// Construct a new dynamic constant lookup. + pub fn dynamic( + pallet_name: impl Into, + constant_name: impl Into, + ) -> DynamicAddress { + DynamicAddress::new(pallet_name, constant_name) + } + } + mod constants_client { + use super::ConstantAddress; + use crate::{ + client::OfflineClientT, error::{Error, MetadataError}, + metadata::DecodeWithMetadata, Config, + }; + use derivative::Derivative; + /// A client for accessing constants. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct ConstantsClient { + client: Client, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for ConstantsClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + ConstantsClient { client: ref __arg_0, _marker: ref __arg_1 } => { + ConstantsClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl ConstantsClient { + /// Create a new [`ConstantsClient`]. + pub fn new(client: Client) -> Self { + Self { + client, + _marker: std::marker::PhantomData, + } + } + } + impl> ConstantsClient { + /// Run the validation logic against some constant address you'd like to access. Returns `Ok(())` + /// if the address is valid (or if it's not possible to check since the address has no validation hash). + /// Return an error if the address was not valid or something went wrong trying to validate it (ie + /// the pallet or constant in question do not exist at all). + pub fn validate( + &self, + address: &Address, + ) -> Result<(), Error> { + if let Some(actual_hash) = address.validation_hash() { + let expected_hash = self + .client + .metadata() + .pallet_by_name_err(address.pallet_name())? + .constant_hash(address.constant_name()) + .ok_or_else(|| { + MetadataError::ConstantNameNotFound( + address.constant_name().to_owned(), + ) + })?; + if actual_hash != expected_hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + } + Ok(()) + } + /// Access the constant at the address given, returning the type defined by this address. + /// This is probably used with addresses given from static codegen, although you can manually + /// construct your own, too. + pub fn at( + &self, + address: &Address, + ) -> Result { + let metadata = self.client.metadata(); + self.validate(address)?; + let constant = metadata + .pallet_by_name_err(address.pallet_name())? + .constant_by_name(address.constant_name()) + .ok_or_else(|| { + MetadataError::ConstantNameNotFound( + address.constant_name().to_owned(), + ) + })?; + let value = ::decode_with_metadata( + &mut constant.value(), + constant.ty(), + &metadata, + )?; + Ok(value) + } + } + } + pub use constant_address::{dynamic, Address, ConstantAddress, DynamicAddress}; + pub use constants_client::ConstantsClient; +} +pub mod custom_values { + //! Types associated with accessing custom types + mod custom_value_address { + use derivative::Derivative; + use std::marker::PhantomData; + use crate::dynamic::DecodedValueThunk; + use crate::metadata::DecodeWithMetadata; + /// This represents the address of a custom value in in the metadata. + /// Anything, that implements the [CustomValueAddress] trait can be used, to fetch + /// custom values from the metadata. + /// The trait is implemented by [str] for dynamic loopup and [StaticAddress] for static queries. + pub trait CustomValueAddress { + /// The type of the custom value. + type Target: DecodeWithMetadata; + /// Should be set to `Yes` for Dynamic values and static values that have a valid type. + /// Should be `()` for custom values, that have an invalid type id. + type IsDecodable; + /// the name (key) by which the custom value can be accessed in the metadata. + fn name(&self) -> &str; + /// An optional hash which, if present, can be checked against node metadata. + fn validation_hash(&self) -> Option<[u8; 32]> { + None + } + } + impl CustomValueAddress for str { + type Target = DecodedValueThunk; + type IsDecodable = Yes; + fn name(&self) -> &str { + self + } + } + /// Used to signal whether a [`CustomValueAddress`] can be decoded. + pub struct Yes; + /// A static address to a custom value. + #[derivative( + Clone(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + Ord(bound = ""), + PartialEq(bound = "") + )] + pub struct StaticAddress { + name: &'static str, + hash: Option<[u8; 32]>, + phantom: PhantomData<(ReturnTy, IsDecodable)>, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone + for StaticAddress { + fn clone(&self) -> Self { + match *self { + StaticAddress { + name: ref __arg_0, + hash: ref __arg_1, + phantom: ref __arg_2, + } => { + StaticAddress { + name: (*__arg_0).clone(), + hash: (*__arg_1).clone(), + phantom: (*__arg_2).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug + for StaticAddress { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + StaticAddress { + name: ref __arg_0, + hash: ref __arg_1, + phantom: ref __arg_2, + } => { + let mut __debug_trait_builder = __f + .debug_struct("StaticAddress"); + let _ = __debug_trait_builder.field("name", &&(*__arg_0)); + let _ = __debug_trait_builder.field("hash", &&(*__arg_1)); + let _ = __debug_trait_builder.field("phantom", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq + for StaticAddress {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq + for StaticAddress { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + StaticAddress { + name: ref __self_0, + hash: ref __self_1, + phantom: ref __self_2, + } => { + match *other { + StaticAddress { + name: ref __other_0, + hash: ref __other_1, + phantom: ref __other_2, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::Ord + for StaticAddress { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + StaticAddress { + name: ref __self_0, + hash: ref __self_1, + phantom: ref __self_2, + } => { + match *other { + StaticAddress { + name: ref __other_0, + hash: ref __other_1, + phantom: ref __other_2, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + impl PartialOrd for StaticAddress { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + impl StaticAddress { + #[doc(hidden)] + /// Creates a new StaticAddress. + pub fn new_static( + name: &'static str, + hash: [u8; 32], + ) -> StaticAddress { + StaticAddress:: { + name, + hash: Some(hash), + phantom: PhantomData, + } + } + /// Do not validate this custom value prior to accessing it. + pub fn unvalidated(self) -> Self { + Self { + name: self.name, + hash: None, + phantom: self.phantom, + } + } + } + impl CustomValueAddress for StaticAddress { + type Target = R; + type IsDecodable = Y; + fn name(&self) -> &str { + self.name + } + fn validation_hash(&self) -> Option<[u8; 32]> { + self.hash + } + } + } + mod custom_values_client { + use crate::client::OfflineClientT; + use crate::custom_values::custom_value_address::{CustomValueAddress, Yes}; + use crate::error::MetadataError; + use crate::metadata::DecodeWithMetadata; + use crate::{Config, Error}; + use derivative::Derivative; + /// A client for accessing custom values stored in the metadata. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct CustomValuesClient { + client: Client, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for CustomValuesClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + CustomValuesClient { client: ref __arg_0, _marker: ref __arg_1 } => { + CustomValuesClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl CustomValuesClient { + /// Create a new [`CustomValuesClient`]. + pub fn new(client: Client) -> Self { + Self { + client, + _marker: std::marker::PhantomData, + } + } + } + impl> CustomValuesClient { + /// Access a custom value by the address it is registered under. This can be just a [str] to get back a dynamic value, + /// or a static address from the generated static interface to get a value of a static type returned. + pub fn at + ?Sized>( + &self, + address: &Address, + ) -> Result { + self.validate(address)?; + let metadata = self.client.metadata(); + let custom = metadata.custom(); + let custom_value = custom + .get(address.name()) + .ok_or_else(|| MetadataError::CustomValueNameNotFound( + address.name().to_string(), + ))?; + let value = ::decode_with_metadata( + &mut custom_value.bytes(), + custom_value.type_id(), + &metadata, + )?; + Ok(value) + } + /// Access the bytes of a custom value by the address it is registered under. + pub fn bytes_at( + &self, + address: &Address, + ) -> Result, Error> { + self.validate(address)?; + let metadata = self.client.metadata(); + let custom = metadata.custom(); + let custom_value = custom + .get(address.name()) + .ok_or_else(|| MetadataError::CustomValueNameNotFound( + address.name().to_string(), + ))?; + Ok(custom_value.bytes().to_vec()) + } + /// Run the validation logic against some custom value address you'd like to access. Returns `Ok(())` + /// if the address is valid (or if it's not possible to check since the address has no validation hash). + /// Returns an error if the address was not valid (wrong name, type or raw bytes) + pub fn validate( + &self, + address: &Address, + ) -> Result<(), Error> { + let metadata = self.client.metadata(); + if let Some(actual_hash) = address.validation_hash() { + let custom = metadata.custom(); + let custom_value = custom + .get(address.name()) + .ok_or_else(|| MetadataError::CustomValueNameNotFound( + address.name().into(), + ))?; + let expected_hash = custom_value.hash(); + if actual_hash != expected_hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + } + if metadata.custom().get(address.name()).is_none() { + return Err(MetadataError::IncompatibleCodegen.into()); + } + Ok(()) + } + } + } + pub use custom_value_address::{CustomValueAddress, StaticAddress, Yes}; + pub use custom_values_client::CustomValuesClient; +} +pub mod dynamic { + //! This module provides the entry points to create dynamic + //! transactions, storage and constant lookups. + use crate::{error::Error, metadata::{DecodeWithMetadata, Metadata}}; + use scale_decode::DecodeAsType; + pub use scale_value::{At, Value}; + /// A [`scale_value::Value`] type endowed with contextual information + /// regarding what type was used to decode each part of it. This implements + /// [`crate::metadata::DecodeWithMetadata`], and is used as a return type + /// for dynamic requests. + pub type DecodedValue = scale_value::Value; + pub use crate::tx::dynamic as tx; + pub use crate::constants::dynamic as constant; + pub use crate::storage::dynamic as storage; + pub use crate::runtime_api::dynamic as runtime_api_call; + /// This is the result of making a dynamic request to a node. From this, + /// we can return the raw SCALE bytes that we were handed back, or we can + /// complete the decoding of the bytes into a [`DecodedValue`] type. + pub struct DecodedValueThunk { + type_id: u32, + metadata: Metadata, + scale_bytes: Vec, + } + impl DecodeWithMetadata for DecodedValueThunk { + fn decode_with_metadata( + bytes: &mut &[u8], + type_id: u32, + metadata: &Metadata, + ) -> Result { + let mut v = Vec::with_capacity(bytes.len()); + v.extend_from_slice(bytes); + *bytes = &[]; + Ok(DecodedValueThunk { + type_id, + metadata: metadata.clone(), + scale_bytes: v, + }) + } + } + impl DecodedValueThunk { + /// Return the SCALE encoded bytes handed back from the node. + pub fn into_encoded(self) -> Vec { + self.scale_bytes + } + /// Return the SCALE encoded bytes handed back from the node without taking ownership of them. + pub fn encoded(&self) -> &[u8] { + &self.scale_bytes + } + /// Decode the SCALE encoded storage entry into a dynamic [`DecodedValue`] type. + pub fn to_value(&self) -> Result { + let val = DecodedValue::decode_as_type( + &mut &*self.scale_bytes, + self.type_id, + self.metadata.types(), + )?; + Ok(val) + } + /// decode the `DecodedValueThunk` into a concrete type. + pub fn as_type(&self) -> Result { + T::decode_as_type( + &mut &self.scale_bytes[..], + self.type_id, + self.metadata.types(), + ) + } + } +} +pub mod error { + //! Types representing the errors that can be returned. + mod dispatch_error { + //! A representation of the dispatch error; an error returned when + //! something fails in trying to submit/execute a transaction. + use crate::metadata::{DecodeWithMetadata, Metadata}; + use core::fmt::Debug; + use scale_decode::{visitor::DecodeAsTypeResult, DecodeAsType}; + use std::borrow::Cow; + use super::{Error, MetadataError}; + /// An error dispatching a transaction. + #[non_exhaustive] + pub enum DispatchError { + /// Some error occurred. + #[error("Some unknown error occurred.")] + Other, + /// Failed to lookup some data. + #[error("Failed to lookup some data.")] + CannotLookup, + /// A bad origin. + #[error("Bad origin.")] + BadOrigin, + /// A custom error in a module. + #[error("Pallet error: {0}")] + Module(ModuleError), + /// At least one consumer is remaining so the account cannot be destroyed. + #[error( + "At least one consumer is remaining so the account cannot be destroyed." + )] + ConsumerRemaining, + /// There are no providers so the account cannot be created. + #[error("There are no providers so the account cannot be created.")] + NoProviders, + /// There are too many consumers so the account cannot be created. + #[error("There are too many consumers so the account cannot be created.")] + TooManyConsumers, + /// An error to do with tokens. + #[error("Token error: {0}")] + Token(TokenError), + /// An arithmetic error. + #[error("Arithmetic error: {0}")] + Arithmetic(ArithmeticError), + /// The number of transactional layers has been reached, or we are not in a transactional layer. + #[error("Transactional error: {0}")] + Transactional(TransactionalError), + /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. + #[error( + "Resources exhausted, e.g. attempt to read/write data which is too large to manipulate." + )] + Exhausted, + /// The state is corrupt; this is generally not going to fix itself. + #[error("The state is corrupt; this is generally not going to fix itself.")] + Corruption, + /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. + #[error( + "Some resource (e.g. a preimage) is unavailable right now. This might fix itself later." + )] + Unavailable, + } + #[automatically_derived] + impl ::core::fmt::Debug for DispatchError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + DispatchError::Other => ::core::fmt::Formatter::write_str(f, "Other"), + DispatchError::CannotLookup => { + ::core::fmt::Formatter::write_str(f, "CannotLookup") + } + DispatchError::BadOrigin => { + ::core::fmt::Formatter::write_str(f, "BadOrigin") + } + DispatchError::Module(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Module", + &__self_0, + ) + } + DispatchError::ConsumerRemaining => { + ::core::fmt::Formatter::write_str(f, "ConsumerRemaining") + } + DispatchError::NoProviders => { + ::core::fmt::Formatter::write_str(f, "NoProviders") + } + DispatchError::TooManyConsumers => { + ::core::fmt::Formatter::write_str(f, "TooManyConsumers") + } + DispatchError::Token(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Token", + &__self_0, + ) + } + DispatchError::Arithmetic(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Arithmetic", + &__self_0, + ) + } + DispatchError::Transactional(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Transactional", + &__self_0, + ) + } + DispatchError::Exhausted => { + ::core::fmt::Formatter::write_str(f, "Exhausted") + } + DispatchError::Corruption => { + ::core::fmt::Formatter::write_str(f, "Corruption") + } + DispatchError::Unavailable => { + ::core::fmt::Formatter::write_str(f, "Unavailable") + } + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for DispatchError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for DispatchError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + DispatchError::Other {} => { + __formatter.write_str("Some unknown error occurred.") + } + DispatchError::CannotLookup {} => { + __formatter.write_str("Failed to lookup some data.") + } + DispatchError::BadOrigin {} => __formatter.write_str("Bad origin."), + DispatchError::Module(_0) => { + __formatter + .write_fmt( + format_args!("Pallet error: {0}", _0.as_display()), + ) + } + DispatchError::ConsumerRemaining {} => { + __formatter + .write_str( + "At least one consumer is remaining so the account cannot be destroyed.", + ) + } + DispatchError::NoProviders {} => { + __formatter + .write_str( + "There are no providers so the account cannot be created.", + ) + } + DispatchError::TooManyConsumers {} => { + __formatter + .write_str( + "There are too many consumers so the account cannot be created.", + ) + } + DispatchError::Token(_0) => { + __formatter + .write_fmt(format_args!("Token error: {0}", _0.as_display())) + } + DispatchError::Arithmetic(_0) => { + __formatter + .write_fmt( + format_args!("Arithmetic error: {0}", _0.as_display()), + ) + } + DispatchError::Transactional(_0) => { + __formatter + .write_fmt( + format_args!("Transactional error: {0}", _0.as_display()), + ) + } + DispatchError::Exhausted {} => { + __formatter + .write_str( + "Resources exhausted, e.g. attempt to read/write data which is too large to manipulate.", + ) + } + DispatchError::Corruption {} => { + __formatter + .write_str( + "The state is corrupt; this is generally not going to fix itself.", + ) + } + DispatchError::Unavailable {} => { + __formatter + .write_str( + "Some resource (e.g. a preimage) is unavailable right now. This might fix itself later.", + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DispatchError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DispatchError { + #[inline] + fn eq(&self, other: &DispatchError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + DispatchError::Module(__self_0), + DispatchError::Module(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + DispatchError::Token(__self_0), + DispatchError::Token(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + DispatchError::Arithmetic(__self_0), + DispatchError::Arithmetic(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + DispatchError::Transactional(__self_0), + DispatchError::Transactional(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DispatchError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + /// An error relating to tokens when dispatching a transaction. + #[non_exhaustive] + pub enum TokenError { + /// Funds are unavailable. + #[error("Funds are unavailable.")] + FundsUnavailable, + /// Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved. + #[error( + "Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved." + )] + OnlyProvider, + /// Account cannot exist with the funds that would be given. + #[error("Account cannot exist with the funds that would be given.")] + BelowMinimum, + /// Account cannot be created. + #[error("Account cannot be created.")] + CannotCreate, + /// The asset in question is unknown. + #[error("The asset in question is unknown.")] + UnknownAsset, + /// Funds exist but are frozen. + #[error("Funds exist but are frozen.")] + Frozen, + /// Operation is not supported by the asset. + #[error("Operation is not supported by the asset.")] + Unsupported, + /// Account cannot be created for a held balance. + #[error("Account cannot be created for a held balance.")] + CannotCreateHold, + /// Withdrawal would cause unwanted loss of account. + #[error("Withdrawal would cause unwanted loss of account.")] + NotExpendable, + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for TokenError { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = TokenError; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "FundsUnavailable" { + return Ok(TokenError::FundsUnavailable); + } + if value.name() == "OnlyProvider" { + return Ok(TokenError::OnlyProvider); + } + if value.name() == "BelowMinimum" { + return Ok(TokenError::BelowMinimum); + } + if value.name() == "CannotCreate" { + return Ok(TokenError::CannotCreate); + } + if value.name() == "UnknownAsset" { + return Ok(TokenError::UnknownAsset); + } + if value.name() == "Frozen" { + return Ok(TokenError::Frozen); + } + if value.name() == "Unsupported" { + return Ok(TokenError::Unsupported); + } + if value.name() == "CannotCreateHold" { + return Ok(TokenError::CannotCreateHold); + } + if value.name() == "NotExpendable" { + return Ok(TokenError::NotExpendable); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + "FundsUnavailable", + "OnlyProvider", + "BelowMinimum", + "CannotCreate", + "UnknownAsset", + "Frozen", + "Unsupported", + "CannotCreateHold", + "NotExpendable", + ]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for TokenError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + TokenError::FundsUnavailable => "FundsUnavailable", + TokenError::OnlyProvider => "OnlyProvider", + TokenError::BelowMinimum => "BelowMinimum", + TokenError::CannotCreate => "CannotCreate", + TokenError::UnknownAsset => "UnknownAsset", + TokenError::Frozen => "Frozen", + TokenError::Unsupported => "Unsupported", + TokenError::CannotCreateHold => "CannotCreateHold", + TokenError::NotExpendable => "NotExpendable", + }, + ) + } + } + #[allow(unused_qualifications)] + impl std::error::Error for TokenError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for TokenError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + TokenError::FundsUnavailable {} => { + __formatter.write_str("Funds are unavailable.") + } + TokenError::OnlyProvider {} => { + __formatter + .write_str( + "Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved.", + ) + } + TokenError::BelowMinimum {} => { + __formatter + .write_str( + "Account cannot exist with the funds that would be given.", + ) + } + TokenError::CannotCreate {} => { + __formatter.write_str("Account cannot be created.") + } + TokenError::UnknownAsset {} => { + __formatter.write_str("The asset in question is unknown.") + } + TokenError::Frozen {} => { + __formatter.write_str("Funds exist but are frozen.") + } + TokenError::Unsupported {} => { + __formatter.write_str("Operation is not supported by the asset.") + } + TokenError::CannotCreateHold {} => { + __formatter + .write_str("Account cannot be created for a held balance.") + } + TokenError::NotExpendable {} => { + __formatter + .write_str( + "Withdrawal would cause unwanted loss of account.", + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TokenError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TokenError { + #[inline] + fn eq(&self, other: &TokenError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TokenError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + /// An error relating to arithmetic when dispatching a transaction. + #[non_exhaustive] + pub enum ArithmeticError { + /// Underflow. + #[error("Underflow.")] + Underflow, + /// Overflow. + #[error("Overflow.")] + Overflow, + /// Division by zero. + #[error("Division by zero.")] + DivisionByZero, + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for ArithmeticError { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = ArithmeticError; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "Underflow" { + return Ok(ArithmeticError::Underflow); + } + if value.name() == "Overflow" { + return Ok(ArithmeticError::Overflow); + } + if value.name() == "DivisionByZero" { + return Ok(ArithmeticError::DivisionByZero); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + "Underflow", + "Overflow", + "DivisionByZero", + ]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for ArithmeticError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + ArithmeticError::Underflow => "Underflow", + ArithmeticError::Overflow => "Overflow", + ArithmeticError::DivisionByZero => "DivisionByZero", + }, + ) + } + } + #[allow(unused_qualifications)] + impl std::error::Error for ArithmeticError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for ArithmeticError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + ArithmeticError::Underflow {} => __formatter.write_str("Underflow."), + ArithmeticError::Overflow {} => __formatter.write_str("Overflow."), + ArithmeticError::DivisionByZero {} => { + __formatter.write_str("Division by zero.") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ArithmeticError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ArithmeticError { + #[inline] + fn eq(&self, other: &ArithmeticError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ArithmeticError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + /// An error relating to thr transactional layers when dispatching a transaction. + #[non_exhaustive] + pub enum TransactionalError { + /// Too many transactional layers have been spawned. + #[error("Too many transactional layers have been spawned.")] + LimitReached, + /// A transactional layer was expected, but does not exist. + #[error("A transactional layer was expected, but does not exist.")] + NoLayer, + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for TransactionalError { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = TransactionalError; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "LimitReached" { + return Ok(TransactionalError::LimitReached); + } + if value.name() == "NoLayer" { + return Ok(TransactionalError::NoLayer); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new(["LimitReached", "NoLayer"]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for TransactionalError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + TransactionalError::LimitReached => "LimitReached", + TransactionalError::NoLayer => "NoLayer", + }, + ) + } + } + #[allow(unused_qualifications)] + impl std::error::Error for TransactionalError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for TransactionalError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + TransactionalError::LimitReached {} => { + __formatter + .write_str( + "Too many transactional layers have been spawned.", + ) + } + TransactionalError::NoLayer {} => { + __formatter + .write_str( + "A transactional layer was expected, but does not exist.", + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionalError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionalError { + #[inline] + fn eq(&self, other: &TransactionalError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TransactionalError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + /// Details about a module error that has occurred. + #[non_exhaustive] + pub struct ModuleError { + metadata: Metadata, + /// Bytes representation: + /// - `bytes[0]`: pallet index + /// - `bytes[1]`: error index + /// - `bytes[2..]`: 3 bytes specific for the module error + bytes: [u8; 5], + } + #[automatically_derived] + impl ::core::clone::Clone for ModuleError { + #[inline] + fn clone(&self) -> ModuleError { + ModuleError { + metadata: ::core::clone::Clone::clone(&self.metadata), + bytes: ::core::clone::Clone::clone(&self.bytes), + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for ModuleError {} + impl PartialEq for ModuleError { + fn eq(&self, other: &Self) -> bool { + self.bytes == other.bytes + } + } + impl Eq for ModuleError {} + /// Custom `Debug` implementation, ignores the very large `metadata` field, using it instead (as + /// intended) to resolve the actual pallet and error names. This is much more useful for debugging. + impl Debug for ModuleError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let details = self.details_string(); + f.write_fmt(format_args!("ModuleError(<{0}>)", details)) + } + } + impl std::fmt::Display for ModuleError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let details = self.details_string(); + f.write_fmt(format_args!("{0}", details)) + } + } + impl ModuleError { + /// Return more details about this error. + pub fn details(&self) -> Result { + let pallet = self.metadata.pallet_by_index_err(self.pallet_index())?; + let variant = pallet + .error_variant_by_index(self.error_index()) + .ok_or_else(|| MetadataError::VariantIndexNotFound( + self.error_index(), + ))?; + Ok(ModuleErrorDetails { + pallet, + variant, + }) + } + /// Return a formatted string of the resolved error details for debugging/display purposes. + pub fn details_string(&self) -> String { + match self.details() { + Ok(details) => { + let res = ::alloc::fmt::format( + format_args!( + "{0}::{1}", details.pallet.name(), details.variant.name + ), + ); + res + } + Err(_) => { + let res = ::alloc::fmt::format( + format_args!( + "Unknown pallet error \'{0:?}\' (pallet and error details cannot be retrieved)", + self.bytes + ), + ); + res + } + } + } + /// Return the underlying module error data that was decoded. + pub fn bytes(&self) -> [u8; 5] { + self.bytes + } + /// Obtain the pallet index from the underlying byte data. + pub fn pallet_index(&self) -> u8 { + self.bytes[0] + } + /// Obtain the error index from the underlying byte data. + pub fn error_index(&self) -> u8 { + self.bytes[1] + } + /// Attempts to decode the ModuleError into the top outer Error enum. + pub fn as_root_error(&self) -> Result { + let decoded = E::decode_as_type( + &mut &self.bytes[..], + self.metadata.outer_enums().error_enum_ty(), + self.metadata.types(), + )?; + Ok(decoded) + } + } + /// Details about the module error. + pub struct ModuleErrorDetails<'a> { + /// The pallet that the error is in + pub pallet: crate::metadata::types::PalletMetadata<'a>, + /// The variant representing the error + pub variant: &'a scale_info::Variant, + } + impl DispatchError { + /// Attempt to decode a runtime [`DispatchError`]. + #[doc(hidden)] + pub fn decode_from<'a>( + bytes: impl Into>, + metadata: Metadata, + ) -> Result { + let bytes = bytes.into(); + let dispatch_error_ty_id = metadata + .dispatch_error_ty() + .ok_or(MetadataError::DispatchErrorNotFound)?; + enum DecodedDispatchError { + Other, + CannotLookup, + BadOrigin, + Module(DecodedModuleErrorBytes), + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(TokenError), + Arithmetic(ArithmeticError), + Transactional(TransactionalError), + Exhausted, + Corruption, + Unavailable, + } + const _: () = { + struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for DecodedDispatchError { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = DecodedDispatchError; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant< + 'scale, + 'info, + >, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "Other" { + return Ok(DecodedDispatchError::Other); + } + if value.name() == "CannotLookup" { + return Ok(DecodedDispatchError::CannotLookup); + } + if value.name() == "BadOrigin" { + return Ok(DecodedDispatchError::BadOrigin); + } + if value.name() == "Module" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + DecodedDispatchError::Module({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "ConsumerRemaining" { + return Ok(DecodedDispatchError::ConsumerRemaining); + } + if value.name() == "NoProviders" { + return Ok(DecodedDispatchError::NoProviders); + } + if value.name() == "TooManyConsumers" { + return Ok(DecodedDispatchError::TooManyConsumers); + } + if value.name() == "Token" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + DecodedDispatchError::Token({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Arithmetic" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + DecodedDispatchError::Arithmetic({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Transactional" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + DecodedDispatchError::Transactional({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Exhausted" { + return Ok(DecodedDispatchError::Exhausted); + } + if value.name() == "Corruption" { + return Ok(DecodedDispatchError::Corruption); + } + if value.name() == "Unavailable" { + return Ok(DecodedDispatchError::Unavailable); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + "Other", + "CannotLookup", + "BadOrigin", + "Module", + "ConsumerRemaining", + "NoProviders", + "TooManyConsumers", + "Token", + "Arithmetic", + "Transactional", + "Exhausted", + "Corruption", + "Unavailable", + ]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite< + 'scale, + 'info, + >, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple< + 'scale, + 'info, + >, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + struct DecodedModuleErrorBytes(Vec); + struct DecodedModuleErrorBytesVisitor; + impl scale_decode::Visitor for DecodedModuleErrorBytesVisitor { + type Error = scale_decode::Error; + type Value<'scale, 'info> = DecodedModuleErrorBytes; + fn unchecked_decode_as_type<'scale, 'info>( + self, + input: &mut &'scale [u8], + _type_id: scale_decode::visitor::TypeId, + _types: &'info scale_info::PortableRegistry, + ) -> DecodeAsTypeResult< + Self, + Result, Self::Error>, + > { + DecodeAsTypeResult::Decoded( + Ok(DecodedModuleErrorBytes(input.to_vec())), + ) + } + } + impl scale_decode::IntoVisitor for DecodedModuleErrorBytes { + type Visitor = DecodedModuleErrorBytesVisitor; + fn into_visitor() -> Self::Visitor { + DecodedModuleErrorBytesVisitor + } + } + let decoded_dispatch_err = DecodedDispatchError::decode_with_metadata( + &mut &*bytes, + dispatch_error_ty_id, + &metadata, + )?; + let dispatch_error = match decoded_dispatch_err { + DecodedDispatchError::Other => DispatchError::Other, + DecodedDispatchError::CannotLookup => DispatchError::CannotLookup, + DecodedDispatchError::BadOrigin => DispatchError::BadOrigin, + DecodedDispatchError::ConsumerRemaining => { + DispatchError::ConsumerRemaining + } + DecodedDispatchError::NoProviders => DispatchError::NoProviders, + DecodedDispatchError::TooManyConsumers => { + DispatchError::TooManyConsumers + } + DecodedDispatchError::Token(val) => DispatchError::Token(val), + DecodedDispatchError::Arithmetic(val) => { + DispatchError::Arithmetic(val) + } + DecodedDispatchError::Transactional(val) => { + DispatchError::Transactional(val) + } + DecodedDispatchError::Exhausted => DispatchError::Exhausted, + DecodedDispatchError::Corruption => DispatchError::Corruption, + DecodedDispatchError::Unavailable => DispatchError::Unavailable, + DecodedDispatchError::Module(module_bytes) => { + let module_bytes = module_bytes.0; + let bytes = if module_bytes.len() == 2 { + [module_bytes[0], module_bytes[1], 0, 0, 0] + } else if module_bytes.len() == 5 { + [ + module_bytes[0], + module_bytes[1], + module_bytes[2], + module_bytes[3], + module_bytes[4], + ] + } else { + { + use ::tracing::__macro_support::Callsite as _; + static __CALLSITE: ::tracing::callsite::DefaultCallsite = { + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "event subxt/src/error/dispatch_error.rs:318", + "subxt::error::dispatch_error", + ::tracing::Level::WARN, + ::core::option::Option::Some( + "subxt/src/error/dispatch_error.rs", + ), + ::core::option::Option::Some(318u32), + ::core::option::Option::Some( + "subxt::error::dispatch_error", + ), + ::tracing_core::field::FieldSet::new( + &["message"], + ::tracing_core::callsite::Identifier(&__CALLSITE), + ), + ::tracing::metadata::Kind::EVENT, + ) + }; + ::tracing::callsite::DefaultCallsite::new(&META) + }; + let enabled = ::tracing::Level::WARN + <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::WARN + <= ::tracing::level_filters::LevelFilter::current() + && { + let interest = __CALLSITE.interest(); + !interest.is_never() + && ::tracing::__macro_support::__is_enabled( + __CALLSITE.metadata(), + interest, + ) + }; + if enabled { + (|value_set: ::tracing::field::ValueSet| { + let meta = __CALLSITE.metadata(); + ::tracing::Event::dispatch(meta, &value_set); + })({ + #[allow(unused_imports)] + use ::tracing::field::{debug, display, Value}; + let mut iter = __CALLSITE.metadata().fields().iter(); + __CALLSITE + .metadata() + .fields() + .value_set( + &[ + ( + &::core::iter::Iterator::next(&mut iter) + .expect("FieldSet corrupted (this is a bug)"), + ::core::option::Option::Some( + &format_args!( + "Can\'t decode error sp_runtime::DispatchError: bytes do not match known shapes" + ) as &dyn Value, + ), + ), + ], + ) + }); + } else { + } + }; + return Err(super::Error::Unknown(bytes.to_vec())); + }; + DispatchError::Module(ModuleError { metadata, bytes }) + } + }; + Ok(dispatch_error) + } + } + } + pub use dispatch_error::{ + ArithmeticError, DispatchError, ModuleError, TokenError, TransactionalError, + }; + use subxt_metadata::StorageHasher; + pub use crate::config::ExtrinsicParamsError; + pub use crate::metadata::Metadata; + pub use scale_decode::Error as DecodeError; + pub use scale_encode::Error as EncodeError; + pub use subxt_metadata::TryFromError as MetadataTryFromError; + /// The underlying error enum, generic over the type held by the `Runtime` + /// variant. Prefer to use the [`Error`] and [`Error`] aliases over + /// using this type directly. + #[non_exhaustive] + pub enum Error { + /// Io error. + #[error("Io error: {0}")] + Io(#[from] std::io::Error), + /// Codec error. + #[error("Scale codec error: {0}")] + Codec(#[from] codec::Error), + /// Rpc error. + #[error("Rpc error: {0}")] + Rpc(#[from] RpcError), + /// Serde serialization error + #[error("Serde json error: {0}")] + Serialization(#[from] serde_json::error::Error), + /// Error working with metadata. + #[error("Metadata error: {0}")] + Metadata(#[from] MetadataError), + /// Error decoding metadata. + #[error("Metadata Decoding error: {0}")] + MetadataDecoding(#[from] MetadataTryFromError), + /// Runtime error. + #[error("Runtime error: {0}")] + Runtime(#[from] DispatchError), + /// Error decoding to a [`crate::dynamic::Value`]. + #[error("Error decoding into dynamic value: {0}")] + Decode(#[from] DecodeError), + /// Error encoding from a [`crate::dynamic::Value`]. + #[error("Error encoding from dynamic value: {0}")] + Encode(#[from] EncodeError), + /// Transaction progress error. + #[error("Transaction error: {0}")] + Transaction(#[from] TransactionError), + /// Error constructing the appropriate extrinsic params. + #[error("Extrinsic params error: {0}")] + ExtrinsicParams(#[from] ExtrinsicParamsError), + /// Block related error. + #[error("Block error: {0}")] + Block(#[from] BlockError), + /// An error encoding a storage address. + #[error("Error encoding storage address: {0}")] + StorageAddress(#[from] StorageAddressError), + /// The bytes representing an error that we were unable to decode. + #[error("An error occurred but it could not be decoded: {0:?}")] + Unknown(Vec), + /// Other error. + #[error("Other error: {0}")] + Other(String), + } + #[automatically_derived] + impl ::core::fmt::Debug for Error { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + Error::Io(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Io", &__self_0) + } + Error::Codec(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Codec", + &__self_0, + ) + } + Error::Rpc(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Rpc", + &__self_0, + ) + } + Error::Serialization(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Serialization", + &__self_0, + ) + } + Error::Metadata(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Metadata", + &__self_0, + ) + } + Error::MetadataDecoding(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "MetadataDecoding", + &__self_0, + ) + } + Error::Runtime(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Runtime", + &__self_0, + ) + } + Error::Decode(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Decode", + &__self_0, + ) + } + Error::Encode(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Encode", + &__self_0, + ) + } + Error::Transaction(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Transaction", + &__self_0, + ) + } + Error::ExtrinsicParams(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ExtrinsicParams", + &__self_0, + ) + } + Error::Block(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Block", + &__self_0, + ) + } + Error::StorageAddress(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "StorageAddress", + &__self_0, + ) + } + Error::Unknown(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Unknown", + &__self_0, + ) + } + Error::Other(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Other", + &__self_0, + ) + } + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for Error { + fn source(&self) -> ::core::option::Option<&(dyn std::error::Error + 'static)> { + use thiserror::__private::AsDynError as _; + #[allow(deprecated)] + match self { + Error::Io { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Codec { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Rpc { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Serialization { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Metadata { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::MetadataDecoding { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Runtime { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Decode { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Encode { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Transaction { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::ExtrinsicParams { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Block { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::StorageAddress { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Unknown { .. } => ::core::option::Option::None, + Error::Other { .. } => ::core::option::Option::None, + } + } + } + #[allow(unused_qualifications)] + impl ::core::fmt::Display for Error { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + Error::Io(_0) => { + __formatter.write_fmt(format_args!("Io error: {0}", _0.as_display())) + } + Error::Codec(_0) => { + __formatter + .write_fmt( + format_args!("Scale codec error: {0}", _0.as_display()), + ) + } + Error::Rpc(_0) => { + __formatter + .write_fmt(format_args!("Rpc error: {0}", _0.as_display())) + } + Error::Serialization(_0) => { + __formatter + .write_fmt( + format_args!("Serde json error: {0}", _0.as_display()), + ) + } + Error::Metadata(_0) => { + __formatter + .write_fmt(format_args!("Metadata error: {0}", _0.as_display())) + } + Error::MetadataDecoding(_0) => { + __formatter + .write_fmt( + format_args!("Metadata Decoding error: {0}", _0.as_display()), + ) + } + Error::Runtime(_0) => { + __formatter + .write_fmt(format_args!("Runtime error: {0}", _0.as_display())) + } + Error::Decode(_0) => { + __formatter + .write_fmt( + format_args!( + "Error decoding into dynamic value: {0}", _0.as_display() + ), + ) + } + Error::Encode(_0) => { + __formatter + .write_fmt( + format_args!( + "Error encoding from dynamic value: {0}", _0.as_display() + ), + ) + } + Error::Transaction(_0) => { + __formatter + .write_fmt( + format_args!("Transaction error: {0}", _0.as_display()), + ) + } + Error::ExtrinsicParams(_0) => { + __formatter + .write_fmt( + format_args!("Extrinsic params error: {0}", _0.as_display()), + ) + } + Error::Block(_0) => { + __formatter + .write_fmt(format_args!("Block error: {0}", _0.as_display())) + } + Error::StorageAddress(_0) => { + __formatter + .write_fmt( + format_args!( + "Error encoding storage address: {0}", _0.as_display() + ), + ) + } + Error::Unknown(_0) => { + __formatter + .write_fmt( + format_args!( + "An error occurred but it could not be decoded: {0:?}", _0 + ), + ) + } + Error::Other(_0) => { + __formatter + .write_fmt(format_args!("Other error: {0}", _0.as_display())) + } + } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: std::io::Error) -> Self { + Error::Io { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: codec::Error) -> Self { + Error::Codec { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: RpcError) -> Self { + Error::Rpc { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: serde_json::error::Error) -> Self { + Error::Serialization { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: MetadataError) -> Self { + Error::Metadata { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: MetadataTryFromError) -> Self { + Error::MetadataDecoding { + 0: source, + } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: DispatchError) -> Self { + Error::Runtime { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: DecodeError) -> Self { + Error::Decode { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: EncodeError) -> Self { + Error::Encode { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: TransactionError) -> Self { + Error::Transaction { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: ExtrinsicParamsError) -> Self { + Error::ExtrinsicParams { + 0: source, + } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: BlockError) -> Self { + Error::Block { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: StorageAddressError) -> Self { + Error::StorageAddress { 0: source } + } + } + impl<'a> From<&'a str> for Error { + fn from(error: &'a str) -> Self { + Error::Other(error.into()) + } + } + impl From for Error { + fn from(error: String) -> Self { + Error::Other(error) + } + } + impl From for Error { + fn from(value: std::convert::Infallible) -> Self { + match value {} + } + } + impl Error { + /// Checks whether the error was caused by a RPC re-connection. + pub fn is_disconnected_will_reconnect(&self) -> bool { + match self { + Error::Rpc(RpcError::DisconnectedWillReconnect(_)) => true, + _ => false, + } + } + } + /// An RPC error. Since we are generic over the RPC client that is used, + /// the error is boxed and could be casted. + #[non_exhaustive] + pub enum RpcError { + /// Error related to the RPC client. + #[error("RPC error: {0}")] + ClientError(Box), + /// This error signals that the request was rejected for some reason. + /// The specific reason is provided. + #[error("RPC error: request rejected: {0}")] + RequestRejected(String), + /// The RPC subscription dropped. + #[error("RPC error: subscription dropped.")] + SubscriptionDropped, + /// The requested URL is insecure. + #[error("RPC error: insecure URL: {0}")] + InsecureUrl(String), + /// The connection was lost and automatically reconnected. + #[error( + "RPC error: the connection was lost `{0}`; reconnect automatically initiated" + )] + DisconnectedWillReconnect(String), + } + #[automatically_derived] + impl ::core::fmt::Debug for RpcError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + RpcError::ClientError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ClientError", + &__self_0, + ) + } + RpcError::RequestRejected(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "RequestRejected", + &__self_0, + ) + } + RpcError::SubscriptionDropped => { + ::core::fmt::Formatter::write_str(f, "SubscriptionDropped") + } + RpcError::InsecureUrl(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InsecureUrl", + &__self_0, + ) + } + RpcError::DisconnectedWillReconnect(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "DisconnectedWillReconnect", + &__self_0, + ) + } + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for RpcError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for RpcError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + RpcError::ClientError(_0) => { + __formatter + .write_fmt(format_args!("RPC error: {0}", _0.as_display())) + } + RpcError::RequestRejected(_0) => { + __formatter + .write_fmt( + format_args!( + "RPC error: request rejected: {0}", _0.as_display() + ), + ) + } + RpcError::SubscriptionDropped {} => { + __formatter.write_str("RPC error: subscription dropped.") + } + RpcError::InsecureUrl(_0) => { + __formatter + .write_fmt( + format_args!("RPC error: insecure URL: {0}", _0.as_display()), + ) + } + RpcError::DisconnectedWillReconnect(_0) => { + __formatter + .write_fmt( + format_args!( + "RPC error: the connection was lost `{0}`; reconnect automatically initiated", + _0.as_display() + ), + ) + } + } + } + } + impl RpcError { + /// Create a `RequestRejected` error from anything that can be turned into a string. + pub fn request_rejected>(s: S) -> RpcError { + RpcError::RequestRejected(s.into()) + } + } + /// Block error + #[non_exhaustive] + pub enum BlockError { + /// An error containing the hash of the block that was not found. + #[error( + "Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)" + )] + NotFound(String), + /// Extrinsic type ID cannot be resolved with the provided metadata. + #[error( + "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata" + )] + MissingType, + /// Unsupported signature. + #[error("Unsupported extrinsic version, only version 4 is supported currently")] + /// The extrinsic has an unsupported version. + UnsupportedVersion(u8), + /// Decoding error. + #[error("Cannot decode extrinsic: {0}")] + DecodingError(codec::Error), + } + #[automatically_derived] + impl ::core::clone::Clone for BlockError { + #[inline] + fn clone(&self) -> BlockError { + match self { + BlockError::NotFound(__self_0) => { + BlockError::NotFound(::core::clone::Clone::clone(__self_0)) + } + BlockError::MissingType => BlockError::MissingType, + BlockError::UnsupportedVersion(__self_0) => { + BlockError::UnsupportedVersion(::core::clone::Clone::clone(__self_0)) + } + BlockError::DecodingError(__self_0) => { + BlockError::DecodingError(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for BlockError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + BlockError::NotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "NotFound", + &__self_0, + ) + } + BlockError::MissingType => { + ::core::fmt::Formatter::write_str(f, "MissingType") + } + BlockError::UnsupportedVersion(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "UnsupportedVersion", + &__self_0, + ) + } + BlockError::DecodingError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "DecodingError", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for BlockError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[allow(unused_qualifications)] + impl std::error::Error for BlockError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for BlockError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + BlockError::NotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)", + _0.as_display() + ), + ) + } + BlockError::MissingType {} => { + __formatter + .write_str( + "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata", + ) + } + BlockError::UnsupportedVersion(_0) => { + __formatter + .write_str( + "Unsupported extrinsic version, only version 4 is supported currently", + ) + } + BlockError::DecodingError(_0) => { + __formatter + .write_fmt( + format_args!("Cannot decode extrinsic: {0}", _0.as_display()), + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BlockError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for BlockError { + #[inline] + fn eq(&self, other: &BlockError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + (BlockError::NotFound(__self_0), BlockError::NotFound(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + ( + BlockError::UnsupportedVersion(__self_0), + BlockError::UnsupportedVersion(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + BlockError::DecodingError(__self_0), + BlockError::DecodingError(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + impl BlockError { + /// Produce an error that a block with the given hash cannot be found. + pub fn not_found(hash: impl AsRef<[u8]>) -> BlockError { + let hash = { + let res = ::alloc::fmt::format(format_args!("0x{0}", hex::encode(hash))); + res + }; + BlockError::NotFound(hash) + } + } + /// Transaction error. + #[non_exhaustive] + pub enum TransactionError { + /// The block hash that the transaction was added to could not be found. + /// This is probably because the block was retracted before being finalized. + #[error( + "The block containing the transaction can no longer be found (perhaps it was on a non-finalized fork?)" + )] + BlockNotFound, + /// An error happened on the node that the transaction was submitted to. + #[error("Error handling transaction: {0}")] + Error(String), + /// The transaction was deemed invalid. + #[error("The transaction is not valid: {0}")] + Invalid(String), + /// The transaction was dropped. + #[error("The transaction was dropped: {0}")] + Dropped(String), + } + #[automatically_derived] + impl ::core::clone::Clone for TransactionError { + #[inline] + fn clone(&self) -> TransactionError { + match self { + TransactionError::BlockNotFound => TransactionError::BlockNotFound, + TransactionError::Error(__self_0) => { + TransactionError::Error(::core::clone::Clone::clone(__self_0)) + } + TransactionError::Invalid(__self_0) => { + TransactionError::Invalid(::core::clone::Clone::clone(__self_0)) + } + TransactionError::Dropped(__self_0) => { + TransactionError::Dropped(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionError::BlockNotFound => { + ::core::fmt::Formatter::write_str(f, "BlockNotFound") + } + TransactionError::Error(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Error", + &__self_0, + ) + } + TransactionError::Invalid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Invalid", + &__self_0, + ) + } + TransactionError::Dropped(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Dropped", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TransactionError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[allow(unused_qualifications)] + impl std::error::Error for TransactionError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for TransactionError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + TransactionError::BlockNotFound {} => { + __formatter + .write_str( + "The block containing the transaction can no longer be found (perhaps it was on a non-finalized fork?)", + ) + } + TransactionError::Error(_0) => { + __formatter + .write_fmt( + format_args!( + "Error handling transaction: {0}", _0.as_display() + ), + ) + } + TransactionError::Invalid(_0) => { + __formatter + .write_fmt( + format_args!( + "The transaction is not valid: {0}", _0.as_display() + ), + ) + } + TransactionError::Dropped(_0) => { + __formatter + .write_fmt( + format_args!( + "The transaction was dropped: {0}", _0.as_display() + ), + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionError { + #[inline] + fn eq(&self, other: &TransactionError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionError::Error(__self_0), + TransactionError::Error(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + TransactionError::Invalid(__self_0), + TransactionError::Invalid(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + TransactionError::Dropped(__self_0), + TransactionError::Dropped(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + /// Something went wrong trying to encode a storage address. + #[non_exhaustive] + pub enum StorageAddressError { + /// Storage map type must be a composite type. + #[error("Storage map type must be a composite type")] + MapTypeMustBeTuple, + /// Storage lookup does not have the expected number of keys. + #[error("Storage lookup requires {expected} keys but got {actual} keys")] + WrongNumberOfKeys { + /// The actual number of keys needed, based on the metadata. + actual: usize, + /// The number of keys provided in the storage address. + expected: usize, + }, + /// This storage entry in the metadata does not have the correct number of hashers to fields. + #[error( + "Storage entry in metadata does not have the correct number of hashers to fields" + )] + WrongNumberOfHashers { + /// The number of hashers in the metadata for this storage entry. + hashers: usize, + /// The number of fields in the metadata for this storage entry. + fields: usize, + }, + /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. + #[error( + "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata." + )] + UnexpectedAddressBytes, + /// An invalid hasher was used to reconstruct a value from a chunk of bytes that is part of a storage address. Hashers where the hash does not contain the original value are invalid for this purpose. + #[error( + "An invalid hasher was used to reconstruct a value of type {ty_name} (id={ty_id}) from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher" + )] + HasherCannotReconstructKey { + /// Type id of the key's type. + ty_id: u32, + /// Type name of the key's type. + ty_name: String, + /// The invalid hasher that caused this error. + hasher: StorageHasher, + }, + } + #[automatically_derived] + impl ::core::clone::Clone for StorageAddressError { + #[inline] + fn clone(&self) -> StorageAddressError { + match self { + StorageAddressError::MapTypeMustBeTuple => { + StorageAddressError::MapTypeMustBeTuple + } + StorageAddressError::WrongNumberOfKeys { + actual: __self_0, + expected: __self_1, + } => { + StorageAddressError::WrongNumberOfKeys { + actual: ::core::clone::Clone::clone(__self_0), + expected: ::core::clone::Clone::clone(__self_1), + } + } + StorageAddressError::WrongNumberOfHashers { + hashers: __self_0, + fields: __self_1, + } => { + StorageAddressError::WrongNumberOfHashers { + hashers: ::core::clone::Clone::clone(__self_0), + fields: ::core::clone::Clone::clone(__self_1), + } + } + StorageAddressError::UnexpectedAddressBytes => { + StorageAddressError::UnexpectedAddressBytes + } + StorageAddressError::HasherCannotReconstructKey { + ty_id: __self_0, + ty_name: __self_1, + hasher: __self_2, + } => { + StorageAddressError::HasherCannotReconstructKey { + ty_id: ::core::clone::Clone::clone(__self_0), + ty_name: ::core::clone::Clone::clone(__self_1), + hasher: ::core::clone::Clone::clone(__self_2), + } + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageAddressError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + StorageAddressError::MapTypeMustBeTuple => { + ::core::fmt::Formatter::write_str(f, "MapTypeMustBeTuple") + } + StorageAddressError::WrongNumberOfKeys { + actual: __self_0, + expected: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "WrongNumberOfKeys", + "actual", + __self_0, + "expected", + &__self_1, + ) + } + StorageAddressError::WrongNumberOfHashers { + hashers: __self_0, + fields: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "WrongNumberOfHashers", + "hashers", + __self_0, + "fields", + &__self_1, + ) + } + StorageAddressError::UnexpectedAddressBytes => { + ::core::fmt::Formatter::write_str(f, "UnexpectedAddressBytes") + } + StorageAddressError::HasherCannotReconstructKey { + ty_id: __self_0, + ty_name: __self_1, + hasher: __self_2, + } => { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "HasherCannotReconstructKey", + "ty_id", + __self_0, + "ty_name", + __self_1, + "hasher", + &__self_2, + ) + } + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for StorageAddressError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for StorageAddressError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + StorageAddressError::MapTypeMustBeTuple {} => { + __formatter.write_str("Storage map type must be a composite type") + } + StorageAddressError::WrongNumberOfKeys { actual, expected } => { + __formatter + .write_fmt( + format_args!( + "Storage lookup requires {0} keys but got {1} keys", + expected.as_display(), actual.as_display() + ), + ) + } + StorageAddressError::WrongNumberOfHashers { hashers, fields } => { + __formatter + .write_str( + "Storage entry in metadata does not have the correct number of hashers to fields", + ) + } + StorageAddressError::UnexpectedAddressBytes {} => { + __formatter + .write_str( + "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata.", + ) + } + StorageAddressError::HasherCannotReconstructKey { + ty_id, + ty_name, + hasher, + } => { + __formatter + .write_fmt( + format_args!( + "An invalid hasher was used to reconstruct a value of type {0} (id={1}) from a hash formed by a {2:?} hasher. This is only possible for concat-style hashers or the identity hasher", + ty_name.as_display(), ty_id.as_display(), hasher + ), + ) + } + } + } + } + /// Something went wrong trying to access details in the metadata. + #[non_exhaustive] + pub enum MetadataError { + /// The DispatchError type isn't available in the metadata + #[error("The DispatchError type isn't available")] + DispatchErrorNotFound, + /// Type not found in metadata. + #[error("Type with ID {0} not found")] + TypeNotFound(u32), + /// Pallet not found (index). + #[error("Pallet with index {0} not found")] + PalletIndexNotFound(u8), + /// Pallet not found (name). + #[error("Pallet with name {0} not found")] + PalletNameNotFound(String), + /// Variant not found. + #[error("Variant with index {0} not found")] + VariantIndexNotFound(u8), + /// Constant not found. + #[error("Constant with name {0} not found")] + ConstantNameNotFound(String), + /// Call not found. + #[error("Call with name {0} not found")] + CallNameNotFound(String), + /// Runtime trait not found. + #[error("Runtime trait with name {0} not found")] + RuntimeTraitNotFound(String), + /// Runtime method not found. + #[error("Runtime method with name {0} not found")] + RuntimeMethodNotFound(String), + /// Call type not found in metadata. + #[error("Call type not found in pallet with index {0}")] + CallTypeNotFoundInPallet(u8), + /// Event type not found in metadata. + #[error("Event type not found in pallet with index {0}")] + EventTypeNotFoundInPallet(u8), + /// Storage details not found in metadata. + #[error("Storage details not found in pallet with name {0}")] + StorageNotFoundInPallet(String), + /// Storage entry not found. + #[error("Storage entry {0} not found")] + StorageEntryNotFound(String), + /// The generated interface used is not compatible with the node. + #[error("The generated code is not compatible with the node")] + IncompatibleCodegen, + /// Custom value not found. + #[error("Custom value with name {0} not found")] + CustomValueNameNotFound(String), + } + #[automatically_derived] + impl ::core::clone::Clone for MetadataError { + #[inline] + fn clone(&self) -> MetadataError { + match self { + MetadataError::DispatchErrorNotFound => { + MetadataError::DispatchErrorNotFound + } + MetadataError::TypeNotFound(__self_0) => { + MetadataError::TypeNotFound(::core::clone::Clone::clone(__self_0)) + } + MetadataError::PalletIndexNotFound(__self_0) => { + MetadataError::PalletIndexNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::PalletNameNotFound(__self_0) => { + MetadataError::PalletNameNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::VariantIndexNotFound(__self_0) => { + MetadataError::VariantIndexNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::ConstantNameNotFound(__self_0) => { + MetadataError::ConstantNameNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::CallNameNotFound(__self_0) => { + MetadataError::CallNameNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::RuntimeTraitNotFound(__self_0) => { + MetadataError::RuntimeTraitNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::RuntimeMethodNotFound(__self_0) => { + MetadataError::RuntimeMethodNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::CallTypeNotFoundInPallet(__self_0) => { + MetadataError::CallTypeNotFoundInPallet( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::EventTypeNotFoundInPallet(__self_0) => { + MetadataError::EventTypeNotFoundInPallet( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::StorageNotFoundInPallet(__self_0) => { + MetadataError::StorageNotFoundInPallet( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::StorageEntryNotFound(__self_0) => { + MetadataError::StorageEntryNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::IncompatibleCodegen => MetadataError::IncompatibleCodegen, + MetadataError::CustomValueNameNotFound(__self_0) => { + MetadataError::CustomValueNameNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for MetadataError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + MetadataError::DispatchErrorNotFound => { + ::core::fmt::Formatter::write_str(f, "DispatchErrorNotFound") + } + MetadataError::TypeNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "TypeNotFound", + &__self_0, + ) + } + MetadataError::PalletIndexNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "PalletIndexNotFound", + &__self_0, + ) + } + MetadataError::PalletNameNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "PalletNameNotFound", + &__self_0, + ) + } + MetadataError::VariantIndexNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "VariantIndexNotFound", + &__self_0, + ) + } + MetadataError::ConstantNameNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ConstantNameNotFound", + &__self_0, + ) + } + MetadataError::CallNameNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "CallNameNotFound", + &__self_0, + ) + } + MetadataError::RuntimeTraitNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "RuntimeTraitNotFound", + &__self_0, + ) + } + MetadataError::RuntimeMethodNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "RuntimeMethodNotFound", + &__self_0, + ) + } + MetadataError::CallTypeNotFoundInPallet(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "CallTypeNotFoundInPallet", + &__self_0, + ) + } + MetadataError::EventTypeNotFoundInPallet(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "EventTypeNotFoundInPallet", + &__self_0, + ) + } + MetadataError::StorageNotFoundInPallet(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "StorageNotFoundInPallet", + &__self_0, + ) + } + MetadataError::StorageEntryNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "StorageEntryNotFound", + &__self_0, + ) + } + MetadataError::IncompatibleCodegen => { + ::core::fmt::Formatter::write_str(f, "IncompatibleCodegen") + } + MetadataError::CustomValueNameNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "CustomValueNameNotFound", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for MetadataError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for MetadataError { + #[inline] + fn eq(&self, other: &MetadataError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + MetadataError::TypeNotFound(__self_0), + MetadataError::TypeNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::PalletIndexNotFound(__self_0), + MetadataError::PalletIndexNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::PalletNameNotFound(__self_0), + MetadataError::PalletNameNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::VariantIndexNotFound(__self_0), + MetadataError::VariantIndexNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::ConstantNameNotFound(__self_0), + MetadataError::ConstantNameNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::CallNameNotFound(__self_0), + MetadataError::CallNameNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::RuntimeTraitNotFound(__self_0), + MetadataError::RuntimeTraitNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::RuntimeMethodNotFound(__self_0), + MetadataError::RuntimeMethodNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::CallTypeNotFoundInPallet(__self_0), + MetadataError::CallTypeNotFoundInPallet(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::EventTypeNotFoundInPallet(__self_0), + MetadataError::EventTypeNotFoundInPallet(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::StorageNotFoundInPallet(__self_0), + MetadataError::StorageNotFoundInPallet(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::StorageEntryNotFound(__self_0), + MetadataError::StorageEntryNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::CustomValueNameNotFound(__self_0), + MetadataError::CustomValueNameNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for MetadataError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for MetadataError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + MetadataError::DispatchErrorNotFound {} => { + __formatter.write_str("The DispatchError type isn't available") + } + MetadataError::TypeNotFound(_0) => { + __formatter + .write_fmt( + format_args!("Type with ID {0} not found", _0.as_display()), + ) + } + MetadataError::PalletIndexNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Pallet with index {0} not found", _0.as_display() + ), + ) + } + MetadataError::PalletNameNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Pallet with name {0} not found", _0.as_display() + ), + ) + } + MetadataError::VariantIndexNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Variant with index {0} not found", _0.as_display() + ), + ) + } + MetadataError::ConstantNameNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Constant with name {0} not found", _0.as_display() + ), + ) + } + MetadataError::CallNameNotFound(_0) => { + __formatter + .write_fmt( + format_args!("Call with name {0} not found", _0.as_display()), + ) + } + MetadataError::RuntimeTraitNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Runtime trait with name {0} not found", _0.as_display() + ), + ) + } + MetadataError::RuntimeMethodNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Runtime method with name {0} not found", _0.as_display() + ), + ) + } + MetadataError::CallTypeNotFoundInPallet(_0) => { + __formatter + .write_fmt( + format_args!( + "Call type not found in pallet with index {0}", _0 + .as_display() + ), + ) + } + MetadataError::EventTypeNotFoundInPallet(_0) => { + __formatter + .write_fmt( + format_args!( + "Event type not found in pallet with index {0}", _0 + .as_display() + ), + ) + } + MetadataError::StorageNotFoundInPallet(_0) => { + __formatter + .write_fmt( + format_args!( + "Storage details not found in pallet with name {0}", _0 + .as_display() + ), + ) + } + MetadataError::StorageEntryNotFound(_0) => { + __formatter + .write_fmt( + format_args!("Storage entry {0} not found", _0.as_display()), + ) + } + MetadataError::IncompatibleCodegen {} => { + __formatter + .write_str("The generated code is not compatible with the node") + } + MetadataError::CustomValueNameNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Custom value with name {0} not found", _0.as_display() + ), + ) + } + } + } + } +} +pub mod events { + //! This module exposes the types and such necessary for working with events. + //! The two main entry points into events are [`crate::OnlineClient::events()`] + //! and calls like [crate::tx::TxProgress::wait_for_finalized_success()]. + mod events_client { + use crate::backend::{Backend, BackendExt, BlockRef}; + use crate::{client::OnlineClientT, error::Error, events::Events, Config}; + use derivative::Derivative; + use std::future::Future; + /// A client for working with events. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct EventsClient { + client: Client, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for EventsClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + EventsClient { client: ref __arg_0, _marker: ref __arg_1 } => { + EventsClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl EventsClient { + /// Create a new [`EventsClient`]. + pub fn new(client: Client) -> Self { + Self { + client, + _marker: std::marker::PhantomData, + } + } + } + impl EventsClient + where + T: Config, + Client: OnlineClientT, + { + /// Obtain events at some block hash. + /// + /// # Warning + /// + /// This call only supports blocks produced since the most recent + /// runtime upgrade. You can attempt to retrieve events from older blocks, + /// but may run into errors attempting to work with them. + pub fn at( + &self, + block_ref: impl Into>, + ) -> impl Future, Error>> + Send + 'static { + self.at_or_latest(Some(block_ref.into())) + } + /// Obtain events for the latest block. + pub fn at_latest( + &self, + ) -> impl Future, Error>> + Send + 'static { + self.at_or_latest(None) + } + /// Obtain events at some block hash. + fn at_or_latest( + &self, + block_ref: Option>, + ) -> impl Future, Error>> + Send + 'static { + let client = self.client.clone(); + async move { + let block_ref = match block_ref { + Some(r) => r, + None => client.backend().latest_finalized_block_ref().await?, + }; + let event_bytes = get_event_bytes(client.backend(), block_ref.hash()) + .await?; + Ok(Events::new(client.metadata(), block_ref.hash(), event_bytes)) + } + } + } + fn system_events_key() -> [u8; 32] { + let a = sp_core_hashing::twox_128(b"System"); + let b = sp_core_hashing::twox_128(b"Events"); + let mut res = [0; 32]; + res[0..16].clone_from_slice(&a); + res[16..32].clone_from_slice(&b); + res + } + pub(crate) async fn get_event_bytes( + backend: &dyn Backend, + block_hash: T::Hash, + ) -> Result, Error> { + Ok( + backend + .storage_fetch_value(system_events_key().to_vec(), block_hash) + .await? + .unwrap_or_default(), + ) + } + } + mod events_type { + //! A representation of a block of events. + use super::{Phase, StaticEvent}; + use crate::{ + client::OnlineClientT, error::{Error, MetadataError}, + events::events_client::get_event_bytes, metadata::types::PalletMetadata, + Config, Metadata, + }; + use codec::{Compact, Decode}; + use derivative::Derivative; + use scale_decode::DecodeAsType; + use std::sync::Arc; + /// A collection of events obtained from a block, bundled with the necessary + /// information needed to decode and iterate over them. + #[derivative(Clone(bound = ""))] + pub struct Events { + metadata: Metadata, + block_hash: T::Hash, + event_bytes: Arc<[u8]>, + start_idx: usize, + num_events: u32, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Events { + fn clone(&self) -> Self { + match *self { + Events { + metadata: ref __arg_0, + block_hash: ref __arg_1, + event_bytes: ref __arg_2, + start_idx: ref __arg_3, + num_events: ref __arg_4, + } => { + Events { + metadata: (*__arg_0).clone(), + block_hash: (*__arg_1).clone(), + event_bytes: (*__arg_2).clone(), + start_idx: (*__arg_3).clone(), + num_events: (*__arg_4).clone(), + } + } + } + } + } + impl std::fmt::Debug for Events { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Events") + .field("block_hash", &self.block_hash) + .field("event_bytes", &self.event_bytes) + .field("start_idx", &self.start_idx) + .field("num_events", &self.num_events) + .finish() + } + } + impl Events { + pub(crate) fn new( + metadata: Metadata, + block_hash: T::Hash, + event_bytes: Vec, + ) -> Self { + let cursor = &mut &*event_bytes; + let num_events = >::decode(cursor).unwrap_or(Compact(0)).0; + let start_idx = event_bytes.len() - cursor.len(); + Self { + metadata, + block_hash, + event_bytes: event_bytes.into(), + start_idx, + num_events, + } + } + /// Obtain the events from a block hash given custom metadata and a client. + /// + /// # Notes + /// + /// - Prefer to use [`crate::events::EventsClient::at`] to obtain the events. + /// - Subxt may fail to decode things that aren't from a runtime using the + /// latest metadata version. + /// - The client may not be able to obtain the block at the given hash. Only + /// archive nodes keep hold of all past block information. + pub async fn new_from_client( + metadata: Metadata, + block_hash: T::Hash, + client: Client, + ) -> Result + where + Client: OnlineClientT, + { + let event_bytes = get_event_bytes(client.backend(), block_hash).await?; + Ok(Events::new(metadata, block_hash, event_bytes)) + } + /// The number of events. + pub fn len(&self) -> u32 { + self.num_events + } + /// Are there no events in this block? + pub fn is_empty(&self) -> bool { + self.num_events == 0 + } + /// Return the block hash that these events are from. + pub fn block_hash(&self) -> T::Hash { + self.block_hash + } + /// Iterate over all of the events, using metadata to dynamically + /// decode them as we go, and returning the raw bytes and other associated + /// details. If an error occurs, all subsequent iterations return `None`. + pub fn iter( + &self, + ) -> impl Iterator< + Item = Result, Error>, + > + Send + Sync + 'static { + let event_bytes = self.event_bytes.clone(); + let metadata = self.metadata.clone(); + let num_events = self.num_events; + let mut pos = self.start_idx; + let mut index = 0; + std::iter::from_fn(move || { + if event_bytes.len() <= pos || num_events == index { + None + } else { + match EventDetails::decode_from( + metadata.clone(), + event_bytes.clone(), + pos, + index, + ) { + Ok(event_details) => { + pos += event_details.bytes().len(); + index += 1; + Some(Ok(event_details)) + } + Err(e) => { + pos = event_bytes.len(); + Some(Err(e)) + } + } + } + }) + } + /// Iterate through the events using metadata to dynamically decode and skip + /// them, and return only those which should decode to the provided `Ev` type. + /// If an error occurs, all subsequent iterations return `None`. + pub fn find( + &self, + ) -> impl Iterator> + '_ { + self.iter() + .filter_map(|ev| { + ev.and_then(|ev| ev.as_event::().map_err(Into::into)) + .transpose() + }) + } + /// Iterate through the events using metadata to dynamically decode and skip + /// them, and return the first event found which decodes to the provided `Ev` type. + pub fn find_first(&self) -> Result, Error> { + self.find::().next().transpose() + } + /// Iterate through the events using metadata to dynamically decode and skip + /// them, and return the last event found which decodes to the provided `Ev` type. + pub fn find_last(&self) -> Result, Error> { + self.find::().last().transpose() + } + /// Find an event that decodes to the type provided. Returns true if it was found. + pub fn has(&self) -> Result { + Ok(self.find::().next().transpose()?.is_some()) + } + } + /// The event details. + pub struct EventDetails { + phase: Phase, + /// The index of the event in the list of events in a given block. + index: u32, + all_bytes: Arc<[u8]>, + start_idx: usize, + event_start_idx: usize, + event_fields_start_idx: usize, + event_fields_end_idx: usize, + end_idx: usize, + metadata: Metadata, + topics: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for EventDetails + where + T::Hash: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "phase", + "index", + "all_bytes", + "start_idx", + "event_start_idx", + "event_fields_start_idx", + "event_fields_end_idx", + "end_idx", + "metadata", + "topics", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.phase, + &self.index, + &self.all_bytes, + &self.start_idx, + &self.event_start_idx, + &self.event_fields_start_idx, + &self.event_fields_end_idx, + &self.end_idx, + &self.metadata, + &&self.topics, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "EventDetails", + names, + values, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for EventDetails + where + T::Hash: ::core::clone::Clone, + { + #[inline] + fn clone(&self) -> EventDetails { + EventDetails { + phase: ::core::clone::Clone::clone(&self.phase), + index: ::core::clone::Clone::clone(&self.index), + all_bytes: ::core::clone::Clone::clone(&self.all_bytes), + start_idx: ::core::clone::Clone::clone(&self.start_idx), + event_start_idx: ::core::clone::Clone::clone(&self.event_start_idx), + event_fields_start_idx: ::core::clone::Clone::clone( + &self.event_fields_start_idx, + ), + event_fields_end_idx: ::core::clone::Clone::clone( + &self.event_fields_end_idx, + ), + end_idx: ::core::clone::Clone::clone(&self.end_idx), + metadata: ::core::clone::Clone::clone(&self.metadata), + topics: ::core::clone::Clone::clone(&self.topics), + } + } + } + impl EventDetails { + fn decode_from( + metadata: Metadata, + all_bytes: Arc<[u8]>, + start_idx: usize, + index: u32, + ) -> Result, Error> { + let input = &mut &all_bytes[start_idx..]; + let phase = Phase::decode(input)?; + let event_start_idx = all_bytes.len() - input.len(); + let pallet_index = u8::decode(input)?; + let variant_index = u8::decode(input)?; + let event_fields_start_idx = all_bytes.len() - input.len(); + let event_pallet = metadata.pallet_by_index_err(pallet_index)?; + let event_variant = event_pallet + .event_variant_by_index(variant_index) + .ok_or(MetadataError::VariantIndexNotFound(variant_index))?; + { + use ::tracing::__macro_support::Callsite as _; + static __CALLSITE: ::tracing::callsite::DefaultCallsite = { + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "event subxt/src/events/events_type.rs:220", + "subxt::events::events_type", + ::tracing::Level::DEBUG, + ::core::option::Option::Some( + "subxt/src/events/events_type.rs", + ), + ::core::option::Option::Some(220u32), + ::core::option::Option::Some("subxt::events::events_type"), + ::tracing_core::field::FieldSet::new( + &["message"], + ::tracing_core::callsite::Identifier(&__CALLSITE), + ), + ::tracing::metadata::Kind::EVENT, + ) + }; + ::tracing::callsite::DefaultCallsite::new(&META) + }; + let enabled = ::tracing::Level::DEBUG + <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::DEBUG + <= ::tracing::level_filters::LevelFilter::current() + && { + let interest = __CALLSITE.interest(); + !interest.is_never() + && ::tracing::__macro_support::__is_enabled( + __CALLSITE.metadata(), + interest, + ) + }; + if enabled { + (|value_set: ::tracing::field::ValueSet| { + let meta = __CALLSITE.metadata(); + ::tracing::Event::dispatch(meta, &value_set); + })({ + #[allow(unused_imports)] + use ::tracing::field::{debug, display, Value}; + let mut iter = __CALLSITE.metadata().fields().iter(); + __CALLSITE + .metadata() + .fields() + .value_set( + &[ + ( + &::core::iter::Iterator::next(&mut iter) + .expect("FieldSet corrupted (this is a bug)"), + ::core::option::Option::Some( + &format_args!( + "Decoding Event \'{0}::{1}\'", event_pallet.name(), & + event_variant.name + ) as &dyn Value, + ), + ), + ], + ) + }); + } else { + } + }; + for field_metadata in &event_variant.fields { + scale_decode::visitor::decode_with_visitor( + input, + field_metadata.ty.id, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(scale_decode::Error::from)?; + } + let event_fields_end_idx = all_bytes.len() - input.len(); + let topics = Vec::::decode(input)?; + let end_idx = all_bytes.len() - input.len(); + Ok(EventDetails { + phase, + index, + start_idx, + event_start_idx, + event_fields_start_idx, + event_fields_end_idx, + end_idx, + all_bytes, + metadata, + topics, + }) + } + /// When was the event produced? + pub fn phase(&self) -> Phase { + self.phase + } + /// What index is this event in the stored events for this block. + pub fn index(&self) -> u32 { + self.index + } + /// The index of the pallet that the event originated from. + pub fn pallet_index(&self) -> u8 { + self.all_bytes[self.event_fields_start_idx - 2] + } + /// The index of the event variant that the event originated from. + pub fn variant_index(&self) -> u8 { + self.all_bytes[self.event_fields_start_idx - 1] + } + /// The name of the pallet from whence the Event originated. + pub fn pallet_name(&self) -> &str { + self.event_metadata().pallet.name() + } + /// The name of the event (ie the name of the variant that it corresponds to). + pub fn variant_name(&self) -> &str { + &self.event_metadata().variant.name + } + /// Fetch details from the metadata for this event. + pub fn event_metadata(&self) -> EventMetadataDetails { + let pallet = self + .metadata + .pallet_by_index(self.pallet_index()) + .expect( + "event pallet to be found; we did this already during decoding", + ); + let variant = pallet + .event_variant_by_index(self.variant_index()) + .expect( + "event variant to be found; we did this already during decoding", + ); + EventMetadataDetails { + pallet, + variant, + } + } + /// Return _all_ of the bytes representing this event, which include, in order: + /// - The phase. + /// - Pallet and event index. + /// - Event fields. + /// - Event Topics. + pub fn bytes(&self) -> &[u8] { + &self.all_bytes[self.start_idx..self.end_idx] + } + /// Return the bytes representing the fields stored in this event. + pub fn field_bytes(&self) -> &[u8] { + &self.all_bytes[self.event_fields_start_idx..self.event_fields_end_idx] + } + /// Decode and provide the event fields back in the form of a [`scale_value::Composite`] + /// type which represents the named or unnamed fields that were present in the event. + pub fn field_values( + &self, + ) -> Result, Error> { + let bytes = &mut self.field_bytes(); + let event_metadata = self.event_metadata(); + let mut fields = event_metadata + .variant + .fields + .iter() + .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); + use scale_decode::DecodeAsFields; + let decoded = >::decode_as_fields(bytes, &mut fields, self.metadata.types())?; + Ok(decoded) + } + /// Attempt to decode these [`EventDetails`] into a type representing the event fields. + /// Such types are exposed in the codegen as `pallet_name::events::EventName` types. + pub fn as_event(&self) -> Result, Error> { + let ev_metadata = self.event_metadata(); + if ev_metadata.pallet.name() == E::PALLET + && ev_metadata.variant.name == E::EVENT + { + let mut fields = ev_metadata + .variant + .fields + .iter() + .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); + let decoded = E::decode_as_fields( + &mut self.field_bytes(), + &mut fields, + self.metadata.types(), + )?; + Ok(Some(decoded)) + } else { + Ok(None) + } + } + /// Attempt to decode these [`EventDetails`] into a root event type (which includes + /// the pallet and event enum variants as well as the event fields). A compatible + /// type for this is exposed via static codegen as a root level `Event` type. + pub fn as_root_event(&self) -> Result { + let bytes = &self + .all_bytes[self.event_start_idx..self.event_fields_end_idx]; + let decoded = E::decode_as_type( + &mut &bytes[..], + self.metadata.outer_enums().event_enum_ty(), + self.metadata.types(), + )?; + Ok(decoded) + } + /// Return the topics associated with this event. + pub fn topics(&self) -> &[T::Hash] { + &self.topics + } + } + /// Details for the given event plucked from the metadata. + pub struct EventMetadataDetails<'a> { + pub pallet: PalletMetadata<'a>, + pub variant: &'a scale_info::Variant, + } + } + use codec::{Decode, Encode}; + pub use events_client::EventsClient; + pub use events_type::{EventDetails, Events}; + use scale_decode::DecodeAsFields; + /// Trait to uniquely identify the events's identity from the runtime metadata. + /// + /// Generated API structures that represent an event implement this trait. + /// + /// The trait is utilized to decode emitted events from a block, via obtaining the + /// form of the `Event` from the metadata. + pub trait StaticEvent: DecodeAsFields { + /// Pallet name. + const PALLET: &'static str; + /// Event name. + const EVENT: &'static str; + /// Returns true if the given pallet and event names match this event. + fn is_event(pallet: &str, event: &str) -> bool { + Self::PALLET == pallet && Self::EVENT == event + } + } + /// A phase of a block's execution. + pub enum Phase { + /// Applying an extrinsic. + ApplyExtrinsic(u32), + /// Finalizing the block. + Finalization, + /// Initializing the block. + Initialization, + } + #[automatically_derived] + impl ::core::marker::Copy for Phase {} + #[automatically_derived] + impl ::core::clone::Clone for Phase { + #[inline] + fn clone(&self) -> Phase { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Phase { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + Phase::ApplyExtrinsic(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ApplyExtrinsic", + &__self_0, + ) + } + Phase::Finalization => { + ::core::fmt::Formatter::write_str(f, "Finalization") + } + Phase::Initialization => { + ::core::fmt::Formatter::write_str(f, "Initialization") + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Phase { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Phase {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Phase { + #[inline] + fn eq(&self, other: &Phase) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + Phase::ApplyExtrinsic(__self_0), + Phase::ApplyExtrinsic(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for Phase { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e.chain("Could not decode `Phase`, failed to read variant byte") + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + Phase::ApplyExtrinsic({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `Phase::ApplyExtrinsic.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(Phase::Finalization) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(Phase::Initialization) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into("Could not decode `Phase`, variant doesn't exist"), + ) + })(); + } + } + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for Phase { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + Phase::ApplyExtrinsic(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + Phase::Finalization => 0_usize, + Phase::Initialization => 0_usize, + _ => 0_usize, + } + } + fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>( + &self, + __codec_dest_edqy: &mut __CodecOutputEdqy, + ) { + match *self { + Phase::ApplyExtrinsic(ref aa) => { + __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + Phase::Finalization => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); + } + Phase::Initialization => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::codec::EncodeLike for Phase {} + }; +} +pub mod metadata { + //! Types representing the metadata obtained from a node. + mod decode_encode_traits { + use super::Metadata; + use crate::error::Error; + /// This trait is implemented for all types that also implement [`scale_decode::DecodeAsType`]. + pub trait DecodeWithMetadata: Sized { + /// Given some metadata and a type ID, attempt to SCALE decode the provided bytes into `Self`. + fn decode_with_metadata( + bytes: &mut &[u8], + type_id: u32, + metadata: &Metadata, + ) -> Result; + } + impl DecodeWithMetadata for T { + fn decode_with_metadata( + bytes: &mut &[u8], + type_id: u32, + metadata: &Metadata, + ) -> Result { + let val = T::decode_as_type(bytes, type_id, metadata.types())?; + Ok(val) + } + } + /// This trait is implemented for all types that also implement [`scale_encode::EncodeAsType`]. + pub trait EncodeWithMetadata { + /// SCALE encode this type to bytes, possibly with the help of metadata. + fn encode_with_metadata( + &self, + type_id: u32, + metadata: &Metadata, + bytes: &mut Vec, + ) -> Result<(), Error>; + } + impl EncodeWithMetadata for T { + /// SCALE encode this type to bytes, possibly with the help of metadata. + fn encode_with_metadata( + &self, + type_id: u32, + metadata: &Metadata, + bytes: &mut Vec, + ) -> Result<(), Error> { + self.encode_as_type_to(type_id, metadata.types(), bytes)?; + Ok(()) + } + } + } + mod metadata_type { + use crate::error::MetadataError; + use std::sync::Arc; + /// A cheaply clone-able representation of the runtime metadata received from a node. + pub struct Metadata { + inner: Arc, + } + #[automatically_derived] + impl ::core::clone::Clone for Metadata { + #[inline] + fn clone(&self) -> Metadata { + Metadata { + inner: ::core::clone::Clone::clone(&self.inner), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Metadata { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Metadata", + "inner", + &&self.inner, + ) + } + } + impl std::ops::Deref for Metadata { + type Target = subxt_metadata::Metadata; + fn deref(&self) -> &Self::Target { + &self.inner + } + } + impl Metadata { + pub(crate) fn new(md: subxt_metadata::Metadata) -> Self { + Metadata { inner: Arc::new(md) } + } + /// Identical to `metadata.pallet_by_name()`, but returns an error if the pallet is not found. + pub fn pallet_by_name_err( + &self, + name: &str, + ) -> Result { + self.pallet_by_name(name) + .ok_or_else(|| MetadataError::PalletNameNotFound(name.to_owned())) + } + /// Identical to `metadata.pallet_by_index()`, but returns an error if the pallet is not found. + pub fn pallet_by_index_err( + &self, + index: u8, + ) -> Result { + self.pallet_by_index(index) + .ok_or(MetadataError::PalletIndexNotFound(index)) + } + /// Identical to `metadata.runtime_api_trait_by_name()`, but returns an error if the trait is not found. + pub fn runtime_api_trait_by_name_err( + &self, + name: &str, + ) -> Result { + self.runtime_api_trait_by_name(name) + .ok_or_else(|| MetadataError::RuntimeTraitNotFound(name.to_owned())) + } + } + impl From for Metadata { + fn from(md: subxt_metadata::Metadata) -> Self { + Metadata::new(md) + } + } + impl TryFrom for Metadata { + type Error = subxt_metadata::TryFromError; + fn try_from( + value: frame_metadata::RuntimeMetadataPrefixed, + ) -> Result { + subxt_metadata::Metadata::try_from(value).map(Metadata::from) + } + } + impl codec::Decode for Metadata { + fn decode(input: &mut I) -> Result { + subxt_metadata::Metadata::decode(input).map(Metadata::new) + } + } + } + pub use decode_encode_traits::{DecodeWithMetadata, EncodeWithMetadata}; + pub use metadata_type::Metadata; + pub use subxt_metadata as types; +} +pub mod runtime_api { + //! Types associated with executing runtime API calls. + mod runtime_client { + use super::runtime_types::RuntimeApi; + use crate::{backend::BlockRef, client::OnlineClientT, error::Error, Config}; + use derivative::Derivative; + use std::{future::Future, marker::PhantomData}; + /// Execute runtime API calls. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct RuntimeApiClient { + client: Client, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for RuntimeApiClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + RuntimeApiClient { client: ref __arg_0, _marker: ref __arg_1 } => { + RuntimeApiClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl RuntimeApiClient { + /// Create a new [`RuntimeApiClient`] + pub fn new(client: Client) -> Self { + Self { + client, + _marker: PhantomData, + } + } + } + impl RuntimeApiClient + where + T: Config, + Client: OnlineClientT, + { + /// Obtain a runtime API interface at some block hash. + pub fn at( + &self, + block_ref: impl Into>, + ) -> RuntimeApi { + RuntimeApi::new(self.client.clone(), block_ref.into()) + } + /// Obtain a runtime API interface at the latest block hash. + pub fn at_latest( + &self, + ) -> impl Future< + Output = Result, Error>, + > + Send + 'static { + let client = self.client.clone(); + async move { + let block_ref = client.backend().latest_finalized_block_ref().await?; + Ok(RuntimeApi::new(client, block_ref)) + } + } + } + } + mod runtime_payload { + use core::marker::PhantomData; + use derivative::Derivative; + use scale_encode::EncodeAsFields; + use scale_value::Composite; + use std::borrow::Cow; + use crate::dynamic::DecodedValueThunk; + use crate::error::MetadataError; + use crate::{metadata::DecodeWithMetadata, Error, Metadata}; + /// This represents a runtime API payload that can call into the runtime of node. + /// + /// # Components + /// + /// - associated return type + /// + /// Resulting bytes of the call are interpreted into this type. + /// + /// - runtime function name + /// + /// The function name of the runtime API call. This is obtained by concatenating + /// the runtime trait name with the trait's method. + /// + /// For example, the substrate runtime trait [Metadata](https://github.com/paritytech/substrate/blob/cb954820a8d8d765ce75021e244223a3b4d5722d/primitives/api/src/lib.rs#L745) + /// contains the `metadata_at_version` function. The corresponding runtime function + /// is `Metadata_metadata_at_version`. + /// + /// - encoded arguments + /// + /// Each argument of the runtime function must be scale-encoded. + pub trait RuntimeApiPayload { + /// The return type of the function call. + type ReturnType: DecodeWithMetadata; + /// The runtime API trait name. + fn trait_name(&self) -> &str; + /// The runtime API method name. + fn method_name(&self) -> &str; + /// Scale encode the arguments data. + fn encode_args_to( + &self, + metadata: &Metadata, + out: &mut Vec, + ) -> Result<(), Error>; + /// Encode arguments data and return the output. This is a convenience + /// wrapper around [`RuntimeApiPayload::encode_args_to`]. + fn encode_args(&self, metadata: &Metadata) -> Result, Error> { + let mut v = Vec::new(); + self.encode_args_to(metadata, &mut v)?; + Ok(v) + } + /// Returns the statically generated validation hash. + fn validation_hash(&self) -> Option<[u8; 32]> { + None + } + } + /// A runtime API payload containing the generic argument data + /// and interpreting the result of the call as `ReturnTy`. + /// + /// This can be created from static values (ie those generated + /// via the `subxt` macro) or dynamic values via [`dynamic`]. + #[derivative( + Clone(bound = "ArgsData: Clone"), + Debug(bound = "ArgsData: std::fmt::Debug"), + Eq(bound = "ArgsData: std::cmp::Eq"), + Ord(bound = "ArgsData: std::cmp::Ord"), + PartialEq(bound = "ArgsData: std::cmp::PartialEq"), + PartialOrd(bound = "ArgsData: std::cmp::PartialOrd") + )] + pub struct Payload { + trait_name: Cow<'static, str>, + method_name: Cow<'static, str>, + args_data: ArgsData, + validation_hash: Option<[u8; 32]>, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Payload + where + ArgsData: Clone, + { + fn clone(&self) -> Self { + match *self { + Payload { + trait_name: ref __arg_0, + method_name: ref __arg_1, + args_data: ref __arg_2, + validation_hash: ref __arg_3, + _marker: ref __arg_4, + } => { + Payload { + trait_name: (*__arg_0).clone(), + method_name: (*__arg_1).clone(), + args_data: (*__arg_2).clone(), + validation_hash: (*__arg_3).clone(), + _marker: (*__arg_4).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Payload + where + ArgsData: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Payload { + trait_name: ref __arg_0, + method_name: ref __arg_1, + args_data: ref __arg_2, + validation_hash: ref __arg_3, + _marker: ref __arg_4, + } => { + let mut __debug_trait_builder = __f.debug_struct("Payload"); + let _ = __debug_trait_builder.field("trait_name", &&(*__arg_0)); + let _ = __debug_trait_builder.field("method_name", &&(*__arg_1)); + let _ = __debug_trait_builder.field("args_data", &&(*__arg_2)); + let _ = __debug_trait_builder + .field("validation_hash", &&(*__arg_3)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_4)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for Payload + where + ArgsData: std::cmp::Eq, + {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for Payload + where + ArgsData: std::cmp::PartialEq, + { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + Payload { + trait_name: ref __self_0, + method_name: ref __self_1, + args_data: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Payload { + trait_name: ref __other_0, + method_name: ref __other_1, + args_data: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + && &(*__self_3) == &(*__other_3) + && &(*__self_4) == &(*__other_4) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialOrd for Payload + where + ArgsData: std::cmp::PartialOrd, + { + fn partial_cmp( + &self, + other: &Self, + ) -> ::std::option::Option<::std::cmp::Ordering> { + match *self { + Payload { + trait_name: ref __self_0, + method_name: ref __self_1, + args_data: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Payload { + trait_name: ref __other_0, + method_name: ref __other_1, + args_data: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_0), + &(*__other_0), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_1), + &(*__other_1), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_2), + &(*__other_2), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_3), + &(*__other_3), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_4), + &(*__other_4), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::Ord for Payload + where + ArgsData: std::cmp::Ord, + { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + Payload { + trait_name: ref __self_0, + method_name: ref __self_1, + args_data: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Payload { + trait_name: ref __other_0, + method_name: ref __other_1, + args_data: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_4), &(*__other_4)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + impl RuntimeApiPayload + for Payload { + type ReturnType = ReturnTy; + fn trait_name(&self) -> &str { + &self.trait_name + } + fn method_name(&self) -> &str { + &self.method_name + } + fn encode_args_to( + &self, + metadata: &Metadata, + out: &mut Vec, + ) -> Result<(), Error> { + let api_method = metadata + .runtime_api_trait_by_name_err(&self.trait_name)? + .method_by_name(&self.method_name) + .ok_or_else(|| MetadataError::RuntimeMethodNotFound( + (*self.method_name).to_owned(), + ))?; + let mut fields = api_method + .inputs() + .map(|input| scale_encode::Field::named(input.ty, &input.name)); + self.args_data.encode_as_fields_to(&mut fields, metadata.types(), out)?; + Ok(()) + } + fn validation_hash(&self) -> Option<[u8; 32]> { + self.validation_hash + } + } + /// A dynamic runtime API payload. + pub type DynamicRuntimeApiPayload = Payload, DecodedValueThunk>; + impl Payload { + /// Create a new [`Payload`]. + pub fn new( + trait_name: impl Into, + method_name: impl Into, + args_data: ArgsData, + ) -> Self { + Payload { + trait_name: Cow::Owned(trait_name.into()), + method_name: Cow::Owned(method_name.into()), + args_data, + validation_hash: None, + _marker: PhantomData, + } + } + /// Create a new static [`Payload`] using static function name + /// and scale-encoded argument data. + /// + /// This is only expected to be used from codegen. + #[doc(hidden)] + pub fn new_static( + trait_name: &'static str, + method_name: &'static str, + args_data: ArgsData, + hash: [u8; 32], + ) -> Payload { + Payload { + trait_name: Cow::Borrowed(trait_name), + method_name: Cow::Borrowed(method_name), + args_data, + validation_hash: Some(hash), + _marker: std::marker::PhantomData, + } + } + /// Do not validate this call prior to submitting it. + pub fn unvalidated(self) -> Self { + Self { + validation_hash: None, + ..self + } + } + /// Returns the trait name. + pub fn trait_name(&self) -> &str { + &self.trait_name + } + /// Returns the method name. + pub fn method_name(&self) -> &str { + &self.method_name + } + /// Returns the arguments data. + pub fn args_data(&self) -> &ArgsData { + &self.args_data + } + } + /// Create a new [`DynamicRuntimeApiPayload`]. + pub fn dynamic( + trait_name: impl Into, + method_name: impl Into, + args_data: impl Into>, + ) -> DynamicRuntimeApiPayload { + Payload::new(trait_name, method_name, args_data.into()) + } + } + mod runtime_types { + use crate::{ + backend::{BackendExt, BlockRef}, + client::OnlineClientT, error::{Error, MetadataError}, + metadata::DecodeWithMetadata, Config, + }; + use codec::Decode; + use derivative::Derivative; + use std::{future::Future, marker::PhantomData}; + use super::RuntimeApiPayload; + /// Execute runtime API calls. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct RuntimeApi { + client: Client, + block_ref: BlockRef, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for RuntimeApi + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + RuntimeApi { + client: ref __arg_0, + block_ref: ref __arg_1, + _marker: ref __arg_2, + } => { + RuntimeApi { + client: (*__arg_0).clone(), + block_ref: (*__arg_1).clone(), + _marker: (*__arg_2).clone(), + } + } + } + } + } + impl RuntimeApi { + /// Create a new [`RuntimeApi`] + pub(crate) fn new(client: Client, block_ref: BlockRef) -> Self { + Self { + client, + block_ref, + _marker: PhantomData, + } + } + } + impl RuntimeApi + where + T: Config, + Client: OnlineClientT, + { + /// Execute a raw runtime API call. + pub fn call_raw<'a, Res: Decode>( + &self, + function: &'a str, + call_parameters: Option<&'a [u8]>, + ) -> impl Future> + 'a { + let client = self.client.clone(); + let block_hash = self.block_ref.hash(); + async move { + let data: Res = client + .backend() + .call_decoding(function, call_parameters, block_hash) + .await?; + Ok(data) + } + } + /// Execute a runtime API call. + pub fn call( + &self, + payload: Call, + ) -> impl Future> { + let client = self.client.clone(); + let block_hash = self.block_ref.hash(); + async move { + let metadata = client.metadata(); + let api_trait = metadata + .runtime_api_trait_by_name_err(payload.trait_name())?; + let api_method = api_trait + .method_by_name(payload.method_name()) + .ok_or_else(|| { + MetadataError::RuntimeMethodNotFound( + payload.method_name().to_owned(), + ) + })?; + if let Some(static_hash) = payload.validation_hash() { + let Some(runtime_hash) = api_trait + .method_hash(payload.method_name()) else { + return Err(MetadataError::IncompatibleCodegen.into()); + }; + if static_hash != runtime_hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + } + let params = payload.encode_args(&metadata)?; + let call_name = { + let res = ::alloc::fmt::format( + format_args!( + "{0}_{1}", payload.trait_name(), payload.method_name() + ), + ); + res + }; + let bytes = client + .backend() + .call(&call_name, Some(params.as_slice()), block_hash) + .await?; + let value = ::decode_with_metadata( + &mut &bytes[..], + api_method.output_ty(), + &metadata, + )?; + Ok(value) + } + } + } + } + pub use runtime_client::RuntimeApiClient; + pub use runtime_payload::{ + dynamic, DynamicRuntimeApiPayload, Payload, RuntimeApiPayload, + }; + pub use runtime_types::RuntimeApi; +} +pub mod storage { + //! Types associated with accessing and working with storage items. + mod storage_address { + use crate::{ + dynamic::DecodedValueThunk, + error::{Error, MetadataError, StorageAddressError}, + metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, + utils::{Encoded, Static}, + }; + use derivative::Derivative; + use scale_info::TypeDef; + use std::borrow::Cow; + use subxt_metadata::{StorageEntryType, StorageHasher}; + use super::StorageKey; + /// This represents a storage address. Anything implementing this trait + /// can be used to fetch and iterate over storage entries. + pub trait StorageAddress { + /// The target type of the value that lives at this address. + type Target: DecodeWithMetadata; + /// The keys type used to construct this address. + type Keys: StorageKey; + /// Can an entry be fetched from this address? + /// Set this type to [`Yes`] to enable the corresponding calls to be made. + type IsFetchable; + /// Can a default entry be obtained from this address? + /// Set this type to [`Yes`] to enable the corresponding calls to be made. + type IsDefaultable; + /// Can this address be iterated over? + /// Set this type to [`Yes`] to enable the corresponding calls to be made. + type IsIterable; + /// The name of the pallet that the entry lives under. + fn pallet_name(&self) -> &str; + /// The name of the entry in a given pallet that the item is at. + fn entry_name(&self) -> &str; + /// Output the non-prefix bytes; that is, any additional bytes that need + /// to be appended to the key to dig into maps. + fn append_entry_bytes( + &self, + metadata: &Metadata, + bytes: &mut Vec, + ) -> Result<(), Error>; + /// An optional hash which, if present, will be checked against + /// the node metadata to confirm that the return type matches what + /// we are expecting. + fn validation_hash(&self) -> Option<[u8; 32]> { + None + } + } + /// Used to signal whether a [`StorageAddress`] can be iterated, + /// fetched and returned with a default value in the type system. + pub struct Yes; + /// A concrete storage address. This can be created from static values (ie those generated + /// via the `subxt` macro) or dynamic values via [`dynamic`]. + #[derivative( + Clone(bound = "Keys: Clone"), + Debug(bound = "Keys: std::fmt::Debug"), + Eq(bound = "Keys: std::cmp::Eq"), + Ord(bound = "Keys: std::cmp::Ord"), + PartialEq(bound = "Keys: std::cmp::PartialEq"), + PartialOrd(bound = "Keys: std::cmp::PartialOrd") + )] + pub struct Address< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > { + pallet_name: Cow<'static, str>, + entry_name: Cow<'static, str>, + keys: Keys, + validation_hash: Option<[u8; 32]>, + _marker: std::marker::PhantomData< + (ReturnTy, Fetchable, Defaultable, Iterable), + >, + } + #[allow(unused_qualifications)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::clone::Clone + for Address + where + Keys: Clone, + { + fn clone(&self) -> Self { + match *self { + Address { + pallet_name: ref __arg_0, + entry_name: ref __arg_1, + keys: ref __arg_2, + validation_hash: ref __arg_3, + _marker: ref __arg_4, + } => { + Address { + pallet_name: (*__arg_0).clone(), + entry_name: (*__arg_1).clone(), + keys: (*__arg_2).clone(), + validation_hash: (*__arg_3).clone(), + _marker: (*__arg_4).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::fmt::Debug for Address + where + Keys: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Address { + pallet_name: ref __arg_0, + entry_name: ref __arg_1, + keys: ref __arg_2, + validation_hash: ref __arg_3, + _marker: ref __arg_4, + } => { + let mut __debug_trait_builder = __f.debug_struct("Address"); + let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); + let _ = __debug_trait_builder.field("entry_name", &&(*__arg_1)); + let _ = __debug_trait_builder.field("keys", &&(*__arg_2)); + let _ = __debug_trait_builder + .field("validation_hash", &&(*__arg_3)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_4)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq + for Address + where + Keys: std::cmp::Eq, + {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::cmp::PartialEq + for Address + where + Keys: std::cmp::PartialEq, + { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + Address { + pallet_name: ref __self_0, + entry_name: ref __self_1, + keys: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Address { + pallet_name: ref __other_0, + entry_name: ref __other_1, + keys: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + && &(*__self_3) == &(*__other_3) + && &(*__self_4) == &(*__other_4) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::cmp::PartialOrd + for Address + where + Keys: std::cmp::PartialOrd, + { + fn partial_cmp( + &self, + other: &Self, + ) -> ::std::option::Option<::std::cmp::Ordering> { + match *self { + Address { + pallet_name: ref __self_0, + entry_name: ref __self_1, + keys: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Address { + pallet_name: ref __other_0, + entry_name: ref __other_1, + keys: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_0), + &(*__other_0), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_1), + &(*__other_1), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_2), + &(*__other_2), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_3), + &(*__other_3), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_4), + &(*__other_4), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::cmp::Ord for Address + where + Keys: std::cmp::Ord, + { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + Address { + pallet_name: ref __self_0, + entry_name: ref __self_1, + keys: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Address { + pallet_name: ref __other_0, + entry_name: ref __other_1, + keys: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_4), &(*__other_4)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + /// A storage key for static encoded values. + /// The original value is only present at construction, but can be decoded from the contained bytes. + #[derivative(Clone(bound = ""), Debug(bound = ""))] + pub struct StaticStorageKey { + pub(super) bytes: Static, + pub(super) _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for StaticStorageKey { + fn clone(&self) -> Self { + match *self { + StaticStorageKey { bytes: ref __arg_0, _marker: ref __arg_1 } => { + StaticStorageKey { + bytes: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for StaticStorageKey { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + StaticStorageKey { bytes: ref __arg_0, _marker: ref __arg_1 } => { + let mut __debug_trait_builder = __f + .debug_struct("StaticStorageKey"); + let _ = __debug_trait_builder.field("bytes", &&(*__arg_0)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + impl StaticStorageKey { + /// Creates a new static storage key + pub fn new(key: &K) -> Self { + StaticStorageKey { + bytes: Static(Encoded(key.encode())), + _marker: std::marker::PhantomData, + } + } + /// Returns the scale-encoded bytes that make up this key + pub fn bytes(&self) -> &[u8] { + &self.bytes.0.0 + } + } + /// A typical storage address constructed at runtime rather than via the `subxt` macro; this + /// has no restriction on what it can be used for (since we don't statically know). + pub type DynamicAddress = Address; + impl DynamicAddress { + /// Creates a new dynamic address. As `Keys` you can use a `Vec` + pub fn new( + pallet_name: impl Into, + entry_name: impl Into, + keys: Keys, + ) -> Self { + Self { + pallet_name: Cow::Owned(pallet_name.into()), + entry_name: Cow::Owned(entry_name.into()), + keys, + validation_hash: None, + _marker: std::marker::PhantomData, + } + } + } + impl< + Keys, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > Address + where + Keys: StorageKey, + ReturnTy: DecodeWithMetadata, + { + /// Create a new [`Address`] using static strings for the pallet and call name. + /// This is only expected to be used from codegen. + #[doc(hidden)] + pub fn new_static( + pallet_name: &'static str, + entry_name: &'static str, + keys: Keys, + hash: [u8; 32], + ) -> Self { + Self { + pallet_name: Cow::Borrowed(pallet_name), + entry_name: Cow::Borrowed(entry_name), + keys, + validation_hash: Some(hash), + _marker: std::marker::PhantomData, + } + } + } + impl< + Keys, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > Address + where + Keys: StorageKey, + ReturnTy: DecodeWithMetadata, + { + /// Do not validate this storage entry prior to accessing it. + pub fn unvalidated(self) -> Self { + Self { + validation_hash: None, + ..self + } + } + /// Return bytes representing the root of this storage entry (ie a hash of + /// the pallet and entry name). Use [`crate::storage::StorageClient::address_bytes()`] + /// to obtain the bytes representing the entire address. + pub fn to_root_bytes(&self) -> Vec { + super::utils::storage_address_root_bytes(self) + } + } + impl StorageAddress + for Address + where + Keys: StorageKey, + ReturnTy: DecodeWithMetadata, + { + type Target = ReturnTy; + type Keys = Keys; + type IsFetchable = Fetchable; + type IsDefaultable = Defaultable; + type IsIterable = Iterable; + fn pallet_name(&self) -> &str { + &self.pallet_name + } + fn entry_name(&self) -> &str { + &self.entry_name + } + fn append_entry_bytes( + &self, + metadata: &Metadata, + bytes: &mut Vec, + ) -> Result<(), Error> { + let pallet = metadata.pallet_by_name_err(self.pallet_name())?; + let storage = pallet + .storage() + .ok_or_else(|| MetadataError::StorageNotFoundInPallet( + self.pallet_name().to_owned(), + ))?; + let entry = storage + .entry_by_name(self.entry_name()) + .ok_or_else(|| MetadataError::StorageEntryNotFound( + self.entry_name().to_owned(), + ))?; + let keys_iter = self.keys.keys_iter(); + let keys_len = self.keys.keys_len(); + if keys_len == 0 { + return Ok(()); + } + let StorageEntryType::Map { hashers, key_ty, .. } = entry + .entry_type() else { + return Err( + StorageAddressError::WrongNumberOfKeys { + expected: 0, + actual: keys_len, + } + .into(), + ); + }; + let ty = metadata + .types() + .resolve(*key_ty) + .ok_or(MetadataError::TypeNotFound(*key_ty))?; + let type_ids = match &ty.type_def { + TypeDef::Tuple(tuple) => { + either::Either::Left(tuple.fields.iter().map(|f| f.id)) + } + _other => either::Either::Right(std::iter::once(*key_ty)), + }; + if hashers.len() == 1 { + let mut input = Vec::new(); + let iter = keys_iter.zip(type_ids); + for (key, type_id) in iter { + key.encode_with_metadata(type_id, metadata, &mut input)?; + } + hash_bytes(&input, &hashers[0], bytes); + } else if hashers.len() >= type_ids.len() { + let iter = keys_iter.zip(type_ids).zip(hashers); + for ((key, type_id), hasher) in iter { + let mut input = Vec::new(); + key.encode_with_metadata(type_id, metadata, &mut input)?; + hash_bytes(&input, hasher, bytes); + } + } else { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: type_ids.len(), + } + .into(), + ); + } + Ok(()) + } + fn validation_hash(&self) -> Option<[u8; 32]> { + self.validation_hash + } + } + /// Construct a new dynamic storage lookup. + pub fn dynamic( + pallet_name: impl Into, + entry_name: impl Into, + storage_entry_keys: Keys, + ) -> DynamicAddress { + DynamicAddress::new(pallet_name, entry_name, storage_entry_keys) + } + /// Take some SCALE encoded bytes and a [`StorageHasher`] and hash the bytes accordingly. + fn hash_bytes(input: &[u8], hasher: &StorageHasher, bytes: &mut Vec) { + match hasher { + StorageHasher::Identity => bytes.extend(input), + StorageHasher::Blake2_128 => { + bytes.extend(sp_core_hashing::blake2_128(input)) + } + StorageHasher::Blake2_128Concat => { + bytes.extend(sp_core_hashing::blake2_128(input)); + bytes.extend(input); + } + StorageHasher::Blake2_256 => { + bytes.extend(sp_core_hashing::blake2_256(input)) + } + StorageHasher::Twox128 => bytes.extend(sp_core_hashing::twox_128(input)), + StorageHasher::Twox256 => bytes.extend(sp_core_hashing::twox_256(input)), + StorageHasher::Twox64Concat => { + bytes.extend(sp_core_hashing::twox_64(input)); + bytes.extend(input); + } + } + } + } + mod storage_client { + use super::{ + storage_type::{validate_storage_address, Storage}, + utils, StorageAddress, + }; + use crate::{ + backend::BlockRef, client::{OfflineClientT, OnlineClientT}, + error::Error, Config, + }; + use derivative::Derivative; + use std::{future::Future, marker::PhantomData}; + /// Query the runtime storage. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct StorageClient { + client: Client, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for StorageClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + StorageClient { client: ref __arg_0, _marker: ref __arg_1 } => { + StorageClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl StorageClient { + /// Create a new [`StorageClient`] + pub fn new(client: Client) -> Self { + Self { + client, + _marker: PhantomData, + } + } + } + impl StorageClient + where + T: Config, + Client: OfflineClientT, + { + /// Run the validation logic against some storage address you'd like to access. Returns `Ok(())` + /// if the address is valid (or if it's not possible to check since the address has no validation hash). + /// Return an error if the address was not valid or something went wrong trying to validate it (ie + /// the pallet or storage entry in question do not exist at all). + pub fn validate( + &self, + address: &Address, + ) -> Result<(), Error> { + let metadata = self.client.metadata(); + let pallet_metadata = metadata + .pallet_by_name_err(address.pallet_name())?; + validate_storage_address(address, pallet_metadata) + } + /// Convert some storage address into the raw bytes that would be submitted to the node in order + /// to retrieve the entries at the root of the associated address. + pub fn address_root_bytes( + &self, + address: &Address, + ) -> Vec { + utils::storage_address_root_bytes(address) + } + /// Convert some storage address into the raw bytes that would be submitted to the node in order + /// to retrieve an entry. This fails if [`StorageAddress::append_entry_bytes`] does; in the built-in + /// implementation this would be if the pallet and storage entry being asked for is not available on the + /// node you're communicating with, or if the metadata is missing some type information (which should not + /// happen). + pub fn address_bytes( + &self, + address: &Address, + ) -> Result, Error> { + utils::storage_address_bytes(address, &self.client.metadata()) + } + } + impl StorageClient + where + T: Config, + Client: OnlineClientT, + { + /// Obtain storage at some block hash. + pub fn at( + &self, + block_ref: impl Into>, + ) -> Storage { + Storage::new(self.client.clone(), block_ref.into()) + } + /// Obtain storage at the latest block hash. + pub fn at_latest( + &self, + ) -> impl Future< + Output = Result, Error>, + > + Send + 'static { + let client = self.client.clone(); + async move { + let block_ref = client.backend().latest_finalized_block_ref().await?; + Ok(Storage::new(client, block_ref)) + } + } + } + } + mod storage_key { + use super::{ + storage_address::StaticStorageKey, + utils::{ + hash_contains_unhashed_value, strip_storage_addess_root_bytes, + strip_storage_hash_bytes, + }, + }; + use crate::{ + dynamic::DecodedValueThunk, error::{Error, StorageAddressError}, + metadata::{DecodeWithMetadata, Metadata}, + utils::{Encoded, Static}, + }; + use scale_encode::EncodeAsType; + use subxt_metadata::StorageHasher; + /// This trait should be implemented by anything that can be used as one or multiple storage keys. + pub trait StorageKey { + /// Iterator over the storage keys, each key implements EncodeAsType to + /// give the corresponding bytes to a `StorageHasher`. + fn keys_iter(&self) -> impl Iterator; + /// How many keys are there in total? Each key is an element that needs to be individually hashed. + fn keys_len(&self) -> usize; + /// Attempts to decode the StorageKey from a storage address that has been stripped of its root bytes. + /// + /// Example: Imagine The `StorageKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. + /// Then the memory layout of the storage address is: + /// ```txt + /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | + /// ``` + /// `cursor` should point into a region after those first 16 bytes, at the start of a new hash. + /// `hashers_and_ty_ids` should consume all the hashers that have been used for decoding, such that there are less hashers coming to the next key. + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static; + } + /// Implement `StorageKey` for `()` which can be used for keyless storage entries. + impl StorageKey for () { + fn keys_iter(&self) -> impl Iterator { + std::iter::empty() + } + fn keys_len(&self) -> usize { + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + _metadata: &Metadata, + ) -> Result { + if hashers_and_ty_ids.is_empty() { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into(), + ); + } + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; + Ok(()) + } + } + impl StorageKey + for StaticStorageKey { + fn keys_iter(&self) -> impl Iterator { + std::iter::once(&self.bytes as &dyn EncodeAsType) + } + fn keys_len(&self) -> usize { + 1 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into(), + ); + }; + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; + decode_storage_key_from_hash(cursor, hasher, *ty_id, metadata) + } + } + pub fn decode_storage_key_from_hash( + cursor: &mut &[u8], + hasher: &StorageHasher, + ty_id: u32, + metadata: &Metadata, + ) -> Result, Error> { + strip_storage_hash_bytes(cursor, hasher)?; + let bytes = *cursor; + if let Err(err) + = scale_decode::visitor::decode_with_visitor( + cursor, + ty_id, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) { + return Err(scale_decode::Error::from(err).into()); + } + let bytes_decoded = bytes.len() - cursor.len(); + if !hash_contains_unhashed_value(hasher) && bytes_decoded > 0 { + let ty_name = metadata + .types() + .resolve(ty_id) + .expect( + "ty_id is in metadata, because decode_with_visitor did not fail above; qed", + ) + .path + .to_string(); + return Err( + StorageAddressError::HasherCannotReconstructKey { + ty_id, + ty_name, + hasher: *hasher, + } + .into(), + ); + } + let key_bytes = bytes[..bytes_decoded].to_vec(); + let key = StaticStorageKey { + bytes: Static(Encoded(key_bytes)), + _marker: std::marker::PhantomData::, + }; + Ok(key) + } + impl StorageKey for Vec { + fn keys_iter(&self) -> impl Iterator { + self.iter().map(|e| e as &dyn EncodeAsType) + } + fn keys_len(&self) -> usize { + self.len() + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); + let mut result: Vec = ::alloc::vec::Vec::new(); + let mut n = 0; + while !cursor.is_empty() { + let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { + return Err(StorageAddressError::UnexpectedAddressBytes.into()); + }; + strip_storage_hash_bytes(cursor, hasher)?; + let decoded = DecodedValueThunk::decode_with_metadata( + cursor, + *ty_id, + metadata, + )?; + let value = decoded.to_value()?; + result.push(value.remove_context()); + n += 1; + } + *hashers_and_ty_ids = &hashers_and_ty_ids[n..]; + Ok(result) + } + } + #[rustfmt::skip] + const _: () = { + { + impl StorageKey for (A, B) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl StorageKey + for (A, B, C) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + > StorageKey for (A, B, C, D) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + E: StorageKey, + > StorageKey for (A, B, C, D, E) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + (self.4.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + (0 * 4 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[4]; + let key = E::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + E: StorageKey, + F: StorageKey, + > StorageKey for (A, B, C, D, E, F) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + (self.4.keys_len()) + + (self.5.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[4]; + let key = E::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[5]; + let key = F::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + E: StorageKey, + F: StorageKey, + G: StorageKey, + > StorageKey for (A, B, C, D, E, F, G) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + (self.4.keys_len()) + + (self.5.keys_len()) + (self.6.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + (0 * 6 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[4]; + let key = E::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[5]; + let key = F::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[6]; + let key = G::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + E: StorageKey, + F: StorageKey, + G: StorageKey, + H: StorageKey, + > StorageKey for (A, B, C, D, E, F, G, H) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + (self.4.keys_len()) + + (self.5.keys_len()) + (self.6.keys_len()) + + (self.7.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + (0 * 6 + 1) + + (0 * 7 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[4]; + let key = E::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[5]; + let key = F::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[6]; + let key = G::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[7]; + let key = H::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + }; + } + mod storage_type { + use super::storage_address::{StorageAddress, Yes}; + use super::utils::strip_storage_addess_root_bytes; + use super::StorageKey; + use crate::{ + backend::{BackendExt, BlockRef}, + client::OnlineClientT, error::{Error, MetadataError, StorageAddressError}, + metadata::{DecodeWithMetadata, Metadata}, + Config, + }; + use codec::Decode; + use derivative::Derivative; + use futures::StreamExt; + use scale_info::TypeDef; + use std::{future::Future, marker::PhantomData}; + use subxt_metadata::StorageHasher; + use subxt_metadata::{PalletMetadata, StorageEntryMetadata, StorageEntryType}; + /// This is returned from a couple of storage functions. + pub use crate::backend::StreamOfResults; + /// Query the runtime storage. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct Storage { + client: Client, + block_ref: BlockRef, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Storage + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + Storage { + client: ref __arg_0, + block_ref: ref __arg_1, + _marker: ref __arg_2, + } => { + Storage { + client: (*__arg_0).clone(), + block_ref: (*__arg_1).clone(), + _marker: (*__arg_2).clone(), + } + } + } + } + } + impl Storage { + /// Create a new [`Storage`] + pub(crate) fn new(client: Client, block_ref: BlockRef) -> Self { + Self { + client, + block_ref, + _marker: PhantomData, + } + } + } + impl Storage + where + T: Config, + Client: OnlineClientT, + { + /// Fetch the raw encoded value at the key given. + pub fn fetch_raw( + &self, + key: impl Into>, + ) -> impl Future>, Error>> + 'static { + let client = self.client.clone(); + let key = key.into(); + let block_ref = self.block_ref.clone(); + async move { + let data = client + .backend() + .storage_fetch_value(key, block_ref.hash()) + .await?; + Ok(data) + } + } + /// Stream all of the raw keys underneath the key given + pub fn fetch_raw_keys( + &self, + key: impl Into>, + ) -> impl Future< + Output = Result>, Error>, + > + 'static { + let client = self.client.clone(); + let block_hash = self.block_ref.hash(); + let key = key.into(); + async move { + let keys = client + .backend() + .storage_fetch_descendant_keys(key, block_hash) + .await?; + Ok(keys) + } + } + /// Fetch a decoded value from storage at a given address. + /// + /// # Example + /// + /// ```no_run + /// use subxt::{ PolkadotConfig, OnlineClient }; + /// + /// #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] + /// pub mod polkadot {} + /// + /// # #[tokio::main] + /// # async fn main() { + /// let api = OnlineClient::::new().await.unwrap(); + /// + /// // Address to a storage entry we'd like to access. + /// let address = polkadot::storage().xcm_pallet().queries(&12345); + /// + /// // Fetch just the keys, returning up to 10 keys. + /// let value = api + /// .storage() + /// .at_latest() + /// .await + /// .unwrap() + /// .fetch(&address) + /// .await + /// .unwrap(); + /// + /// println!("Value: {:?}", value); + /// # } + /// ``` + pub fn fetch<'address, Address>( + &self, + address: &'address Address, + ) -> impl Future, Error>> + 'address + where + Address: StorageAddress + 'address, + { + let client = self.clone(); + async move { + let metadata = client.client.metadata(); + let (pallet, entry) = lookup_entry_details( + address.pallet_name(), + address.entry_name(), + &metadata, + )?; + validate_storage_address(address, pallet)?; + let lookup_bytes = super::utils::storage_address_bytes( + address, + &metadata, + )?; + if let Some(data) = client.fetch_raw(lookup_bytes).await? { + let val = decode_storage_with_metadata::< + Address::Target, + >(&mut &*data, &metadata, entry)?; + Ok(Some(val)) + } else { + Ok(None) + } + } + } + /// Fetch a StorageKey that has a default value with an optional block hash. + pub fn fetch_or_default<'address, Address>( + &self, + address: &'address Address, + ) -> impl Future> + 'address + where + Address: StorageAddress + + 'address, + { + let client = self.clone(); + async move { + let pallet_name = address.pallet_name(); + let entry_name = address.entry_name(); + if let Some(data) = client.fetch(address).await? { + Ok(data) + } else { + let metadata = client.client.metadata(); + let (_pallet_metadata, storage_entry) = lookup_entry_details( + pallet_name, + entry_name, + &metadata, + )?; + let return_ty_id = return_type_from_storage_entry_type( + storage_entry.entry_type(), + ); + let bytes = &mut storage_entry.default_bytes(); + let val = Address::Target::decode_with_metadata( + bytes, + return_ty_id, + &metadata, + )?; + Ok(val) + } + } + } + /// Returns an iterator of key value pairs. + /// + /// ```no_run + /// use subxt::{ PolkadotConfig, OnlineClient }; + /// + /// #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] + /// pub mod polkadot {} + /// + /// # #[tokio::main] + /// # async fn main() { + /// let api = OnlineClient::::new().await.unwrap(); + /// + /// // Address to the root of a storage entry that we'd like to iterate over. + /// let address = polkadot::storage().xcm_pallet().version_notifiers_iter(); + /// + /// // Iterate over keys and values at that address. + /// let mut iter = api + /// .storage() + /// .at_latest() + /// .await + /// .unwrap() + /// .iter(address) + /// .await + /// .unwrap(); + /// + /// while let Some(Ok(kv)) = iter.next().await { + /// println!("Key bytes: 0x{}", hex::encode(&kv.key_bytes)); + /// println!("Value: {}", kv.value); + /// } + /// # } + /// ``` + pub fn iter
( + &self, + address: Address, + ) -> impl Future< + Output = Result>, Error>, + > + 'static + where + Address: StorageAddress + 'static, + Address::Keys: 'static + Sized, + { + let client = self.client.clone(); + let block_ref = self.block_ref.clone(); + async move { + let metadata = client.metadata(); + let (pallet, entry) = lookup_entry_details( + address.pallet_name(), + address.entry_name(), + &metadata, + )?; + validate_storage_address(&address, pallet)?; + let entry = entry.entry_type(); + let return_type_id = entry.value_ty(); + let hasher_type_id_pairs = storage_hasher_type_id_pairs( + entry, + &metadata, + )?; + let address_bytes = super::utils::storage_address_bytes( + &address, + &metadata, + )?; + let s = client + .backend() + .storage_fetch_descendant_values(address_bytes, block_ref.hash()) + .await? + .map(move |kv| { + let kv = match kv { + Ok(kv) => kv, + Err(e) => return Err(e), + }; + let value = Address::Target::decode_with_metadata( + &mut &*kv.value, + return_type_id, + &metadata, + )?; + let key_bytes = kv.key; + let cursor = &mut &key_bytes[..]; + strip_storage_addess_root_bytes(cursor)?; + let keys = ::decode_from_bytes( + cursor, + &hasher_type_id_pairs, + &metadata, + )?; + Ok(StorageKeyValuePair::
{ + keys, + key_bytes, + value, + }) + }); + let s = StreamOfResults::new(Box::pin(s)); + Ok(s) + } + } + /// The storage version of a pallet. + /// The storage version refers to the `frame_support::traits::Metadata::StorageVersion` type. + pub async fn storage_version( + &self, + pallet_name: impl AsRef, + ) -> Result { + self.client + .metadata() + .pallet_by_name(pallet_name.as_ref()) + .ok_or_else(|| MetadataError::PalletNameNotFound( + pallet_name.as_ref().into(), + ))?; + pub const STORAGE_VERSION_STORAGE_KEY_POSTFIX: &[u8] = b":__STORAGE_VERSION__:"; + let mut key_bytes: Vec = ::alloc::vec::Vec::new(); + key_bytes + .extend(&sp_core_hashing::twox_128(pallet_name.as_ref().as_bytes())); + key_bytes + .extend( + &sp_core_hashing::twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX), + ); + let storage_version_bytes = self + .fetch_raw(key_bytes) + .await? + .ok_or_else(|| { + { + let res = ::alloc::fmt::format( + format_args!( + "Unexpected: entry for storage version in pallet \"{0}\" not found", + pallet_name.as_ref() + ), + ); + res + } + })?; + u16::decode(&mut &storage_version_bytes[..]).map_err(Into::into) + } + /// Fetch the runtime WASM code. + pub async fn runtime_wasm_code(&self) -> Result, Error> { + const CODE: &str = ":code"; + self.fetch_raw(CODE.as_bytes()) + .await? + .ok_or_else(|| { + { + let res = ::alloc::fmt::format( + format_args!( + "Unexpected: entry for well known key \"{0}\" not found", + CODE + ), + ); + res + } + .into() + }) + } + } + pub(crate) fn storage_hasher_type_id_pairs( + entry: &StorageEntryType, + metadata: &Metadata, + ) -> Result, Error> { + match entry { + StorageEntryType::Plain(_) => Ok(::alloc::vec::Vec::new()), + StorageEntryType::Map { hashers, key_ty, .. } => { + let ty = metadata + .types() + .resolve(*key_ty) + .ok_or(MetadataError::TypeNotFound(*key_ty))?; + match &ty.type_def { + TypeDef::Tuple(tuple) => { + if hashers.len() < tuple.fields.len() { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: tuple.fields.len(), + } + .into(), + ); + } + let pairs: Vec<(StorageHasher, u32)> = tuple + .fields + .iter() + .zip(hashers.iter()) + .map(|(e, h)| (*h, e.id)) + .collect(); + Ok(pairs) + } + _other => { + if hashers.is_empty() { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into(), + ); + } + Ok( + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([(hashers[0], *key_ty)]), + ), + ) + } + } + } + } + } + /// A pair of keys and values together with all the bytes that make up the storage address. + /// `keys` is `None` if non-concat hashers are used. In this case the keys could not be extracted back from the key_bytes. + pub struct StorageKeyValuePair { + /// The bytes that make up the address of the storage entry. + pub key_bytes: Vec, + /// The keys that can be used to construct the address of this storage entry. + pub keys: T::Keys, + /// The value of the storage entry. + pub value: T::Target, + } + #[automatically_derived] + impl ::core::clone::Clone + for StorageKeyValuePair + where + T::Keys: ::core::clone::Clone, + T::Target: ::core::clone::Clone, + { + #[inline] + fn clone(&self) -> StorageKeyValuePair { + StorageKeyValuePair { + key_bytes: ::core::clone::Clone::clone(&self.key_bytes), + keys: ::core::clone::Clone::clone(&self.keys), + value: ::core::clone::Clone::clone(&self.value), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug + for StorageKeyValuePair + where + T::Keys: ::core::fmt::Debug, + T::Target: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "StorageKeyValuePair", + "key_bytes", + &self.key_bytes, + "keys", + &self.keys, + "value", + &&self.value, + ) + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for StorageKeyValuePair + where + T::Keys: ::core::cmp::Eq, + T::Target: ::core::cmp::Eq, + { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for StorageKeyValuePair {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for StorageKeyValuePair + where + T::Keys: ::core::cmp::PartialEq, + T::Target: ::core::cmp::PartialEq, + { + #[inline] + fn eq(&self, other: &StorageKeyValuePair) -> bool { + self.key_bytes == other.key_bytes && self.keys == other.keys + && self.value == other.value + } + } + #[automatically_derived] + impl ::core::cmp::Ord + for StorageKeyValuePair + where + T::Keys: ::core::cmp::Ord, + T::Target: ::core::cmp::Ord, + { + #[inline] + fn cmp(&self, other: &StorageKeyValuePair) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp(&self.key_bytes, &other.key_bytes) { + ::core::cmp::Ordering::Equal => { + match ::core::cmp::Ord::cmp(&self.keys, &other.keys) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp(&self.value, &other.value) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd + for StorageKeyValuePair + where + T::Keys: ::core::cmp::PartialOrd, + T::Target: ::core::cmp::PartialOrd, + { + #[inline] + fn partial_cmp( + &self, + other: &StorageKeyValuePair, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp( + &self.key_bytes, + &other.key_bytes, + ) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + match ::core::cmp::PartialOrd::partial_cmp( + &self.keys, + &other.keys, + ) { + ::core::option::Option::Some( + ::core::cmp::Ordering::Equal, + ) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.value, + &other.value, + ) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + /// Validate a storage address against the metadata. + pub(crate) fn validate_storage_address( + address: &Address, + pallet: PalletMetadata<'_>, + ) -> Result<(), Error> { + if let Some(hash) = address.validation_hash() { + validate_storage(pallet, address.entry_name(), hash)?; + } + Ok(()) + } + /// Return details about the given storage entry. + fn lookup_entry_details<'a>( + pallet_name: &str, + entry_name: &str, + metadata: &'a Metadata, + ) -> Result<(PalletMetadata<'a>, &'a StorageEntryMetadata), Error> { + let pallet_metadata = metadata.pallet_by_name_err(pallet_name)?; + let storage_metadata = pallet_metadata + .storage() + .ok_or_else(|| MetadataError::StorageNotFoundInPallet( + pallet_name.to_owned(), + ))?; + let storage_entry = storage_metadata + .entry_by_name(entry_name) + .ok_or_else(|| MetadataError::StorageEntryNotFound( + entry_name.to_owned(), + ))?; + Ok((pallet_metadata, storage_entry)) + } + /// Validate a storage entry against the metadata. + fn validate_storage( + pallet: PalletMetadata<'_>, + storage_name: &str, + hash: [u8; 32], + ) -> Result<(), Error> { + let Some(expected_hash) = pallet.storage_hash(storage_name) else { + return Err(MetadataError::IncompatibleCodegen.into()); + }; + if expected_hash != hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + Ok(()) + } + /// Fetch the return type out of a [`StorageEntryType`]. + fn return_type_from_storage_entry_type(entry: &StorageEntryType) -> u32 { + match entry { + StorageEntryType::Plain(ty) => *ty, + StorageEntryType::Map { value_ty, .. } => *value_ty, + } + } + /// Given some bytes, a pallet and storage name, decode the response. + fn decode_storage_with_metadata( + bytes: &mut &[u8], + metadata: &Metadata, + storage_metadata: &StorageEntryMetadata, + ) -> Result { + let ty = storage_metadata.entry_type(); + let return_ty = return_type_from_storage_entry_type(ty); + let val = T::decode_with_metadata(bytes, return_ty, metadata)?; + Ok(val) + } + } + pub mod utils { + //! these utility methods complement the [`StorageAddress`] trait, but + //! aren't things that should ever be overridden, and so don't exist on + //! the trait itself. + use subxt_metadata::StorageHasher; + use super::StorageAddress; + use crate::{ + error::{Error, StorageAddressError}, + metadata::Metadata, + }; + /// Return the root of a given [`StorageAddress`]: hash the pallet name and entry name + /// and append those bytes to the output. + pub(crate) fn write_storage_address_root_bytes( + addr: &Address, + out: &mut Vec, + ) { + out.extend(sp_core_hashing::twox_128(addr.pallet_name().as_bytes())); + out.extend(sp_core_hashing::twox_128(addr.entry_name().as_bytes())); + } + /// Outputs the [`storage_address_root_bytes`] as well as any additional bytes that represent + /// a lookup in a storage map at that location. + pub(crate) fn storage_address_bytes( + addr: &Address, + metadata: &Metadata, + ) -> Result, Error> { + let mut bytes = Vec::new(); + write_storage_address_root_bytes(addr, &mut bytes); + addr.append_entry_bytes(metadata, &mut bytes)?; + Ok(bytes) + } + /// Outputs a vector containing the bytes written by [`write_storage_address_root_bytes`]. + pub(crate) fn storage_address_root_bytes( + addr: &Address, + ) -> Vec { + let mut bytes = Vec::new(); + write_storage_address_root_bytes(addr, &mut bytes); + bytes + } + /// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. + pub(crate) fn strip_storage_addess_root_bytes( + address_bytes: &mut &[u8], + ) -> Result<(), StorageAddressError> { + if address_bytes.len() >= 16 { + *address_bytes = &address_bytes[16..]; + Ok(()) + } else { + Err(StorageAddressError::UnexpectedAddressBytes) + } + } + /// Strips the first few bytes off a hash to possibly skip to the plan key value, + /// if [`hash_contains_unhashed_value()`] for this StorageHasher. + /// + /// Returns `Err(..)` if there are not enough bytes. + /// Returns `Ok(())` otherwise + pub fn strip_storage_hash_bytes( + hash: &mut &[u8], + hasher: &StorageHasher, + ) -> Result<(), StorageAddressError> { + let bytes_to_strip = match hasher { + StorageHasher::Blake2_128Concat => 16, + StorageHasher::Twox64Concat => 8, + StorageHasher::Blake2_128 => 16, + StorageHasher::Blake2_256 => 32, + StorageHasher::Twox128 => 16, + StorageHasher::Twox256 => 32, + StorageHasher::Identity => 0, + }; + if hash.len() < bytes_to_strip { + return Err(StorageAddressError::UnexpectedAddressBytes); + } + *hash = &hash[bytes_to_strip..]; + Ok(()) + } + /// This value is contained within the hash for concat-stle hashers + /// ([`StorageHasher::Identity`] or [`StorageHasher::Identity`]) and the + /// identity hash function ([`StorageHasher::Identity`]). + pub fn hash_contains_unhashed_value(hasher: &StorageHasher) -> bool { + match hasher { + StorageHasher::Blake2_128Concat + | StorageHasher::Twox64Concat + | StorageHasher::Identity => true, + _ => false, + } + } + } + pub use storage_client::StorageClient; + pub use storage_type::{Storage, StorageKeyValuePair}; + /// Types representing an address which describes where a storage + /// entry lives and how to properly decode it. + pub mod address { + pub use super::storage_address::{ + dynamic, Address, DynamicAddress, StaticStorageKey, StorageAddress, Yes, + }; + } + pub use storage_key::StorageKey; + pub use storage_address::{dynamic, Address, DynamicAddress, StorageAddress}; +} +pub mod tx { + //! Create and submit extrinsics. + //! + //! An extrinsic is submitted with an "signed extra" and "additional" parameters, which can be + //! different for each chain. The trait [`crate::config::ExtrinsicParams`] determines exactly which + //! additional and signed extra parameters are used when constructing an extrinsic, and is a part + //! of the chain configuration (see [`crate::config::Config`]). + use crate::macros::cfg_substrate_compat; + mod signer { + //! A library to **sub**mit e**xt**rinsics to a + //! [substrate](https://github.com/paritytech/substrate) node via RPC. + use crate::macros::cfg_substrate_compat; + use crate::Config; + /// Signing transactions requires a [`Signer`]. This is responsible for + /// providing the "from" account that the transaction is being signed by, + /// as well as actually signing a SCALE encoded payload. + pub trait Signer { + /// Return the "from" account ID. + fn account_id(&self) -> T::AccountId; + /// Return the "from" address. + fn address(&self) -> T::Address; + /// Takes a signer payload for an extrinsic, and returns a signature based on it. + /// + /// Some signers may fail, for instance because the hardware on which the keys are located has + /// refused the operation. + fn sign(&self, signer_payload: &[u8]) -> T::Signature; + } + } + mod tx_client { + use std::borrow::Cow; + use crate::{ + backend::{BackendExt, BlockRef, TransactionStatus}, + client::{OfflineClientT, OnlineClientT}, + config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, Hasher}, + error::{Error, MetadataError}, + tx::{Signer as SignerT, TxPayload, TxProgress}, + utils::{Encoded, PhantomDataSendSync}, + }; + use codec::{Compact, Decode, Encode}; + use derivative::Derivative; + use sp_core_hashing::blake2_256; + /// A client for working with transactions. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct TxClient { + client: Client, + _marker: PhantomDataSendSync, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for TxClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + TxClient { client: ref __arg_0, _marker: ref __arg_1 } => { + TxClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl TxClient { + /// Create a new [`TxClient`] + pub fn new(client: Client) -> Self { + Self { + client, + _marker: PhantomDataSendSync::new(), + } + } + } + impl> TxClient { + /// Run the validation logic against some extrinsic you'd like to submit. Returns `Ok(())` + /// if the call is valid (or if it's not possible to check since the call has no validation hash). + /// Return an error if the call was not valid or something went wrong trying to validate it (ie + /// the pallet or call in question do not exist at all). + pub fn validate(&self, call: &Call) -> Result<(), Error> + where + Call: TxPayload, + { + if let Some(details) = call.validation_details() { + let expected_hash = self + .client + .metadata() + .pallet_by_name_err(details.pallet_name)? + .call_hash(details.call_name) + .ok_or_else(|| MetadataError::CallNameNotFound( + details.call_name.to_owned(), + ))?; + if details.hash != expected_hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + } + Ok(()) + } + /// Return the SCALE encoded bytes representing the call data of the transaction. + pub fn call_data(&self, call: &Call) -> Result, Error> + where + Call: TxPayload, + { + let metadata = self.client.metadata(); + let mut bytes = Vec::new(); + call.encode_call_data_to(&metadata, &mut bytes)?; + Ok(bytes) + } + /// Creates an unsigned extrinsic without submitting it. + pub fn create_unsigned( + &self, + call: &Call, + ) -> Result, Error> + where + Call: TxPayload, + { + self.validate(call)?; + let extrinsic = { + let mut encoded_inner = Vec::new(); + 4u8.encode_to(&mut encoded_inner); + call.encode_call_data_to( + &self.client.metadata(), + &mut encoded_inner, + )?; + let len = Compact( + u32::try_from(encoded_inner.len()) + .expect("extrinsic size expected to be <4GB"), + ); + let mut encoded = Vec::new(); + len.encode_to(&mut encoded); + encoded.extend(encoded_inner); + encoded + }; + Ok(SubmittableExtrinsic::from_bytes(self.client.clone(), extrinsic)) + } + /// Create a partial extrinsic. + pub fn create_partial_signed_with_nonce( + &self, + call: &Call, + account_nonce: u64, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + { + self.validate(call)?; + let call_data = self.call_data(call)?; + let additional_and_extra_params = >::new(account_nonce, self.client.clone(), other_params)?; + Ok(PartialExtrinsic { + client: self.client.clone(), + call_data, + additional_and_extra_params, + }) + } + /// Creates a signed extrinsic without submitting it. + pub fn create_signed_with_nonce( + &self, + call: &Call, + signer: &Signer, + account_nonce: u64, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + Signer: SignerT, + { + self.validate(call)?; + let partial_signed = self + .create_partial_signed_with_nonce( + call, + account_nonce, + other_params, + )?; + Ok(partial_signed.sign(signer)) + } + } + impl TxClient + where + T: Config, + C: OnlineClientT, + { + /// Get the account nonce for a given account ID. + pub async fn account_nonce( + &self, + account_id: &T::AccountId, + ) -> Result { + let block_ref = self + .client + .backend() + .latest_finalized_block_ref() + .await?; + crate::blocks::get_account_nonce( + &self.client, + account_id, + block_ref.hash(), + ) + .await + } + /// Creates a partial signed extrinsic, without submitting it. + pub async fn create_partial_signed( + &self, + call: &Call, + account_id: &T::AccountId, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + { + let account_nonce = self.account_nonce(account_id).await?; + self.create_partial_signed_with_nonce(call, account_nonce, other_params) + } + /// Creates a signed extrinsic, without submitting it. + pub async fn create_signed( + &self, + call: &Call, + signer: &Signer, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + Signer: SignerT, + { + let account_nonce = self.account_nonce(&signer.account_id()).await?; + self.create_signed_with_nonce(call, signer, account_nonce, other_params) + } + /// Creates and signs an extrinsic and submits it to the chain. Passes default parameters + /// to construct the "signed extra" and "additional" payloads needed by the extrinsic. + /// + /// Returns a [`TxProgress`], which can be used to track the status of the transaction + /// and obtain details about it, once it has made it into a block. + pub async fn sign_and_submit_then_watch_default( + &self, + call: &Call, + signer: &Signer, + ) -> Result, Error> + where + Call: TxPayload, + Signer: SignerT, + >::OtherParams: Default, + { + self.sign_and_submit_then_watch(call, signer, Default::default()).await + } + /// Creates and signs an extrinsic and submits it to the chain. + /// + /// Returns a [`TxProgress`], which can be used to track the status of the transaction + /// and obtain details about it, once it has made it into a block. + pub async fn sign_and_submit_then_watch( + &self, + call: &Call, + signer: &Signer, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + Signer: SignerT, + { + self.create_signed(call, signer, other_params) + .await? + .submit_and_watch() + .await + } + /// Creates and signs an extrinsic and submits to the chain for block inclusion. Passes + /// default parameters to construct the "signed extra" and "additional" payloads needed + /// by the extrinsic. + /// + /// Returns `Ok` with the extrinsic hash if it is valid extrinsic. + /// + /// # Note + /// + /// Success does not mean the extrinsic has been included in the block, just that it is valid + /// and has been included in the transaction pool. + pub async fn sign_and_submit_default( + &self, + call: &Call, + signer: &Signer, + ) -> Result + where + Call: TxPayload, + Signer: SignerT, + >::OtherParams: Default, + { + self.sign_and_submit(call, signer, Default::default()).await + } + /// Creates and signs an extrinsic and submits to the chain for block inclusion. + /// + /// Returns `Ok` with the extrinsic hash if it is valid extrinsic. + /// + /// # Note + /// + /// Success does not mean the extrinsic has been included in the block, just that it is valid + /// and has been included in the transaction pool. + pub async fn sign_and_submit( + &self, + call: &Call, + signer: &Signer, + other_params: >::OtherParams, + ) -> Result + where + Call: TxPayload, + Signer: SignerT, + { + self.create_signed(call, signer, other_params).await?.submit().await + } + } + /// This payload contains the information needed to produce an extrinsic. + pub struct PartialExtrinsic { + client: C, + call_data: Vec, + additional_and_extra_params: T::ExtrinsicParams, + } + impl PartialExtrinsic + where + T: Config, + C: OfflineClientT, + { + fn with_signer_payload(&self, f: F) -> R + where + F: for<'a> FnOnce(Cow<'a, [u8]>) -> R, + { + let mut bytes = self.call_data.clone(); + self.additional_and_extra_params.encode_extra_to(&mut bytes); + self.additional_and_extra_params.encode_additional_to(&mut bytes); + if bytes.len() > 256 { + f(Cow::Borrowed(blake2_256(&bytes).as_ref())) + } else { + f(Cow::Owned(bytes)) + } + } + /// Return the signer payload for this extrinsic. These are the bytes that must + /// be signed in order to produce a valid signature for the extrinsic. + pub fn signer_payload(&self) -> Vec { + self.with_signer_payload(|bytes| bytes.to_vec()) + } + /// Return the bytes representing the call data for this partially constructed + /// extrinsic. + pub fn call_data(&self) -> &[u8] { + &self.call_data + } + /// Convert this [`PartialExtrinsic`] into a [`SubmittableExtrinsic`], ready to submit. + /// The provided `signer` is responsible for providing the "from" address for the transaction, + /// as well as providing a signature to attach to it. + pub fn sign(&self, signer: &Signer) -> SubmittableExtrinsic + where + Signer: SignerT, + { + let signature = self.with_signer_payload(|bytes| signer.sign(&bytes)); + self.sign_with_address_and_signature(&signer.address(), &signature) + } + /// Convert this [`PartialExtrinsic`] into a [`SubmittableExtrinsic`], ready to submit. + /// An address, and something representing a signature that can be SCALE encoded, are both + /// needed in order to construct it. If you have a `Signer` to hand, you can use + /// [`PartialExtrinsic::sign()`] instead. + pub fn sign_with_address_and_signature( + &self, + address: &T::Address, + signature: &T::Signature, + ) -> SubmittableExtrinsic { + let extrinsic = { + let mut encoded_inner = Vec::new(); + (0b10000000 + 4u8).encode_to(&mut encoded_inner); + address.encode_to(&mut encoded_inner); + signature.encode_to(&mut encoded_inner); + self.additional_and_extra_params.encode_extra_to(&mut encoded_inner); + encoded_inner.extend(&self.call_data); + let len = Compact( + u32::try_from(encoded_inner.len()) + .expect("extrinsic size expected to be <4GB"), + ); + let mut encoded = Vec::new(); + len.encode_to(&mut encoded); + encoded.extend(encoded_inner); + encoded + }; + SubmittableExtrinsic::from_bytes(self.client.clone(), extrinsic) + } + } + /// This represents an extrinsic that has been signed and is ready to submit. + pub struct SubmittableExtrinsic { + client: C, + encoded: Encoded, + marker: std::marker::PhantomData, + } + impl SubmittableExtrinsic + where + T: Config, + C: OfflineClientT, + { + /// Create a [`SubmittableExtrinsic`] from some already-signed and prepared + /// extrinsic bytes, and some client (anything implementing [`OfflineClientT`] + /// or [`OnlineClientT`]). + /// + /// Prefer to use [`TxClient`] to create and sign extrinsics. This is simply + /// exposed in case you want to skip this process and submit something you've + /// already created. + pub fn from_bytes(client: C, tx_bytes: Vec) -> Self { + Self { + client, + encoded: Encoded(tx_bytes), + marker: std::marker::PhantomData, + } + } + /// Calculate and return the hash of the extrinsic, based on the configured hasher. + pub fn hash(&self) -> T::Hash { + T::Hasher::hash_of(&self.encoded) + } + /// Returns the SCALE encoded extrinsic bytes. + pub fn encoded(&self) -> &[u8] { + &self.encoded.0 + } + /// Consumes [`SubmittableExtrinsic`] and returns the SCALE encoded + /// extrinsic bytes. + pub fn into_encoded(self) -> Vec { + self.encoded.0 + } + } + impl SubmittableExtrinsic + where + T: Config, + C: OnlineClientT, + { + /// Submits the extrinsic to the chain. + /// + /// Returns a [`TxProgress`], which can be used to track the status of the transaction + /// and obtain details about it, once it has made it into a block. + pub async fn submit_and_watch(&self) -> Result, Error> { + let ext_hash = self.hash(); + let sub = self + .client + .backend() + .submit_transaction(&self.encoded.0) + .await?; + Ok(TxProgress::new(sub, self.client.clone(), ext_hash)) + } + /// Submits the extrinsic to the chain for block inclusion. + /// + /// It's usually better to call `submit_and_watch` to get an idea of the progress of the + /// submission and whether it's eventually successful or not. This call does not guarantee + /// success, and is just sending the transaction to the chain. + pub async fn submit(&self) -> Result { + let ext_hash = self.hash(); + let mut sub = self + .client + .backend() + .submit_transaction(&self.encoded.0) + .await?; + match sub.next().await { + Some(Ok(status)) => { + match status { + TransactionStatus::Validated + | TransactionStatus::Broadcasted { .. } + | TransactionStatus::InBestBlock { .. } + | TransactionStatus::NoLongerInBestBlock + | TransactionStatus::InFinalizedBlock { .. } => Ok(ext_hash), + TransactionStatus::Error { message } => { + Err( + Error::Other({ + let res = ::alloc::fmt::format( + format_args!("Transaction error: {0}", message), + ); + res + }), + ) + } + TransactionStatus::Invalid { message } => { + Err( + Error::Other({ + let res = ::alloc::fmt::format( + format_args!("Transaction invalid: {0}", message), + ); + res + }), + ) + } + TransactionStatus::Dropped { message } => { + Err( + Error::Other({ + let res = ::alloc::fmt::format( + format_args!("Transaction dropped: {0}", message), + ); + res + }), + ) + } + } + } + Some(Err(e)) => Err(e), + None => { + Err( + Error::Other( + "Transaction broadcast was unsuccessful; stream terminated early" + .into(), + ), + ) + } + } + } + /// Validate a transaction by submitting it to the relevant Runtime API. A transaction that is + /// valid can be added to a block, but may still end up in an error state. + /// + /// Returns `Ok` with a [`ValidationResult`], which is the result of attempting to dry run the extrinsic. + pub async fn validate(&self) -> Result { + let latest_block_ref = self + .client + .backend() + .latest_finalized_block_ref() + .await?; + self.validate_at(latest_block_ref).await + } + /// Validate a transaction by submitting it to the relevant Runtime API. A transaction that is + /// valid can be added to a block, but may still end up in an error state. + /// + /// Returns `Ok` with a [`ValidationResult`], which is the result of attempting to dry run the extrinsic. + pub async fn validate_at( + &self, + at: impl Into>, + ) -> Result { + let block_hash = at.into().hash(); + let mut params = Vec::with_capacity(8 + self.encoded.0.len() + 8); + 2u8.encode_to(&mut params); + params.extend(self.encoded().iter()); + block_hash.encode_to(&mut params); + let res: Vec = self + .client + .backend() + .call( + "TaggedTransactionQueue_validate_transaction", + Some(¶ms), + block_hash, + ) + .await?; + ValidationResult::try_from_bytes(res) + } + /// This returns an estimate for what the extrinsic is expected to cost to execute, less any tips. + /// The actual amount paid can vary from block to block based on node traffic and other factors. + pub async fn partial_fee_estimate(&self) -> Result { + let mut params = self.encoded().to_vec(); + (self.encoded().len() as u32).encode_to(&mut params); + let latest_block_ref = self + .client + .backend() + .latest_finalized_block_ref() + .await?; + let (_, _, _, partial_fee) = self + .client + .backend() + .call_decoding::< + (Compact, Compact, u8, u128), + >( + "TransactionPaymentApi_query_info", + Some(¶ms), + latest_block_ref.hash(), + ) + .await?; + Ok(partial_fee) + } + } + impl ValidationResult { + #[allow(clippy::get_first)] + fn try_from_bytes(bytes: Vec) -> Result { + if bytes.get(0) == Some(&0) { + let res = TransactionValid::decode(&mut &bytes[1..])?; + Ok(ValidationResult::Valid(res)) + } else if bytes.get(0) == Some(&1) && bytes.get(1) == Some(&0) { + let res = TransactionInvalid::decode(&mut &bytes[2..])?; + Ok(ValidationResult::Invalid(res)) + } else if bytes.get(0) == Some(&1) && bytes.get(1) == Some(&1) { + let res = TransactionUnknown::decode(&mut &bytes[2..])?; + Ok(ValidationResult::Unknown(res)) + } else { + Err(crate::Error::Unknown(bytes)) + } + } + } + /// The result of performing [`SubmittableExtrinsic::validate()`]. + pub enum ValidationResult { + /// The transaction is valid + Valid(TransactionValid), + /// The transaction is invalid + Invalid(TransactionInvalid), + /// Unable to validate the transaction + Unknown(TransactionUnknown), + } + #[automatically_derived] + impl ::core::clone::Clone for ValidationResult { + #[inline] + fn clone(&self) -> ValidationResult { + match self { + ValidationResult::Valid(__self_0) => { + ValidationResult::Valid(::core::clone::Clone::clone(__self_0)) + } + ValidationResult::Invalid(__self_0) => { + ValidationResult::Invalid(::core::clone::Clone::clone(__self_0)) + } + ValidationResult::Unknown(__self_0) => { + ValidationResult::Unknown(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ValidationResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ValidationResult::Valid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Valid", + &__self_0, + ) + } + ValidationResult::Invalid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Invalid", + &__self_0, + ) + } + ValidationResult::Unknown(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Unknown", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ValidationResult {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ValidationResult { + #[inline] + fn eq(&self, other: &ValidationResult) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + ValidationResult::Valid(__self_0), + ValidationResult::Valid(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + ValidationResult::Invalid(__self_0), + ValidationResult::Invalid(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + ValidationResult::Unknown(__self_0), + ValidationResult::Unknown(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + impl ValidationResult { + /// Is the transaction valid. + pub fn is_valid(&self) -> bool { + match self { + ValidationResult::Valid(_) => true, + _ => false, + } + } + } + /// Transaction is valid; here is some more information about it. + pub struct TransactionValid { + /// Priority of the transaction. + /// + /// Priority determines the ordering of two transactions that have all + /// their dependencies (required tags) satisfied. + pub priority: u64, + /// Transaction dependencies + /// + /// A non-empty list signifies that some other transactions which provide + /// given tags are required to be included before that one. + pub requires: Vec>, + /// Provided tags + /// + /// A list of tags this transaction provides. Successfully importing the transaction + /// will enable other transactions that depend on (require) those tags to be included as well. + /// Provided and required tags allow Substrate to build a dependency graph of transactions + /// and import them in the right (linear) order. + pub provides: Vec>, + /// Transaction longevity + /// + /// Longevity describes minimum number of blocks the validity is correct. + /// After this period transaction should be removed from the pool or revalidated. + pub longevity: u64, + /// A flag indicating if the transaction should be propagated to other peers. + /// + /// By setting `false` here the transaction will still be considered for + /// including in blocks that are authored on the current node, but will + /// never be sent to other peers. + pub propagate: bool, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for TransactionValid { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(TransactionValid { + priority: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::priority`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + requires: { + let __codec_res_edqy = , + > as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::requires`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + provides: { + let __codec_res_edqy = , + > as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::provides`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + longevity: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::longevity`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + propagate: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::propagate`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for TransactionValid { + #[inline] + fn clone(&self) -> TransactionValid { + TransactionValid { + priority: ::core::clone::Clone::clone(&self.priority), + requires: ::core::clone::Clone::clone(&self.requires), + provides: ::core::clone::Clone::clone(&self.provides), + longevity: ::core::clone::Clone::clone(&self.longevity), + propagate: ::core::clone::Clone::clone(&self.propagate), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionValid { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "TransactionValid", + "priority", + &self.priority, + "requires", + &self.requires, + "provides", + &self.provides, + "longevity", + &self.longevity, + "propagate", + &&self.propagate, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionValid {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionValid { + #[inline] + fn eq(&self, other: &TransactionValid) -> bool { + self.priority == other.priority && self.requires == other.requires + && self.provides == other.provides + && self.longevity == other.longevity + && self.propagate == other.propagate + } + } + /// The runtime was unable to validate the transaction. + pub enum TransactionUnknown { + /// Could not lookup some information that is required to validate the transaction. + CannotLookup, + /// No validator found for the given unsigned transaction. + NoUnsignedValidator, + /// Any other custom unknown validity that is not covered by this enum. + Custom(u8), + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for TransactionUnknown { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `TransactionUnknown`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionUnknown::CannotLookup) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionUnknown::NoUnsignedValidator, + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionUnknown::Custom({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionUnknown::Custom.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `TransactionUnknown`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for TransactionUnknown { + #[inline] + fn clone(&self) -> TransactionUnknown { + match self { + TransactionUnknown::CannotLookup => TransactionUnknown::CannotLookup, + TransactionUnknown::NoUnsignedValidator => { + TransactionUnknown::NoUnsignedValidator + } + TransactionUnknown::Custom(__self_0) => { + TransactionUnknown::Custom(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionUnknown { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionUnknown::CannotLookup => { + ::core::fmt::Formatter::write_str(f, "CannotLookup") + } + TransactionUnknown::NoUnsignedValidator => { + ::core::fmt::Formatter::write_str(f, "NoUnsignedValidator") + } + TransactionUnknown::Custom(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Custom", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionUnknown {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionUnknown { + #[inline] + fn eq(&self, other: &TransactionUnknown) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionUnknown::Custom(__self_0), + TransactionUnknown::Custom(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + /// The transaction is invalid. + pub enum TransactionInvalid { + /// The call of the transaction is not expected. + Call, + /// General error to do with the inability to pay some fees (e.g. account balance too low). + Payment, + /// General error to do with the transaction not yet being valid (e.g. nonce too high). + Future, + /// General error to do with the transaction being outdated (e.g. nonce too low). + Stale, + /// General error to do with the transaction's proofs (e.g. signature). + /// + /// # Possible causes + /// + /// When using a signed extension that provides additional data for signing, it is required + /// that the signing and the verifying side use the same additional data. Additional + /// data will only be used to generate the signature, but will not be part of the transaction + /// itself. As the verifying side does not know which additional data was used while signing + /// it will only be able to assume a bad signature and cannot express a more meaningful error. + BadProof, + /// The transaction birth block is ancient. + /// + /// # Possible causes + /// + /// For `FRAME`-based runtimes this would be caused by `current block number + /// - Era::birth block number > BlockHashCount`. (e.g. in Polkadot `BlockHashCount` = 2400, so + /// a + /// transaction with birth block number 1337 would be valid up until block number 1337 + 2400, + /// after which point the transaction would be considered to have an ancient birth block.) + AncientBirthBlock, + /// The transaction would exhaust the resources of current block. + /// + /// The transaction might be valid, but there are not enough resources + /// left in the current block. + ExhaustsResources, + /// Any other custom invalid validity that is not covered by this enum. + Custom(u8), + /// An extrinsic with a Mandatory dispatch resulted in Error. This is indicative of either a + /// malicious validator or a buggy `provide_inherent`. In any case, it can result in + /// dangerously overweight blocks and therefore if found, invalidates the block. + BadMandatory, + /// An extrinsic with a mandatory dispatch tried to be validated. + /// This is invalid; only inherent extrinsics are allowed to have mandatory dispatches. + MandatoryValidation, + /// The sending address is disabled or known to be invalid. + BadSigner, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for TransactionInvalid { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `TransactionInvalid`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::Call) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::Payment) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::Future) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 3usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::Stale) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 4usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::BadProof) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 5usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionInvalid::AncientBirthBlock, + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 6usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionInvalid::ExhaustsResources, + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 7usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionInvalid::Custom({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionInvalid::Custom.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 8usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::BadMandatory) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 9usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionInvalid::MandatoryValidation, + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 10usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::BadSigner) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `TransactionInvalid`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for TransactionInvalid { + #[inline] + fn clone(&self) -> TransactionInvalid { + match self { + TransactionInvalid::Call => TransactionInvalid::Call, + TransactionInvalid::Payment => TransactionInvalid::Payment, + TransactionInvalid::Future => TransactionInvalid::Future, + TransactionInvalid::Stale => TransactionInvalid::Stale, + TransactionInvalid::BadProof => TransactionInvalid::BadProof, + TransactionInvalid::AncientBirthBlock => { + TransactionInvalid::AncientBirthBlock + } + TransactionInvalid::ExhaustsResources => { + TransactionInvalid::ExhaustsResources + } + TransactionInvalid::Custom(__self_0) => { + TransactionInvalid::Custom(::core::clone::Clone::clone(__self_0)) + } + TransactionInvalid::BadMandatory => TransactionInvalid::BadMandatory, + TransactionInvalid::MandatoryValidation => { + TransactionInvalid::MandatoryValidation + } + TransactionInvalid::BadSigner => TransactionInvalid::BadSigner, + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionInvalid { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionInvalid::Call => { + ::core::fmt::Formatter::write_str(f, "Call") + } + TransactionInvalid::Payment => { + ::core::fmt::Formatter::write_str(f, "Payment") + } + TransactionInvalid::Future => { + ::core::fmt::Formatter::write_str(f, "Future") + } + TransactionInvalid::Stale => { + ::core::fmt::Formatter::write_str(f, "Stale") + } + TransactionInvalid::BadProof => { + ::core::fmt::Formatter::write_str(f, "BadProof") + } + TransactionInvalid::AncientBirthBlock => { + ::core::fmt::Formatter::write_str(f, "AncientBirthBlock") + } + TransactionInvalid::ExhaustsResources => { + ::core::fmt::Formatter::write_str(f, "ExhaustsResources") + } + TransactionInvalid::Custom(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Custom", + &__self_0, + ) + } + TransactionInvalid::BadMandatory => { + ::core::fmt::Formatter::write_str(f, "BadMandatory") + } + TransactionInvalid::MandatoryValidation => { + ::core::fmt::Formatter::write_str(f, "MandatoryValidation") + } + TransactionInvalid::BadSigner => { + ::core::fmt::Formatter::write_str(f, "BadSigner") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionInvalid {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionInvalid { + #[inline] + fn eq(&self, other: &TransactionInvalid) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionInvalid::Custom(__self_0), + TransactionInvalid::Custom(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + } + mod tx_payload { + //! This module contains the trait and types used to represent + //! transactions that can be submitted. + use crate::{ + dynamic::Value, error::{Error, MetadataError}, + metadata::Metadata, + }; + use codec::Encode; + use derivative::Derivative; + use scale_encode::EncodeAsFields; + use scale_value::{Composite, ValueDef, Variant}; + use std::{borrow::Cow, sync::Arc}; + /// This represents a transaction payload that can be submitted + /// to a node. + pub trait TxPayload { + /// Encode call data to the provided output. + fn encode_call_data_to( + &self, + metadata: &Metadata, + out: &mut Vec, + ) -> Result<(), Error>; + /// Encode call data and return the output. This is a convenience + /// wrapper around [`TxPayload::encode_call_data_to`]. + fn encode_call_data(&self, metadata: &Metadata) -> Result, Error> { + let mut v = Vec::new(); + self.encode_call_data_to(metadata, &mut v)?; + Ok(v) + } + /// Returns the details needed to validate the call, which + /// include a statically generated hash, the pallet name, + /// and the call name. + fn validation_details(&self) -> Option> { + None + } + } + pub struct ValidationDetails<'a> { + /// The pallet name. + pub pallet_name: &'a str, + /// The call name. + pub call_name: &'a str, + /// A hash (this is generated at compile time in our codegen) + /// to compare against the runtime code. + pub hash: [u8; 32], + } + /// A transaction payload containing some generic `CallData`. + #[derivative( + Clone(bound = "CallData: Clone"), + Debug(bound = "CallData: std::fmt::Debug"), + Eq(bound = "CallData: std::cmp::Eq"), + Ord(bound = "CallData: std::cmp::Ord"), + PartialEq(bound = "CallData: std::cmp::PartialEq"), + PartialOrd(bound = "CallData: std::cmp::PartialOrd") + )] + pub struct Payload { + pallet_name: Cow<'static, str>, + call_name: Cow<'static, str>, + call_data: CallData, + validation_hash: Option<[u8; 32]>, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Payload + where + CallData: Clone, + { + fn clone(&self) -> Self { + match *self { + Payload { + pallet_name: ref __arg_0, + call_name: ref __arg_1, + call_data: ref __arg_2, + validation_hash: ref __arg_3, + } => { + Payload { + pallet_name: (*__arg_0).clone(), + call_name: (*__arg_1).clone(), + call_data: (*__arg_2).clone(), + validation_hash: (*__arg_3).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Payload + where + CallData: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Payload { + pallet_name: ref __arg_0, + call_name: ref __arg_1, + call_data: ref __arg_2, + validation_hash: ref __arg_3, + } => { + let mut __debug_trait_builder = __f.debug_struct("Payload"); + let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); + let _ = __debug_trait_builder.field("call_name", &&(*__arg_1)); + let _ = __debug_trait_builder.field("call_data", &&(*__arg_2)); + let _ = __debug_trait_builder + .field("validation_hash", &&(*__arg_3)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for Payload + where + CallData: std::cmp::Eq, + {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for Payload + where + CallData: std::cmp::PartialEq, + { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + Payload { + pallet_name: ref __self_0, + call_name: ref __self_1, + call_data: ref __self_2, + validation_hash: ref __self_3, + } => { + match *other { + Payload { + pallet_name: ref __other_0, + call_name: ref __other_1, + call_data: ref __other_2, + validation_hash: ref __other_3, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + && &(*__self_3) == &(*__other_3) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialOrd for Payload + where + CallData: std::cmp::PartialOrd, + { + fn partial_cmp( + &self, + other: &Self, + ) -> ::std::option::Option<::std::cmp::Ordering> { + match *self { + Payload { + pallet_name: ref __self_0, + call_name: ref __self_1, + call_data: ref __self_2, + validation_hash: ref __self_3, + } => { + match *other { + Payload { + pallet_name: ref __other_0, + call_name: ref __other_1, + call_data: ref __other_2, + validation_hash: ref __other_3, + } => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_0), + &(*__other_0), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_1), + &(*__other_1), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_2), + &(*__other_2), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_3), + &(*__other_3), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::Ord for Payload + where + CallData: std::cmp::Ord, + { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + Payload { + pallet_name: ref __self_0, + call_name: ref __self_1, + call_data: ref __self_2, + validation_hash: ref __self_3, + } => { + match *other { + Payload { + pallet_name: ref __other_0, + call_name: ref __other_1, + call_data: ref __other_2, + validation_hash: ref __other_3, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + /// A boxed transaction payload. + pub type BoxedPayload = Payload>; + /// The type of a payload typically used for dynamic transaction payloads. + pub type DynamicPayload = Payload>; + impl Payload { + /// Create a new [`Payload`]. + pub fn new( + pallet_name: impl Into, + call_name: impl Into, + call_data: CallData, + ) -> Self { + Payload { + pallet_name: Cow::Owned(pallet_name.into()), + call_name: Cow::Owned(call_name.into()), + call_data, + validation_hash: None, + } + } + /// Create a new [`Payload`] using static strings for the pallet and call name. + /// This is only expected to be used from codegen. + #[doc(hidden)] + pub fn new_static( + pallet_name: &'static str, + call_name: &'static str, + call_data: CallData, + validation_hash: [u8; 32], + ) -> Self { + Payload { + pallet_name: Cow::Borrowed(pallet_name), + call_name: Cow::Borrowed(call_name), + call_data, + validation_hash: Some(validation_hash), + } + } + /// Box the payload. + pub fn boxed(self) -> BoxedPayload + where + CallData: EncodeAsFields + Send + Sync + 'static, + { + BoxedPayload { + pallet_name: self.pallet_name, + call_name: self.call_name, + call_data: Arc::new(self.call_data), + validation_hash: self.validation_hash, + } + } + /// Do not validate this call prior to submitting it. + pub fn unvalidated(self) -> Self { + Self { + validation_hash: None, + ..self + } + } + /// Returns the call data. + pub fn call_data(&self) -> &CallData { + &self.call_data + } + /// Returns the pallet name. + pub fn pallet_name(&self) -> &str { + &self.pallet_name + } + /// Returns the call name. + pub fn call_name(&self) -> &str { + &self.call_name + } + } + impl Payload> { + /// Convert the dynamic `Composite` payload into a [`Value`]. + /// This is useful if you want to use this as an argument for a + /// larger dynamic call that wants to use this as a nested call. + pub fn into_value(self) -> Value<()> { + let call = Value { + context: (), + value: ValueDef::Variant(Variant { + name: self.call_name.into_owned(), + values: self.call_data, + }), + }; + Value::unnamed_variant(self.pallet_name, [call]) + } + } + impl TxPayload for Payload { + fn encode_call_data_to( + &self, + metadata: &Metadata, + out: &mut Vec, + ) -> Result<(), Error> { + let pallet = metadata.pallet_by_name_err(&self.pallet_name)?; + let call = pallet + .call_variant_by_name(&self.call_name) + .ok_or_else(|| MetadataError::CallNameNotFound( + (*self.call_name).to_owned(), + ))?; + let pallet_index = pallet.index(); + let call_index = call.index; + pallet_index.encode_to(out); + call_index.encode_to(out); + let mut fields = call + .fields + .iter() + .map(|f| scale_encode::Field::new(f.ty.id, f.name.as_deref())); + self.call_data.encode_as_fields_to(&mut fields, metadata.types(), out)?; + Ok(()) + } + fn validation_details(&self) -> Option> { + self.validation_hash + .map(|hash| ValidationDetails { + pallet_name: &self.pallet_name, + call_name: &self.call_name, + hash, + }) + } + } + /// Construct a transaction at runtime; essentially an alias to [`Payload::new()`] + /// which provides a [`Composite`] value for the call data. + pub fn dynamic( + pallet_name: impl Into, + call_name: impl Into, + call_data: impl Into>, + ) -> DynamicPayload { + Payload::new(pallet_name, call_name, call_data.into()) + } + } + mod tx_progress { + //! Types representing extrinsics/transactions that have been submitted to a node. + use std::task::Poll; + use crate::utils::strip_compact_prefix; + use crate::{ + backend::{BlockRef, StreamOfResults, TransactionStatus as BackendTxStatus}, + client::OnlineClientT, + error::{DispatchError, Error, RpcError, TransactionError}, + events::EventsClient, Config, + }; + use derivative::Derivative; + use futures::{Stream, StreamExt}; + /// This struct represents a subscription to the progress of some transaction. + pub struct TxProgress { + sub: Option>>, + ext_hash: T::Hash, + client: C, + } + impl std::fmt::Debug for TxProgress { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TxProgress") + .field("sub", &"") + .field("ext_hash", &self.ext_hash) + .field("client", &"") + .finish() + } + } + impl Unpin for TxProgress {} + impl TxProgress { + /// Instantiate a new [`TxProgress`] from a custom subscription. + pub fn new( + sub: StreamOfResults>, + client: C, + ext_hash: T::Hash, + ) -> Self { + Self { + sub: Some(sub), + client, + ext_hash, + } + } + /// Return the hash of the extrinsic. + pub fn extrinsic_hash(&self) -> T::Hash { + self.ext_hash + } + } + impl TxProgress + where + T: Config, + C: OnlineClientT, + { + /// Return the next transaction status when it's emitted. This just delegates to the + /// [`futures::Stream`] implementation for [`TxProgress`], but allows you to + /// avoid importing that trait if you don't otherwise need it. + pub async fn next(&mut self) -> Option, Error>> { + StreamExt::next(self).await + } + /// Wait for the transaction to be finalized, and return a [`TxInBlock`] + /// instance when it is, or an error if there was a problem waiting for finalization. + /// + /// **Note:** consumes `self`. If you'd like to perform multiple actions as the state of the + /// transaction progresses, use [`TxProgress::next()`] instead. + /// + /// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some + /// probability that the transaction will not make it into a block but there is no guarantee + /// that this is true. In those cases the stream is closed however, so you currently have no way to find + /// out if they finally made it into a block or not. + pub async fn wait_for_finalized(mut self) -> Result, Error> { + while let Some(status) = self.next().await { + match status? { + TxStatus::InFinalizedBlock(s) => return Ok(s), + TxStatus::Error { message } => { + return Err(TransactionError::Error(message).into()); + } + TxStatus::Invalid { message } => { + return Err(TransactionError::Invalid(message).into()); + } + TxStatus::Dropped { message } => { + return Err(TransactionError::Dropped(message).into()); + } + _ => continue, + } + } + Err(RpcError::SubscriptionDropped.into()) + } + /// Wait for the transaction to be finalized, and for the transaction events to indicate + /// that the transaction was successful. Returns the events associated with the transaction, + /// as well as a couple of other details (block hash and extrinsic hash). + /// + /// **Note:** consumes self. If you'd like to perform multiple actions as progress is made, + /// use [`TxProgress::next()`] instead. + /// + /// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some + /// probability that the transaction will not make it into a block but there is no guarantee + /// that this is true. In those cases the stream is closed however, so you currently have no way to find + /// out if they finally made it into a block or not. + pub async fn wait_for_finalized_success( + self, + ) -> Result, Error> { + let evs = self.wait_for_finalized().await?.wait_for_success().await?; + Ok(evs) + } + } + impl Stream for TxProgress { + type Item = Result, Error>; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + let sub = match self.sub.as_mut() { + Some(sub) => sub, + None => return Poll::Ready(None), + }; + sub.poll_next_unpin(cx) + .map_ok(|status| { + match status { + BackendTxStatus::Validated => TxStatus::Validated, + BackendTxStatus::Broadcasted { num_peers } => { + TxStatus::Broadcasted { num_peers } + } + BackendTxStatus::NoLongerInBestBlock => { + TxStatus::NoLongerInBestBlock + } + BackendTxStatus::InBestBlock { hash } => { + TxStatus::InBestBlock( + TxInBlock::new(hash, self.ext_hash, self.client.clone()), + ) + } + BackendTxStatus::InFinalizedBlock { hash } => { + self.sub = None; + TxStatus::InFinalizedBlock( + TxInBlock::new(hash, self.ext_hash, self.client.clone()), + ) + } + BackendTxStatus::Error { message } => { + self.sub = None; + TxStatus::Error { message } + } + BackendTxStatus::Invalid { message } => { + self.sub = None; + TxStatus::Invalid { message } + } + BackendTxStatus::Dropped { message } => { + self.sub = None; + TxStatus::Dropped { message } + } + } + }) + } + } + /// Possible transaction statuses returned from our [`TxProgress::next()`] call. + #[derivative(Debug(bound = "C: std::fmt::Debug"))] + pub enum TxStatus { + /// Transaction is part of the future queue. + Validated, + /// The transaction has been broadcast to other nodes. + Broadcasted { + /// Number of peers it's been broadcast to. + num_peers: u32, + }, + /// Transaction is no longer in a best block. + NoLongerInBestBlock, + /// Transaction has been included in block with given hash. + InBestBlock(TxInBlock), + /// Transaction has been finalized by a finality-gadget, e.g GRANDPA + InFinalizedBlock(TxInBlock), + /// Something went wrong in the node. + Error { + /// Human readable message; what went wrong. + message: String, + }, + /// Transaction is invalid (bad nonce, signature etc). + Invalid { + /// Human readable message; why was it invalid. + message: String, + }, + /// The transaction was dropped. + Dropped { + /// Human readable message; why was it dropped. + message: String, + }, + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for TxStatus + where + C: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + TxStatus::Validated => { + let mut __debug_trait_builder = __f.debug_tuple("Validated"); + __debug_trait_builder.finish() + } + TxStatus::Broadcasted { num_peers: ref __arg_0 } => { + let mut __debug_trait_builder = __f.debug_struct("Broadcasted"); + let _ = __debug_trait_builder.field("num_peers", &&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::NoLongerInBestBlock => { + let mut __debug_trait_builder = __f + .debug_tuple("NoLongerInBestBlock"); + __debug_trait_builder.finish() + } + TxStatus::InBestBlock(ref __arg_0) => { + let mut __debug_trait_builder = __f.debug_tuple("InBestBlock"); + let _ = __debug_trait_builder.field(&&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::InFinalizedBlock(ref __arg_0) => { + let mut __debug_trait_builder = __f + .debug_tuple("InFinalizedBlock"); + let _ = __debug_trait_builder.field(&&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::Error { message: ref __arg_0 } => { + let mut __debug_trait_builder = __f.debug_struct("Error"); + let _ = __debug_trait_builder.field("message", &&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::Invalid { message: ref __arg_0 } => { + let mut __debug_trait_builder = __f.debug_struct("Invalid"); + let _ = __debug_trait_builder.field("message", &&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::Dropped { message: ref __arg_0 } => { + let mut __debug_trait_builder = __f.debug_struct("Dropped"); + let _ = __debug_trait_builder.field("message", &&(*__arg_0)); + __debug_trait_builder.finish() + } + } + } + } + impl TxStatus { + /// A convenience method to return the finalized details. Returns + /// [`None`] if the enum variant is not [`TxStatus::InFinalizedBlock`]. + pub fn as_finalized(&self) -> Option<&TxInBlock> { + match self { + Self::InFinalizedBlock(val) => Some(val), + _ => None, + } + } + /// A convenience method to return the best block details. Returns + /// [`None`] if the enum variant is not [`TxStatus::InBestBlock`]. + pub fn as_in_block(&self) -> Option<&TxInBlock> { + match self { + Self::InBestBlock(val) => Some(val), + _ => None, + } + } + } + /// This struct represents a transaction that has made it into a block. + #[derivative(Debug(bound = "C: std::fmt::Debug"))] + pub struct TxInBlock { + block_ref: BlockRef, + ext_hash: T::Hash, + client: C, + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for TxInBlock + where + C: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + TxInBlock { + block_ref: ref __arg_0, + ext_hash: ref __arg_1, + client: ref __arg_2, + } => { + let mut __debug_trait_builder = __f.debug_struct("TxInBlock"); + let _ = __debug_trait_builder.field("block_ref", &&(*__arg_0)); + let _ = __debug_trait_builder.field("ext_hash", &&(*__arg_1)); + let _ = __debug_trait_builder.field("client", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + impl TxInBlock { + pub(crate) fn new( + block_ref: BlockRef, + ext_hash: T::Hash, + client: C, + ) -> Self { + Self { + block_ref, + ext_hash, + client, + } + } + /// Return the hash of the block that the transaction has made it into. + pub fn block_hash(&self) -> T::Hash { + self.block_ref.hash() + } + /// Return the hash of the extrinsic that was submitted. + pub fn extrinsic_hash(&self) -> T::Hash { + self.ext_hash + } + } + impl> TxInBlock { + /// Fetch the events associated with this transaction. If the transaction + /// was successful (ie no `ExtrinsicFailed`) events were found, then we return + /// the events associated with it. If the transaction was not successful, or + /// something else went wrong, we return an error. + /// + /// **Note:** If multiple `ExtrinsicFailed` errors are returned (for instance + /// because a pallet chooses to emit one as an event, which is considered + /// abnormal behaviour), it is not specified which of the errors is returned here. + /// You can use [`TxInBlock::fetch_events`] instead if you'd like to + /// work with multiple "error" events. + /// + /// **Note:** This has to download block details from the node and decode events + /// from them. + pub async fn wait_for_success( + &self, + ) -> Result, Error> { + let events = self.fetch_events().await?; + for ev in events.iter() { + let ev = ev?; + if ev.pallet_name() == "System" + && ev.variant_name() == "ExtrinsicFailed" + { + let dispatch_error = DispatchError::decode_from( + ev.field_bytes(), + self.client.metadata(), + )?; + return Err(dispatch_error.into()); + } + } + Ok(events) + } + /// Fetch all of the events associated with this transaction. This succeeds whether + /// the transaction was a success or not; it's up to you to handle the error and + /// success events however you prefer. + /// + /// **Note:** This has to download block details from the node and decode events + /// from them. + pub async fn fetch_events( + &self, + ) -> Result, Error> { + let block_body = self + .client + .backend() + .block_body(self.block_ref.hash()) + .await? + .ok_or(Error::Transaction(TransactionError::BlockNotFound))?; + let extrinsic_idx = block_body + .iter() + .position(|ext| { + use crate::config::Hasher; + let Ok((_, stripped)) = strip_compact_prefix(ext) else { + return false; + }; + let hash = T::Hasher::hash_of(&stripped); + hash == self.ext_hash + }) + .ok_or(Error::Transaction(TransactionError::BlockNotFound))?; + let events = EventsClient::new(self.client.clone()) + .at(self.block_ref.clone()) + .await?; + Ok( + crate::blocks::ExtrinsicEvents::new( + self.ext_hash, + extrinsic_idx as u32, + events, + ), + ) + } + } + } + pub use self::{ + signer::Signer, + tx_client::{ + PartialExtrinsic, SubmittableExtrinsic, TransactionInvalid, + TransactionUnknown, TxClient, ValidationResult, + }, + tx_payload::{dynamic, BoxedPayload, DynamicPayload, Payload, TxPayload}, + tx_progress::{TxInBlock, TxProgress, TxStatus}, + }; +} +pub mod utils { + //! Miscellaneous utility helpers. + mod account_id { + //! The "default" Substrate/Polkadot AccountId. This is used in codegen, as well as signing related bits. + //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_core::AccountId32` + //! for instance, to gain functionality without forcing a dependency on Substrate crates here. + use codec::{Decode, Encode}; + use serde::{Deserialize, Serialize}; + /// A 32-byte cryptographic identifier. This is a simplified version of Substrate's + /// `sp_core::crypto::AccountId32`. To obtain more functionality, convert this into + /// that type. + pub struct AccountId32(pub [u8; 32]); + #[automatically_derived] + impl ::core::clone::Clone for AccountId32 { + #[inline] + fn clone(&self) -> AccountId32 { + AccountId32(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::cmp::Eq for AccountId32 { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for AccountId32 {} + #[automatically_derived] + impl ::core::cmp::PartialEq for AccountId32 { + #[inline] + fn eq(&self, other: &AccountId32) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Ord for AccountId32 { + #[inline] + fn cmp(&self, other: &AccountId32) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for AccountId32 { + #[inline] + fn partial_cmp( + &self, + other: &AccountId32, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for AccountId32 { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.0) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.0) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.0, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike for AccountId32 {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for AccountId32 { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok( + AccountId32({ + let __codec_res_edqy = <[u8; 32] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `AccountId32.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for AccountId32 { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "AccountId32", + &&self.0, + ) + } + } + impl ::scale_encode::EncodeAsType for AccountId32 { + #[allow(unused_variables)] + fn encode_as_type_to( + &self, + __encode_as_type_type_id: u32, + __encode_as_type_types: &::scale_encode::PortableRegistry, + __encode_as_type_out: &mut ::scale_encode::Vec, + ) -> Result<(), ::scale_encode::Error> { + let AccountId32(_0) = self; + ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ) + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + } + impl ::scale_encode::EncodeAsFields for AccountId32 { + #[allow(unused_variables)] + fn encode_as_fields_to( + &self, + __encode_as_type_fields: &mut dyn ::scale_encode::FieldIter<'_>, + __encode_as_type_types: &::scale_encode::PortableRegistry, + __encode_as_type_out: &mut ::scale_encode::Vec, + ) -> Result<(), ::scale_encode::Error> { + let AccountId32(_0) = self; + ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ) + .encode_as_fields_to( + __encode_as_type_fields, + __encode_as_type_types, + __encode_as_type_out, + ) + } + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for AccountId32 { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = AccountId32; + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + self.visit_tuple(&mut value.as_tuple(), type_id) + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: value.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = value; + Ok( + AccountId32({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ) + } + } + impl ::scale_decode::DecodeAsFields for AccountId32 { + fn decode_as_fields<'info>( + input: &mut &[u8], + fields: &mut dyn ::scale_decode::FieldIter<'info>, + types: &'info ::scale_decode::PortableRegistry, + ) -> Result { + let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; + let mut composite = ::scale_decode::visitor::types::Composite::new( + input, + path, + fields, + types, + false, + ); + use ::scale_decode::{Visitor, IntoVisitor}; + let val = ::into_visitor() + .visit_composite( + &mut composite, + ::scale_decode::visitor::TypeId(0), + ); + composite.skip_decoding()?; + *input = composite.bytes_from_undecoded(); + val.map_err(From::from) + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for AccountId32 { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "AccountId32", + "subxt::utils::account_id", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .docs( + &[ + "A 32-byte cryptographic identifier. This is a simplified version of Substrate's", + "`sp_core::crypto::AccountId32`. To obtain more functionality, convert this into", + "that type.", + ], + ) + .composite( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 32]>().type_name("[u8; 32]")), + ) + } + } + }; + impl AsRef<[u8]> for AccountId32 { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } + } + impl AsRef<[u8; 32]> for AccountId32 { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } + } + impl From<[u8; 32]> for AccountId32 { + fn from(x: [u8; 32]) -> Self { + AccountId32(x) + } + } + impl AccountId32 { + fn to_ss58check(&self) -> String { + const SUBSTRATE_SS58_PREFIX: u8 = 42; + let mut v = <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([SUBSTRATE_SS58_PREFIX]), + ); + v.extend(self.0); + let r = ss58hash(&v); + v.extend(&r[0..2]); + use base58::ToBase58; + v.to_base58() + } + fn from_ss58check(s: &str) -> Result { + const CHECKSUM_LEN: usize = 2; + let body_len = 32; + use base58::FromBase58; + let data = s.from_base58().map_err(|_| FromSs58Error::BadBase58)?; + if data.len() < 2 { + return Err(FromSs58Error::BadLength); + } + let prefix_len = match data[0] { + 0..=63 => 1, + 64..=127 => 2, + _ => return Err(FromSs58Error::InvalidPrefix), + }; + if data.len() != prefix_len + body_len + CHECKSUM_LEN { + return Err(FromSs58Error::BadLength); + } + let hash = ss58hash(&data[0..body_len + prefix_len]); + let checksum = &hash[0..CHECKSUM_LEN]; + if data[body_len + prefix_len..body_len + prefix_len + CHECKSUM_LEN] + != *checksum + { + return Err(FromSs58Error::InvalidChecksum); + } + let result = data[prefix_len..body_len + prefix_len] + .try_into() + .map_err(|_| FromSs58Error::BadLength)?; + Ok(AccountId32(result)) + } + } + /// An error obtained from trying to interpret an SS58 encoded string into an AccountId32 + #[allow(missing_docs)] + pub enum FromSs58Error { + #[error("Base 58 requirement is violated")] + BadBase58, + #[error("Length is bad")] + BadLength, + #[error("Invalid checksum")] + InvalidChecksum, + #[error("Invalid SS58 prefix byte.")] + InvalidPrefix, + } + #[allow(unused_qualifications)] + impl std::error::Error for FromSs58Error {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for FromSs58Error { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + FromSs58Error::BadBase58 {} => { + __formatter.write_str("Base 58 requirement is violated") + } + FromSs58Error::BadLength {} => __formatter.write_str("Length is bad"), + FromSs58Error::InvalidChecksum {} => { + __formatter.write_str("Invalid checksum") + } + FromSs58Error::InvalidPrefix {} => { + __formatter.write_str("Invalid SS58 prefix byte.") + } + } + } + } + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::clone::Clone for FromSs58Error { + #[inline] + fn clone(&self) -> FromSs58Error { + *self + } + } + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::marker::Copy for FromSs58Error {} + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::cmp::Eq for FromSs58Error { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::marker::StructuralPartialEq for FromSs58Error {} + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::cmp::PartialEq for FromSs58Error { + #[inline] + fn eq(&self, other: &FromSs58Error) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::fmt::Debug for FromSs58Error { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + FromSs58Error::BadBase58 => "BadBase58", + FromSs58Error::BadLength => "BadLength", + FromSs58Error::InvalidChecksum => "InvalidChecksum", + FromSs58Error::InvalidPrefix => "InvalidPrefix", + }, + ) + } + } + fn ss58hash(data: &[u8]) -> Vec { + use blake2::{Blake2b512, Digest}; + const PREFIX: &[u8] = b"SS58PRE"; + let mut ctx = Blake2b512::new(); + ctx.update(PREFIX); + ctx.update(data); + ctx.finalize().to_vec() + } + impl Serialize for AccountId32 { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_ss58check()) + } + } + impl<'de> Deserialize<'de> for AccountId32 { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + AccountId32::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| serde::de::Error::custom({ + let res = ::alloc::fmt::format(format_args!("{0:?}", e)); + res + })) + } + } + impl std::fmt::Display for AccountId32 { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.write_fmt(format_args!("{0}", self.to_ss58check())) + } + } + impl std::str::FromStr for AccountId32 { + type Err = FromSs58Error; + fn from_str(s: &str) -> Result { + AccountId32::from_ss58check(s) + } + } + } + pub mod bits { + //! Generic `scale_bits` over `bitvec`-like `BitOrder` and `BitFormat` types. + use codec::{Compact, Input}; + use scale_bits::{ + scale::format::{Format, OrderFormat, StoreFormat}, + Bits, + }; + use scale_decode::IntoVisitor; + use std::marker::PhantomData; + /// Associates `bitvec::store::BitStore` trait with corresponding, type-erased `scale_bits::StoreFormat` enum. + /// + /// Used to decode bit sequences by providing `scale_bits::StoreFormat` using + /// `bitvec`-like type type parameters. + pub trait BitStore { + /// Corresponding `scale_bits::StoreFormat` value. + const FORMAT: StoreFormat; + /// Number of bits that the backing store types holds. + const BITS: u32; + } + impl BitStore for u8 { + const FORMAT: StoreFormat = StoreFormat::U8; + const BITS: u32 = ::BITS; + } + impl BitStore for u16 { + const FORMAT: StoreFormat = StoreFormat::U16; + const BITS: u32 = ::BITS; + } + impl BitStore for u32 { + const FORMAT: StoreFormat = StoreFormat::U32; + const BITS: u32 = ::BITS; + } + impl BitStore for u64 { + const FORMAT: StoreFormat = StoreFormat::U64; + const BITS: u32 = ::BITS; + } + /// Associates `bitvec::order::BitOrder` trait with corresponding, type-erased `scale_bits::OrderFormat` enum. + /// + /// Used to decode bit sequences in runtime by providing `scale_bits::OrderFormat` using + /// `bitvec`-like type type parameters. + pub trait BitOrder { + /// Corresponding `scale_bits::OrderFormat` value. + const FORMAT: OrderFormat; + } + ///Type-level value that corresponds to `scale_bits::OrderFormat::Lsb0` at run-time + /// and `bitvec::order::BitOrder::Lsb0` at the type level. + pub enum Lsb0 {} + #[automatically_derived] + impl ::core::clone::Clone for Lsb0 { + #[inline] + fn clone(&self) -> Lsb0 { + match *self {} + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Lsb0 { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self {} + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Lsb0 {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Lsb0 { + #[inline] + fn eq(&self, other: &Lsb0) -> bool { + match *self {} + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Lsb0 { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + impl BitOrder for Lsb0 { + const FORMAT: OrderFormat = OrderFormat::Lsb0; + } + ///Type-level value that corresponds to `scale_bits::OrderFormat::Msb0` at run-time + /// and `bitvec::order::BitOrder::Msb0` at the type level. + pub enum Msb0 {} + #[automatically_derived] + impl ::core::clone::Clone for Msb0 { + #[inline] + fn clone(&self) -> Msb0 { + match *self {} + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Msb0 { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self {} + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Msb0 {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Msb0 { + #[inline] + fn eq(&self, other: &Msb0) -> bool { + match *self {} + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Msb0 { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + impl BitOrder for Msb0 { + const FORMAT: OrderFormat = OrderFormat::Msb0; + } + /// Constructs a run-time format parameters based on the corresponding type-level parameters. + fn bit_format() -> Format { + Format { + order: Order::FORMAT, + store: Store::FORMAT, + } + } + /// `scale_bits::Bits` generic over the bit store (`u8`/`u16`/`u32`/`u64`) and bit order (LSB, MSB) + /// used for SCALE encoding/decoding. Uses `scale_bits::Bits`-default `u8` and LSB format underneath. + pub struct DecodedBits { + bits: Bits, + _marker: PhantomData<(Store, Order)>, + } + #[automatically_derived] + impl ::core::fmt::Debug + for DecodedBits { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "DecodedBits", + "bits", + &self.bits, + "_marker", + &&self._marker, + ) + } + } + #[automatically_derived] + impl< + Store: ::core::clone::Clone, + Order: ::core::clone::Clone, + > ::core::clone::Clone for DecodedBits { + #[inline] + fn clone(&self) -> DecodedBits { + DecodedBits { + bits: ::core::clone::Clone::clone(&self.bits), + _marker: ::core::clone::Clone::clone(&self._marker), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for DecodedBits {} + #[automatically_derived] + impl< + Store: ::core::cmp::PartialEq, + Order: ::core::cmp::PartialEq, + > ::core::cmp::PartialEq for DecodedBits { + #[inline] + fn eq(&self, other: &DecodedBits) -> bool { + self.bits == other.bits && self._marker == other._marker + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for DecodedBits { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + impl DecodedBits { + /// Extracts the underlying `scale_bits::Bits` value. + pub fn into_bits(self) -> Bits { + self.bits + } + /// References the underlying `scale_bits::Bits` value. + pub fn as_bits(&self) -> &Bits { + &self.bits + } + } + impl core::iter::FromIterator for DecodedBits { + fn from_iter>(iter: T) -> Self { + DecodedBits { + bits: Bits::from_iter(iter), + _marker: PhantomData, + } + } + } + impl codec::Decode + for DecodedBits { + fn decode(input: &mut I) -> Result { + /// Equivalent of `BitSlice::MAX_BITS` on 32bit machine. + const ARCH32BIT_BITSLICE_MAX_BITS: u32 = 0x1fff_ffff; + let Compact(bits) = >::decode(input)?; + if bits > ARCH32BIT_BITSLICE_MAX_BITS { + return Err("Attempt to decode a BitVec with too many bits".into()); + } + let elements = (bits / Store::BITS) + u32::from(bits % Store::BITS != 0); + let bytes_in_elem = Store::BITS.saturating_div(u8::BITS); + let bytes_needed = (elements * bytes_in_elem) as usize; + let mut storage = codec::Encode::encode(&Compact(bits)); + let prefix_len = storage.len(); + storage.reserve_exact(bytes_needed); + storage.extend(::alloc::vec::from_elem(0, bytes_needed)); + input.read(&mut storage[prefix_len..])?; + let decoder = scale_bits::decode_using_format_from( + &storage, + bit_format::(), + )?; + let bits = decoder.collect::, _>>()?; + let bits = Bits::from_iter(bits); + Ok(DecodedBits { + bits, + _marker: PhantomData, + }) + } + } + impl codec::Encode + for DecodedBits { + fn size_hint(&self) -> usize { + self.bits.size_hint() + } + fn encoded_size(&self) -> usize { + self.bits.encoded_size() + } + fn encode(&self) -> Vec { + scale_bits::encode_using_format( + self.bits.iter(), + bit_format::(), + ) + } + } + #[doc(hidden)] + pub struct DecodedBitsVisitor(std::marker::PhantomData<(S, O)>); + impl scale_decode::Visitor for DecodedBitsVisitor { + type Value<'scale, 'info> = DecodedBits; + type Error = scale_decode::Error; + fn unchecked_decode_as_type<'scale, 'info>( + self, + input: &mut &'scale [u8], + type_id: scale_decode::visitor::TypeId, + types: &'info scale_info::PortableRegistry, + ) -> scale_decode::visitor::DecodeAsTypeResult< + Self, + Result, Self::Error>, + > { + let res = scale_decode::visitor::decode_with_visitor( + input, + type_id.0, + types, + Bits::into_visitor(), + ) + .map(|bits| DecodedBits { + bits, + _marker: PhantomData, + }); + scale_decode::visitor::DecodeAsTypeResult::Decoded(res) + } + } + impl scale_decode::IntoVisitor for DecodedBits { + type Visitor = DecodedBitsVisitor; + fn into_visitor() -> Self::Visitor { + DecodedBitsVisitor(PhantomData) + } + } + impl scale_encode::EncodeAsType for DecodedBits { + fn encode_as_type_to( + &self, + type_id: u32, + types: &scale_info::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + self.bits.encode_as_type_to(type_id, types, out) + } + } + } + mod era { + use scale_decode::DecodeAsType; + use scale_encode::EncodeAsType; + /// An era to describe the longevity of a transaction. + pub enum Era { + /// The transaction is valid forever. The genesis hash must be present in the signed content. + #[default] + Immortal, + /// The transaction will expire. Use [`Era::mortal`] to construct this with correct values. + /// + /// When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter + /// of `system` module. + Mortal { + /// The number of blocks that the tx will be valid for after the checkpoint block + /// hash found in the signer payload. + period: u64, + /// The phase in the period that this transaction's lifetime begins (and, importantly, + /// implies which block hash is included in the signature material). If the `period` is + /// greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that + /// `period` is. + phase: u64, + }, + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Era {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Era { + #[inline] + fn eq(&self, other: &Era) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + Era::Mortal { period: __self_0, phase: __self_1 }, + Era::Mortal { period: __arg1_0, phase: __arg1_1 }, + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::default::Default for Era { + #[inline] + fn default() -> Era { + Self::Immortal + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Era { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Era { + #[inline] + fn clone(&self) -> Era { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for Era {} + #[automatically_derived] + impl ::core::fmt::Debug for Era { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + Era::Immortal => ::core::fmt::Formatter::write_str(f, "Immortal"), + Era::Mortal { period: __self_0, phase: __self_1 } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Mortal", + "period", + __self_0, + "phase", + &__self_1, + ) + } + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Era { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + Era::Immortal => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "Era", + 0u32, + "Immortal", + ) + } + Era::Mortal { ref period, ref phase } => { + let mut __serde_state = _serde::Serializer::serialize_struct_variant( + __serializer, + "Era", + 1u32, + "Mortal", + 0 + 1 + 1, + )?; + _serde::ser::SerializeStructVariant::serialize_field( + &mut __serde_state, + "period", + period, + )?; + _serde::ser::SerializeStructVariant::serialize_field( + &mut __serde_state, + "phase", + phase, + )?; + _serde::ser::SerializeStructVariant::end(__serde_state) + } + } + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Era { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "Immortal" => _serde::__private::Ok(__Field::__field0), + "Mortal" => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"Immortal" => _serde::__private::Ok(__Field::__field0), + b"Mortal" => _serde::__private::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Era; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "enum Era", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(Era::Immortal) + } + (__Field::__field1, __variant) => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "period" => _serde::__private::Ok(__Field::__field0), + "phase" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"period" => _serde::__private::Ok(__Field::__field0), + b"phase" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Era; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant Era::Mortal", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant Era::Mortal with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct variant Era::Mortal with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(Era::Mortal { + period: __field0, + phase: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("period"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("phase"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("period")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("phase")? + } + }; + _serde::__private::Ok(Era::Mortal { + period: __field0, + phase: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "period", + "phase", + ]; + _serde::de::VariantAccess::struct_variant( + __variant, + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &["Immortal", "Mortal"]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "Era", + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for Era { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = Era; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "Immortal" { + return Ok(Era::Immortal); + } + if value.name() == "Mortal" { + let fields = value.fields(); + return if fields.has_unnamed_fields() { + if fields.remaining() != 2usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 2usize, + }), + ); + } + let vals = fields; + Ok(Era::Mortal { + period: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("period"))? + }, + phase: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("phase"))? + }, + }) + } else { + let vals: ::scale_decode::BTreeMap, _> = fields + .map(|res| res.map(|item| (item.name(), item))) + .collect::>()?; + Ok(Era::Mortal { + period: { + let val = *vals + .get(&Some("period")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "period".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("period"))? + }, + phase: { + let val = *vals + .get(&Some("phase")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "phase".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("phase"))? + }, + }) + }; + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new(["Immortal", "Mortal"]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + impl ::scale_encode::EncodeAsType for Era { + #[allow(unused_variables)] + fn encode_as_type_to( + &self, + __encode_as_type_type_id: u32, + __encode_as_type_types: &::scale_encode::PortableRegistry, + __encode_as_type_out: &mut ::scale_encode::Vec, + ) -> Result<(), ::scale_encode::Error> { + match self { + Self::Immortal => { + ::scale_encode::Variant { + name: "Immortal", + fields: ::scale_encode::Composite( + ([] + as [( + Option<&'static str>, + &dyn ::scale_encode::EncodeAsType, + ); 0]) + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Mortal { period, phase } => { + ::scale_encode::Variant { + name: "Mortal", + fields: ::scale_encode::Composite( + [ + ( + Some("period"), + period as &dyn ::scale_encode::EncodeAsType, + ), + (Some("phase"), phase as &dyn ::scale_encode::EncodeAsType), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + _ => { + ::core::panicking::panic( + "internal error: entered unreachable code", + ) + } + } + } + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for Era { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "Era", + "subxt::utils::era", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .docs(&["An era to describe the longevity of a transaction."]) + .variant( + ::scale_info::build::Variants::new() + .variant( + "Immortal", + |v| { + v + .index(0usize as ::core::primitive::u8) + .docs( + &[ + "The transaction is valid forever. The genesis hash must be present in the signed content.", + ], + ) + }, + ) + .variant( + "Mortal", + |v| { + v + .index(1usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::named() + .field(|f| { + f + .ty::() + .name("period") + .type_name("u64") + .docs( + &[ + "The number of blocks that the tx will be valid for after the checkpoint block", + "hash found in the signer payload.", + ], + ) + }) + .field(|f| { + f + .ty::() + .name("phase") + .type_name("u64") + .docs( + &[ + "The phase in the period that this transaction's lifetime begins (and, importantly,", + "implies which block hash is included in the signature material). If the `period` is", + "greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that", + "`period` is.", + ], + ) + }), + ) + .docs( + &[ + "The transaction will expire. Use [`Era::mortal`] to construct this with correct values.", + "", + "When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter", + "of `system` module.", + ], + ) + }, + ), + ) + } + } + }; + impl Era { + /// Create a new era based on a period (which should be a power of two between 4 and 65536 + /// inclusive) and a block number on which it should start (or, for long periods, be shortly + /// after the start). + /// + /// If using `Era` in the context of `FRAME` runtime, make sure that `period` + /// does not exceed `BlockHashCount` parameter passed to `system` module, since that + /// prunes old blocks and renders transactions immediately invalid. + pub fn mortal(period: u64, current: u64) -> Self { + let period = period + .checked_next_power_of_two() + .unwrap_or(1 << 16) + .clamp(4, 1 << 16); + let phase = current % period; + let quantize_factor = (period >> 12).max(1); + let quantized_phase = phase / quantize_factor * quantize_factor; + Self::Mortal { + period, + phase: quantized_phase, + } + } + } + impl codec::Encode for Era { + fn encode_to(&self, output: &mut T) { + match self { + Self::Immortal => output.push_byte(0), + Self::Mortal { period, phase } => { + let quantize_factor = (*period >> 12).max(1); + let encoded = (period.trailing_zeros() - 1).clamp(1, 15) as u16 + | ((phase / quantize_factor) << 4) as u16; + encoded.encode_to(output); + } + } + } + } + impl codec::Decode for Era { + fn decode(input: &mut I) -> Result { + let first = input.read_byte()?; + if first == 0 { + Ok(Self::Immortal) + } else { + let encoded = first as u64 + ((input.read_byte()? as u64) << 8); + let period = 2 << (encoded % (1 << 4)); + let quantize_factor = (period >> 12).max(1); + let phase = (encoded >> 4) * quantize_factor; + if period >= 4 && phase < period { + Ok(Self::Mortal { period, phase }) + } else { + Err("Invalid period and phase".into()) + } + } + } + } + } + mod multi_address { + //! The "default" Substrate/Polkadot Address type. This is used in codegen, as well as signing related bits. + //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_runtime::MultiAddress` + //! for instance, to gain functionality without forcing a dependency on Substrate crates here. + use codec::{Decode, Encode}; + /// A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's + /// `sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion + /// functionality is provided via `From` impls if the `substrate-compat` feature is enabled). + pub enum MultiAddress { + /// It's an account ID (pubkey). + Id(AccountId), + /// It's an account index. + Index(#[codec(compact)] AccountIndex), + /// It's some arbitrary raw bytes. + Raw(Vec), + /// It's a 32 byte representation. + Address32([u8; 32]), + /// Its a 20 byte representation. + Address20([u8; 20]), + } + #[automatically_derived] + impl< + AccountId: ::core::clone::Clone, + AccountIndex: ::core::clone::Clone, + > ::core::clone::Clone for MultiAddress { + #[inline] + fn clone(&self) -> MultiAddress { + match self { + MultiAddress::Id(__self_0) => { + MultiAddress::Id(::core::clone::Clone::clone(__self_0)) + } + MultiAddress::Index(__self_0) => { + MultiAddress::Index(::core::clone::Clone::clone(__self_0)) + } + MultiAddress::Raw(__self_0) => { + MultiAddress::Raw(::core::clone::Clone::clone(__self_0)) + } + MultiAddress::Address32(__self_0) => { + MultiAddress::Address32(::core::clone::Clone::clone(__self_0)) + } + MultiAddress::Address20(__self_0) => { + MultiAddress::Address20(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for MultiAddress { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; + let _: ::core::cmp::AssertParamIsEq<[u8; 20]>; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for MultiAddress {} + #[automatically_derived] + impl< + AccountId: ::core::cmp::PartialEq, + AccountIndex: ::core::cmp::PartialEq, + > ::core::cmp::PartialEq for MultiAddress { + #[inline] + fn eq(&self, other: &MultiAddress) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + ( + MultiAddress::Index(__self_0), + MultiAddress::Index(__arg1_0), + ) => *__self_0 == *__arg1_0, + (MultiAddress::Raw(__self_0), MultiAddress::Raw(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + ( + MultiAddress::Address32(__self_0), + MultiAddress::Address32(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MultiAddress::Address20(__self_0), + MultiAddress::Address20(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl< + AccountId: ::core::cmp::Ord, + AccountIndex: ::core::cmp::Ord, + > ::core::cmp::Ord for MultiAddress { + #[inline] + fn cmp( + &self, + other: &MultiAddress, + ) -> ::core::cmp::Ordering { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) { + ::core::cmp::Ordering::Equal => { + match (self, other) { + (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { + ::core::cmp::Ord::cmp(__self_0, __arg1_0) + } + ( + MultiAddress::Index(__self_0), + MultiAddress::Index(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiAddress::Raw(__self_0), + MultiAddress::Raw(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiAddress::Address32(__self_0), + MultiAddress::Address32(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiAddress::Address20(__self_0), + MultiAddress::Address20(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl< + AccountId: ::core::cmp::PartialOrd, + AccountIndex: ::core::cmp::PartialOrd, + > ::core::cmp::PartialOrd for MultiAddress { + #[inline] + fn partial_cmp( + &self, + other: &MultiAddress, + ) -> ::core::option::Option<::core::cmp::Ordering> { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + match (self, other) { + (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) + } + (MultiAddress::Index(__self_0), MultiAddress::Index(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) + } + (MultiAddress::Raw(__self_0), MultiAddress::Raw(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) + } + ( + MultiAddress::Address32(__self_0), + MultiAddress::Address32(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + ( + MultiAddress::Address20(__self_0), + MultiAddress::Address20(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode + for MultiAddress + where + AccountId: ::codec::Encode, + AccountId: ::codec::Encode, + AccountIndex: ::codec::HasCompact, + { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + MultiAddress::Id(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiAddress::Index(ref aa) => { + 0_usize + .saturating_add( + ::codec::Encode::size_hint( + &<::Type as ::codec::EncodeAsRef< + '_, + AccountIndex, + >>::RefType::from(aa), + ), + ) + } + MultiAddress::Raw(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiAddress::Address32(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiAddress::Address20(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + _ => 0_usize, + } + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + match *self { + MultiAddress::Id(ref aa) => { + __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiAddress::Index(ref aa) => { + __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); + { + ::codec::Encode::encode_to( + &<::Type as ::codec::EncodeAsRef< + '_, + AccountIndex, + >>::RefType::from(aa), + __codec_dest_edqy, + ); + } + } + MultiAddress::Raw(ref aa) => { + __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiAddress::Address32(ref aa) => { + __codec_dest_edqy.push_byte(3usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiAddress::Address20(ref aa) => { + __codec_dest_edqy.push_byte(4usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::codec::EncodeLike + for MultiAddress + where + AccountId: ::codec::Encode, + AccountId: ::codec::Encode, + AccountIndex: ::codec::HasCompact, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode + for MultiAddress + where + AccountId: ::codec::Decode, + AccountId: ::codec::Decode, + AccountIndex: ::codec::HasCompact, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `MultiAddress`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Id({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Id.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Index({ + let __codec_res_edqy = <::Type as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Index.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy.into() + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Raw({ + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Raw.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 3usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Address32({ + let __codec_res_edqy = <[u8; 32] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Address32.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 4usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Address20({ + let __codec_res_edqy = <[u8; 20] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Address20.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `MultiAddress`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + #[automatically_derived] + impl< + AccountId: ::core::fmt::Debug, + AccountIndex: ::core::fmt::Debug, + > ::core::fmt::Debug for MultiAddress { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + MultiAddress::Id(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Id", + &__self_0, + ) + } + MultiAddress::Index(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Index", + &__self_0, + ) + } + MultiAddress::Raw(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Raw", + &__self_0, + ) + } + MultiAddress::Address32(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Address32", + &__self_0, + ) + } + MultiAddress::Address20(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Address20", + &__self_0, + ) + } + } + } + } + impl ::scale_encode::EncodeAsType + for MultiAddress + where + AccountId: ::scale_encode::EncodeAsType, + AccountIndex: ::scale_encode::EncodeAsType, + { + #[allow(unused_variables)] + fn encode_as_type_to( + &self, + __encode_as_type_type_id: u32, + __encode_as_type_types: &::scale_encode::PortableRegistry, + __encode_as_type_out: &mut ::scale_encode::Vec, + ) -> Result<(), ::scale_encode::Error> { + match self { + Self::Id(_0) => { + ::scale_encode::Variant { + name: "Id", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Index(_0) => { + ::scale_encode::Variant { + name: "Index", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Raw(_0) => { + ::scale_encode::Variant { + name: "Raw", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Address32(_0) => { + ::scale_encode::Variant { + name: "Address32", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Address20(_0) => { + ::scale_encode::Variant { + name: "Address20", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + _ => { + ::core::panicking::panic( + "internal error: entered unreachable code", + ) + } + } + } + } + const _: () = { + pub struct Visitor( + ::core::marker::PhantomData<(AccountId, AccountIndex)>, + ); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor + for MultiAddress + where + AccountId: ::scale_decode::IntoVisitor, + ::scale_decode::Error: From< + <::Visitor as ::scale_decode::Visitor>::Error, + >, + AccountIndex: ::scale_decode::IntoVisitor, + ::scale_decode::Error: From< + <::Visitor as ::scale_decode::Visitor>::Error, + >, + { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor + for Visitor + where + AccountId: ::scale_decode::IntoVisitor, + ::scale_decode::Error: From< + <::Visitor as ::scale_decode::Visitor>::Error, + >, + AccountIndex: ::scale_decode::IntoVisitor, + ::scale_decode::Error: From< + <::Visitor as ::scale_decode::Visitor>::Error, + >, + { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = MultiAddress; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "Id" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Id({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Index" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Index({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Raw" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Raw({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Address32" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Address32({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Address20" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Address20({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + "Id", + "Index", + "Raw", + "Address32", + "Address20", + ]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo + for MultiAddress + where + AccountId: ::scale_info::TypeInfo + 'static, + AccountIndex: ::scale_info::scale::HasCompact, + AccountId: ::scale_info::TypeInfo + 'static, + AccountIndex: ::scale_info::TypeInfo + 'static, + { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "MultiAddress", + "subxt::utils::multi_address", + &[], + ), + ) + .type_params( + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + ::scale_info::TypeParameter::new( + "AccountId", + ::core::option::Option::Some( + ::scale_info::meta_type::(), + ), + ), + ::scale_info::TypeParameter::new( + "AccountIndex", + ::core::option::Option::Some( + ::scale_info::meta_type::(), + ), + ), + ]), + ), + ) + .docs( + &[ + "A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's", + "`sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion", + "functionality is provided via `From` impls if the `substrate-compat` feature is enabled).", + ], + ) + .variant( + ::scale_info::build::Variants::new() + .variant( + "Id", + |v| { + v + .index(0usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::().type_name("AccountId")), + ) + .docs(&["It's an account ID (pubkey)."]) + }, + ) + .variant( + "Index", + |v| { + v + .index(1usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| { + f.compact::().type_name("AccountIndex") + }), + ) + .docs(&["It's an account index."]) + }, + ) + .variant( + "Raw", + |v| { + v + .index(2usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::>().type_name("Vec")), + ) + .docs(&["It's some arbitrary raw bytes."]) + }, + ) + .variant( + "Address32", + |v| { + v + .index(3usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 32]>().type_name("[u8; 32]")), + ) + .docs(&["It's a 32 byte representation."]) + }, + ) + .variant( + "Address20", + |v| { + v + .index(4usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 20]>().type_name("[u8; 20]")), + ) + .docs(&["Its a 20 byte representation."]) + }, + ), + ) + } + } + }; + impl From + for MultiAddress { + fn from(a: AccountId) -> Self { + Self::Id(a) + } + } + } + mod multi_signature { + //! The "default" Substrate/Polkadot Signature type. This is used in codegen, as well as signing related bits. + //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_runtime::MultiSignature` + //! for instance, to gain functionality without forcing a dependency on Substrate crates here. + use codec::{Decode, Encode}; + /// Signature container that can store known signature types. This is a simplified version of + /// `sp_runtime::MultiSignature`. To obtain more functionality, convert this into that type. + pub enum MultiSignature { + /// An Ed25519 signature. + Ed25519([u8; 64]), + /// An Sr25519 signature. + Sr25519([u8; 64]), + /// An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID). + Ecdsa([u8; 65]), + } + #[automatically_derived] + impl ::core::clone::Clone for MultiSignature { + #[inline] + fn clone(&self) -> MultiSignature { + match self { + MultiSignature::Ed25519(__self_0) => { + MultiSignature::Ed25519(::core::clone::Clone::clone(__self_0)) + } + MultiSignature::Sr25519(__self_0) => { + MultiSignature::Sr25519(::core::clone::Clone::clone(__self_0)) + } + MultiSignature::Ecdsa(__self_0) => { + MultiSignature::Ecdsa(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for MultiSignature { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; + let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; + let _: ::core::cmp::AssertParamIsEq<[u8; 65]>; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for MultiSignature {} + #[automatically_derived] + impl ::core::cmp::PartialEq for MultiSignature { + #[inline] + fn eq(&self, other: &MultiSignature) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + MultiSignature::Ed25519(__self_0), + MultiSignature::Ed25519(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MultiSignature::Sr25519(__self_0), + MultiSignature::Sr25519(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MultiSignature::Ecdsa(__self_0), + MultiSignature::Ecdsa(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Ord for MultiSignature { + #[inline] + fn cmp(&self, other: &MultiSignature) -> ::core::cmp::Ordering { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) { + ::core::cmp::Ordering::Equal => { + match (self, other) { + ( + MultiSignature::Ed25519(__self_0), + MultiSignature::Ed25519(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiSignature::Sr25519(__self_0), + MultiSignature::Sr25519(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiSignature::Ecdsa(__self_0), + MultiSignature::Ecdsa(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for MultiSignature { + #[inline] + fn partial_cmp( + &self, + other: &MultiSignature, + ) -> ::core::option::Option<::core::cmp::Ordering> { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + match (self, other) { + ( + MultiSignature::Ed25519(__self_0), + MultiSignature::Ed25519(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + ( + MultiSignature::Sr25519(__self_0), + MultiSignature::Sr25519(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + ( + MultiSignature::Ecdsa(__self_0), + MultiSignature::Ecdsa(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for MultiSignature { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + MultiSignature::Ed25519(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiSignature::Sr25519(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiSignature::Ecdsa(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + _ => 0_usize, + } + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + match *self { + MultiSignature::Ed25519(ref aa) => { + __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiSignature::Sr25519(ref aa) => { + __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiSignature::Ecdsa(ref aa) => { + __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::codec::EncodeLike for MultiSignature {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for MultiSignature { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `MultiSignature`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiSignature::Ed25519({ + let __codec_res_edqy = <[u8; 64] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiSignature::Ed25519.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiSignature::Sr25519({ + let __codec_res_edqy = <[u8; 64] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiSignature::Sr25519.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiSignature::Ecdsa({ + let __codec_res_edqy = <[u8; 65] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiSignature::Ecdsa.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `MultiSignature`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for MultiSignature { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + MultiSignature::Ed25519(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Ed25519", + &__self_0, + ) + } + MultiSignature::Sr25519(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Sr25519", + &__self_0, + ) + } + MultiSignature::Ecdsa(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Ecdsa", + &__self_0, + ) + } + } + } + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for MultiSignature { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "MultiSignature", + "subxt::utils::multi_signature", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .docs( + &[ + "Signature container that can store known signature types. This is a simplified version of", + "`sp_runtime::MultiSignature`. To obtain more functionality, convert this into that type.", + ], + ) + .variant( + ::scale_info::build::Variants::new() + .variant( + "Ed25519", + |v| { + v + .index(0usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 64]>().type_name("[u8; 64]")), + ) + .docs(&["An Ed25519 signature."]) + }, + ) + .variant( + "Sr25519", + |v| { + v + .index(1usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 64]>().type_name("[u8; 64]")), + ) + .docs(&["An Sr25519 signature."]) + }, + ) + .variant( + "Ecdsa", + |v| { + v + .index(2usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 65]>().type_name("[u8; 65]")), + ) + .docs( + &[ + "An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID).", + ], + ) + }, + ), + ) + } + } + }; + } + mod static_type { + use codec::{Decode, Encode}; + use scale_decode::{visitor::DecodeAsTypeResult, IntoVisitor, Visitor}; + use scale_encode::EncodeAsType; + /// If the type inside this implements [`Encode`], this will implement [`scale_encode::EncodeAsType`]. + /// If the type inside this implements [`Decode`], this will implement [`scale_decode::DecodeAsType`]. + /// + /// In either direction, we ignore any type information and just attempt to encode/decode statically + /// via the [`Encode`] and [`Decode`] implementations. This can be useful as an adapter for types which + /// do not implement [`scale_encode::EncodeAsType`] and [`scale_decode::DecodeAsType`] themselves, but + /// it's best to avoid using it where possible as it will not take into account any type information, + /// and is thus more likely to encode or decode incorrectly. + pub struct Static(pub T); + #[automatically_derived] + impl ::core::fmt::Debug for Static { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Static", &&self.0) + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for Static + where + T: ::codec::Encode, + T: ::codec::Encode, + { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.0) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.0) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.0, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike for Static + where + T: ::codec::Encode, + T: ::codec::Encode, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for Static + where + T: ::codec::Decode, + T: ::codec::Decode, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok( + Static::< + T, + >({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `Static.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + } + } + }; + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Static {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Static { + #[inline] + fn eq(&self, other: &Static) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Static { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Static { + #[inline] + fn clone(&self) -> Static { + Static(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Static { + #[inline] + fn partial_cmp( + &self, + other: &Static, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Static { + #[inline] + fn cmp(&self, other: &Static) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::hash::Hash for Static { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + impl EncodeAsType for Static { + fn encode_as_type_to( + &self, + _type_id: u32, + _types: &scale_decode::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + self.0.encode_to(out); + Ok(()) + } + } + pub struct StaticDecodeAsTypeVisitor(std::marker::PhantomData); + impl Visitor for StaticDecodeAsTypeVisitor { + type Value<'scale, 'info> = Static; + type Error = scale_decode::Error; + fn unchecked_decode_as_type<'scale, 'info>( + self, + input: &mut &'scale [u8], + _type_id: scale_decode::visitor::TypeId, + _types: &'info scale_info::PortableRegistry, + ) -> DecodeAsTypeResult< + Self, + Result, Self::Error>, + > { + use scale_decode::{visitor::DecodeError, Error}; + let decoded = T::decode(input) + .map(Static) + .map_err(|e| Error::new(DecodeError::CodecError(e).into())); + DecodeAsTypeResult::Decoded(decoded) + } + } + impl IntoVisitor for Static { + type Visitor = StaticDecodeAsTypeVisitor; + fn into_visitor() -> Self::Visitor { + StaticDecodeAsTypeVisitor(std::marker::PhantomData) + } + } + impl From for Static { + fn from(value: T) -> Self { + Static(value) + } + } + impl std::ops::Deref for Static { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl std::ops::DerefMut for Static { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + } + mod unchecked_extrinsic { + //! The "default" Substrate/Polkadot UncheckedExtrinsic. + //! This is used in codegen for runtime API calls. + //! + //! The inner bytes represent the encoded extrinsic expected by the + //! runtime APIs. Deriving `EncodeAsType` would lead to the inner + //! bytes to be re-encoded (length prefixed). + use std::marker::PhantomData; + use codec::{Decode, Encode}; + use scale_decode::{ + visitor::DecodeAsTypeResult, DecodeAsType, IntoVisitor, Visitor, + }; + use super::{Encoded, Static}; + /// The unchecked extrinsic from substrate. + pub struct UncheckedExtrinsic( + Static, + #[codec(skip)] + PhantomData<(Address, Call, Signature, Extra)>, + ); + #[automatically_derived] + impl< + Address: ::core::clone::Clone, + Call: ::core::clone::Clone, + Signature: ::core::clone::Clone, + Extra: ::core::clone::Clone, + > ::core::clone::Clone for UncheckedExtrinsic { + #[inline] + fn clone(&self) -> UncheckedExtrinsic { + UncheckedExtrinsic( + ::core::clone::Clone::clone(&self.0), + ::core::clone::Clone::clone(&self.1), + ) + } + } + #[automatically_derived] + impl< + Address: ::core::fmt::Debug, + Call: ::core::fmt::Debug, + Signature: ::core::fmt::Debug, + Extra: ::core::fmt::Debug, + > ::core::fmt::Debug for UncheckedExtrinsic { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field2_finish( + f, + "UncheckedExtrinsic", + &self.0, + &&self.1, + ) + } + } + #[automatically_derived] + impl< + Address: ::core::cmp::Eq, + Call: ::core::cmp::Eq, + Signature: ::core::cmp::Eq, + Extra: ::core::cmp::Eq, + > ::core::cmp::Eq for UncheckedExtrinsic { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq< + PhantomData<(Address, Call, Signature, Extra)>, + >; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for UncheckedExtrinsic {} + #[automatically_derived] + impl< + Address: ::core::cmp::PartialEq, + Call: ::core::cmp::PartialEq, + Signature: ::core::cmp::PartialEq, + Extra: ::core::cmp::PartialEq, + > ::core::cmp::PartialEq + for UncheckedExtrinsic { + #[inline] + fn eq( + &self, + other: &UncheckedExtrinsic, + ) -> bool { + self.0 == other.0 && self.1 == other.1 + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode + for UncheckedExtrinsic { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.0) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.0) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.0, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike + for UncheckedExtrinsic {} + }; + impl< + Address, + Call, + Signature, + Extra, + > UncheckedExtrinsic { + /// Construct a new [`UncheckedExtrinsic`]. + pub fn new(bytes: Vec) -> Self { + Self(Static(Encoded(bytes)), PhantomData) + } + /// Get the bytes of the encoded extrinsic. + pub fn bytes(&self) -> &[u8] { + self.0.0.0.as_slice() + } + } + impl Decode + for UncheckedExtrinsic { + fn decode(input: &mut I) -> Result { + let xt_vec: Vec = Decode::decode(input)?; + Ok(UncheckedExtrinsic::new(xt_vec)) + } + } + impl scale_encode::EncodeAsType + for UncheckedExtrinsic { + fn encode_as_type_to( + &self, + type_id: u32, + types: &scale_info::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + self.0.encode_as_type_to(type_id, types, out) + } + } + impl From> + for UncheckedExtrinsic { + fn from(bytes: Vec) -> Self { + UncheckedExtrinsic::new(bytes) + } + } + impl< + Address, + Call, + Signature, + Extra, + > From> for Vec { + fn from(bytes: UncheckedExtrinsic) -> Self { + bytes.0.0.0 + } + } + pub struct UncheckedExtrinsicDecodeAsTypeVisitor< + Address, + Call, + Signature, + Extra, + >( + PhantomData<(Address, Call, Signature, Extra)>, + ); + impl Visitor + for UncheckedExtrinsicDecodeAsTypeVisitor { + type Value<'scale, 'info> = UncheckedExtrinsic< + Address, + Call, + Signature, + Extra, + >; + type Error = scale_decode::Error; + fn unchecked_decode_as_type<'scale, 'info>( + self, + input: &mut &'scale [u8], + type_id: scale_decode::visitor::TypeId, + types: &'info scale_info::PortableRegistry, + ) -> DecodeAsTypeResult< + Self, + Result, Self::Error>, + > { + DecodeAsTypeResult::Decoded( + Self::Value::decode_as_type(input, type_id.0, types), + ) + } + } + impl IntoVisitor + for UncheckedExtrinsic { + type Visitor = UncheckedExtrinsicDecodeAsTypeVisitor< + Address, + Call, + Signature, + Extra, + >; + fn into_visitor() -> Self::Visitor { + UncheckedExtrinsicDecodeAsTypeVisitor(PhantomData) + } + } + } + mod wrapper_opaque { + use super::PhantomDataSendSync; + use codec::{Compact, Decode, DecodeAll, Encode}; + use derivative::Derivative; + use scale_decode::{IntoVisitor, Visitor}; + use scale_encode::EncodeAsType; + /// A wrapper for any type `T` which implement encode/decode in a way compatible with `Vec`. + /// [`WrapperKeepOpaque`] stores the type only in its opaque format, aka as a `Vec`. To + /// access the real type `T` [`Self::try_decode`] needs to be used. + #[derivative( + Debug(bound = ""), + Clone(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Default(bound = ""), + Hash(bound = "") + )] + pub struct WrapperKeepOpaque { + data: Vec, + _phantom: PhantomDataSendSync, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for WrapperKeepOpaque { + fn clone(&self) -> Self { + match *self { + WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { + WrapperKeepOpaque { + data: (*__arg_0).clone(), + _phantom: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for WrapperKeepOpaque { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { + let mut __debug_trait_builder = __f + .debug_struct("WrapperKeepOpaque"); + let _ = __debug_trait_builder.field("data", &&(*__arg_0)); + let _ = __debug_trait_builder.field("_phantom", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::default::Default for WrapperKeepOpaque { + fn default() -> Self { + WrapperKeepOpaque { + data: ::std::default::Default::default(), + _phantom: ::std::default::Default::default(), + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for WrapperKeepOpaque {} + #[allow(unused_qualifications)] + impl ::std::hash::Hash for WrapperKeepOpaque { + fn hash<__HT>(&self, __state: &mut __HT) + where + __HT: ::std::hash::Hasher, + { + match *self { + WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { + ::std::hash::Hash::hash(&(*__arg_0), __state); + ::std::hash::Hash::hash(&(*__arg_1), __state); + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for WrapperKeepOpaque { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + WrapperKeepOpaque { + data: ref __self_0, + _phantom: ref __self_1, + } => { + match *other { + WrapperKeepOpaque { + data: ref __other_0, + _phantom: ref __other_1, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + } + } + } + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for WrapperKeepOpaque + where + PhantomDataSendSync: ::codec::Encode, + PhantomDataSendSync: ::codec::Encode, + { + fn size_hint(&self) -> usize { + 0_usize + .saturating_add(::codec::Encode::size_hint(&self.data)) + .saturating_add(::codec::Encode::size_hint(&self._phantom)) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&self.data, __codec_dest_edqy); + ::codec::Encode::encode_to(&self._phantom, __codec_dest_edqy); + } + } + #[automatically_derived] + impl ::codec::EncodeLike for WrapperKeepOpaque + where + PhantomDataSendSync: ::codec::Encode, + PhantomDataSendSync: ::codec::Encode, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for WrapperKeepOpaque + where + PhantomDataSendSync: ::codec::Decode, + PhantomDataSendSync: ::codec::Decode, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(WrapperKeepOpaque:: { + data: { + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `WrapperKeepOpaque::data`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + _phantom: { + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `WrapperKeepOpaque::_phantom`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + impl WrapperKeepOpaque { + /// Try to decode the wrapped type from the inner `data`. + /// + /// Returns `None` if the decoding failed. + pub fn try_decode(&self) -> Option + where + T: Decode, + { + T::decode_all(&mut &self.data[..]).ok() + } + /// Returns the length of the encoded `T`. + pub fn encoded_len(&self) -> usize { + self.data.len() + } + /// Returns the encoded data. + pub fn encoded(&self) -> &[u8] { + &self.data + } + /// Create from the given encoded `data`. + pub fn from_encoded(data: Vec) -> Self { + Self { + data, + _phantom: PhantomDataSendSync::new(), + } + } + /// Create from some raw value by encoding it. + pub fn from_value(value: T) -> Self + where + T: Encode, + { + Self { + data: value.encode(), + _phantom: PhantomDataSendSync::new(), + } + } + } + impl EncodeAsType for WrapperKeepOpaque { + fn encode_as_type_to( + &self, + type_id: u32, + types: &scale_info::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + use scale_encode::error::{Error, ErrorKind, Kind}; + let Some(ty) = types.resolve(type_id) else { + return Err(Error::new(ErrorKind::TypeNotFound(type_id))); + }; + let scale_info::TypeDef::Composite(_) = &ty.type_def else { + return Err( + Error::new(ErrorKind::WrongShape { + actual: Kind::Struct, + expected: type_id, + }), + ); + }; + if ty.path.ident().as_deref() != Some("WrapperKeepOpaque") { + return Err( + Error::new(ErrorKind::WrongShape { + actual: Kind::Struct, + expected: type_id, + }), + ); + } + self.data.encode_to(out); + Ok(()) + } + } + pub struct WrapperKeepOpaqueVisitor(std::marker::PhantomData); + impl Visitor for WrapperKeepOpaqueVisitor { + type Value<'scale, 'info> = WrapperKeepOpaque; + type Error = scale_decode::Error; + fn visit_composite<'scale, 'info>( + self, + value: &mut scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + use scale_decode::error::{Error, ErrorKind}; + if value.path().ident().as_deref() != Some("WrapperKeepOpaque") { + return Err( + Error::custom_str( + "Type to decode is not 'WrapperTypeKeepOpaque'", + ), + ); + } + if value.remaining() != 2 { + return Err( + Error::new(ErrorKind::WrongLength { + actual_len: value.remaining(), + expected_len: 2, + }), + ); + } + let Compact(len) = value + .decode_item(Compact::::into_visitor()) + .expect("length checked")?; + let field = value.next().expect("length checked")?; + if field.bytes().len() != len as usize { + return Err( + Error::custom_str( + "WrapperTypeKeepOpaque compact encoded length doesn't line up with encoded byte len", + ), + ); + } + Ok(WrapperKeepOpaque { + data: field.bytes().to_vec(), + _phantom: PhantomDataSendSync::new(), + }) + } + } + impl IntoVisitor for WrapperKeepOpaque { + type Visitor = WrapperKeepOpaqueVisitor; + fn into_visitor() -> Self::Visitor { + WrapperKeepOpaqueVisitor(std::marker::PhantomData) + } + } + } + use crate::error::RpcError; + use crate::Error; + use codec::{Compact, Decode, Encode}; + use derivative::Derivative; + use url::Url; + pub use account_id::AccountId32; + pub use era::Era; + pub use multi_address::MultiAddress; + pub use multi_signature::MultiSignature; + pub use static_type::Static; + pub use unchecked_extrinsic::UncheckedExtrinsic; + pub use wrapper_opaque::WrapperKeepOpaque; + #[doc(hidden)] + pub use primitive_types::{H160, H256, H512}; + /// Wraps an already encoded byte vector, prevents being encoded as a raw byte vector as part of + /// the transaction payload + pub struct Encoded(pub Vec); + #[automatically_derived] + impl ::core::clone::Clone for Encoded { + #[inline] + fn clone(&self) -> Encoded { + Encoded(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Encoded { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Encoded", &&self.0) + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Encoded { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Encoded {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Encoded { + #[inline] + fn eq(&self, other: &Encoded) -> bool { + self.0 == other.0 + } + } + impl codec::Encode for Encoded { + fn encode(&self) -> Vec { + self.0.to_owned() + } + } + /// Decodes a compact encoded value from the beginning of the provided bytes, + /// returning the value and any remaining bytes. + pub(crate) fn strip_compact_prefix( + bytes: &[u8], + ) -> Result<(u64, &[u8]), codec::Error> { + let cursor = &mut &*bytes; + let val = >::decode(cursor)?; + Ok((val.0, *cursor)) + } + /// A URL is considered secure if it uses a secure scheme ("https" or "wss") or is referring to localhost. + /// + /// Returns an error if the the string could not be parsed into a URL. + pub fn url_is_secure(url: &str) -> Result { + let url = Url::parse(url) + .map_err(|e| Error::Rpc(RpcError::ClientError(Box::new(e))))?; + let secure_scheme = url.scheme() == "https" || url.scheme() == "wss"; + let is_localhost = url + .host() + .is_some_and(|e| match e { + url::Host::Domain(e) => e == "localhost", + url::Host::Ipv4(e) => e.is_loopback(), + url::Host::Ipv6(e) => e.is_loopback(), + }); + Ok(secure_scheme || is_localhost) + } + /// Validates, that the given Url is secure ("https" or "wss" scheme) or is referring to localhost. + pub fn validate_url_is_secure(url: &str) -> Result<(), Error> { + if !url_is_secure(url)? { + Err(Error::Rpc(crate::error::RpcError::InsecureUrl(url.into()))) + } else { + Ok(()) + } + } + /// A version of [`std::marker::PhantomData`] that is also Send and Sync (which is fine + /// because regardless of the generic param, it is always possible to Send + Sync this + /// 0 size type). + #[derivative( + Clone(bound = ""), + PartialEq(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + Default(bound = ""), + Hash(bound = "") + )] + #[scale_info(skip_type_params(T))] + #[doc(hidden)] + pub struct PhantomDataSendSync(core::marker::PhantomData); + #[allow(unused_qualifications)] + impl ::std::clone::Clone for PhantomDataSendSync { + fn clone(&self) -> Self { + match *self { + PhantomDataSendSync(ref __arg_0) => { + PhantomDataSendSync((*__arg_0).clone()) + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for PhantomDataSendSync { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + PhantomDataSendSync(ref __arg_0) => { + let mut __debug_trait_builder = __f + .debug_tuple("PhantomDataSendSync"); + let _ = __debug_trait_builder.field(&&(*__arg_0)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::default::Default for PhantomDataSendSync { + fn default() -> Self { + PhantomDataSendSync(::std::default::Default::default()) + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for PhantomDataSendSync {} + #[allow(unused_qualifications)] + impl ::std::hash::Hash for PhantomDataSendSync { + fn hash<__HT>(&self, __state: &mut __HT) + where + __HT: ::std::hash::Hasher, + { + match *self { + PhantomDataSendSync(ref __arg_0) => { + ::std::hash::Hash::hash(&(*__arg_0), __state); + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for PhantomDataSendSync { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + PhantomDataSendSync(ref __self_0) => { + match *other { + PhantomDataSendSync(ref __other_0) => { + true && &(*__self_0) == &(*__other_0) + } + } + } + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for PhantomDataSendSync + where + core::marker::PhantomData: ::codec::Encode, + core::marker::PhantomData: ::codec::Encode, + { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.0) + } + fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>( + &self, + __codec_dest_edqy: &mut __CodecOutputEdqy, + ) { + ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.0) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.0, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike for PhantomDataSendSync + where + core::marker::PhantomData: ::codec::Encode, + core::marker::PhantomData: ::codec::Encode, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for PhantomDataSendSync + where + core::marker::PhantomData: ::codec::Decode, + core::marker::PhantomData: ::codec::Decode, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok( + PhantomDataSendSync::< + T, + >({ + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `PhantomDataSendSync.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for PhantomDataSendSync + where + core::marker::PhantomData: ::scale_info::TypeInfo + 'static, + T: 'static, + { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "PhantomDataSendSync", + "subxt::utils", + &[], + ), + ) + .type_params( + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + ::scale_info::TypeParameter::new( + "T", + ::core::option::Option::None, + ), + ]), + ), + ) + .docs( + &[ + "A version of [`std::marker::PhantomData`] that is also Send and Sync (which is fine", + "because regardless of the generic param, it is always possible to Send + Sync this", + "0 size type).", + ], + ) + .composite( + ::scale_info::build::Fields::unnamed() + .field(|f| { + f + .ty::>() + .type_name("core::marker::PhantomData") + }), + ) + } + } + }; + impl PhantomDataSendSync { + pub(crate) fn new() -> Self { + Self(core::marker::PhantomData) + } + } + unsafe impl Send for PhantomDataSendSync {} + unsafe impl Sync for PhantomDataSendSync {} + /// This represents a key-value collection and is SCALE compatible + /// with collections like BTreeMap. This has the same type params + /// as `BTreeMap` which allows us to easily swap the two during codegen. + pub type KeyedVec = Vec<(K, V)>; +} +#[macro_use] +mod macros { + pub(crate) use { + cfg_feature, cfg_jsonrpsee, cfg_reconnecting_rpc_client, cfg_substrate_compat, + cfg_unstable_light_client, + }; + #[allow(unused)] + pub(crate) use {cfg_jsonrpsee_native, cfg_jsonrpsee_web}; +} +pub use crate::{ + client::{OfflineClient, OnlineClient}, + config::{Config, PolkadotConfig, SubstrateConfig}, + error::Error, metadata::Metadata, +}; +/// Re-export external crates that are made use of in the subxt API. +pub mod ext { + pub use codec; + pub use frame_metadata; + pub use futures; + pub use scale_bits; + pub use scale_decode; + pub use scale_encode; + pub use scale_value; +} +/// Generate a strongly typed API for interacting with a Substrate runtime from its metadata. +/// +/// # Metadata +/// +/// First, you'll need to get hold of some metadata for the node you'd like to interact with. One +/// way to do this is by using the `subxt` CLI tool: +/// +/// ```bash +/// # Install the CLI tool: +/// cargo install subxt-cli +/// # Use it to download metadata (in this case, from a node running locally) +/// subxt metadata > polkadot_metadata.scale +/// ``` +/// +/// Run `subxt metadata --help` for more options. +/// +/// # Basic usage +/// +/// Annotate a Rust module with the `subxt` attribute referencing the aforementioned metadata file. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// )] +/// mod polkadot {} +/// ``` +/// +/// The `subxt` macro will populate the annotated module with all of the methods and types required +/// for interacting with the runtime that the metadata is in via Subxt. +/// +/// # Configuration +/// +/// This macro supports a number of attributes to configure what is generated: +/// +/// ## `crate = "..."` +/// +/// Use this attribute to specify a custom path to the `subxt` crate: +/// +/// ```rust +/// # pub extern crate subxt; +/// # pub mod path { pub mod to { pub use subxt; } } +/// # fn main() {} +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// crate = "crate::path::to::subxt" +/// )] +/// mod polkadot {} +/// ``` +/// +/// This is useful if you write a library which uses this macro, but don't want to force users to depend on `subxt` +/// at the top level too. By default the path `::subxt` is used. +/// +/// ## `substitute_type(path = "...", with = "...")` +/// +/// This attribute replaces any reference to the generated type at the path given by `path` with a +/// reference to the path given by `with`. +/// +/// ```rust +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// substitute_type(path = "sp_arithmetic::per_things::Perbill", with = "crate::Foo") +/// )] +/// mod polkadot {} +/// +/// # #[derive( +/// # scale_encode::EncodeAsType, +/// # scale_decode::DecodeAsType, +/// # codec::Encode, +/// # codec::Decode, +/// # Clone, +/// # Debug, +/// # )] +/// // In reality this needs some traits implementing on +/// // it to allow it to be used in place of Perbill: +/// pub struct Foo(u32); +/// # impl codec::CompactAs for Foo { +/// # type As = u32; +/// # fn encode_as(&self) -> &Self::As { +/// # &self.0 +/// # } +/// # fn decode_from(x: Self::As) -> Result { +/// # Ok(Foo(x)) +/// # } +/// # } +/// # impl From> for Foo { +/// # fn from(v: codec::Compact) -> Foo { +/// # v.0 +/// # } +/// # } +/// # fn main() {} +/// ``` +/// +/// If the type you're substituting contains generic parameters, you can "pattern match" on those, and +/// make use of them in the substituted type, like so: +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// substitute_type( +/// path = "sp_runtime::multiaddress::MultiAddress", +/// with = "::subxt::utils::Static<::sp_runtime::MultiAddress>" +/// ) +/// )] +/// mod polkadot {} +/// ``` +/// +/// The above is also an example of using the [`crate::utils::Static`] type to wrap some type which doesn't +/// on it's own implement [`scale_encode::EncodeAsType`] or [`scale_decode::DecodeAsType`], which are required traits +/// for any substitute type to implement by default. +/// +/// ## `derive_for_all_types = "..."` +/// +/// By default, all generated types derive a small set of traits. This attribute allows you to derive additional +/// traits on all generated types: +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// derive_for_all_types = "Eq, PartialEq" +/// )] +/// mod polkadot {} +/// ``` +/// +/// Any substituted types (including the default substitutes) must also implement these traits in order to avoid errors +/// here. +/// +/// ## `derive_for_type(path = "...", derive = "...")` +/// +/// Unlike the above, which derives some trait on every generated type, this attribute allows you to derive traits only +/// for specific types. Note that any types which are used inside the specified type may also need to derive the same traits. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// derive_for_all_types = "Eq, PartialEq", +/// derive_for_type(path = "frame_support::PalletId", derive = "Ord, PartialOrd"), +/// derive_for_type(path = "sp_runtime::ModuleError", derive = "Hash"), +/// )] +/// mod polkadot {} +/// ``` +/// +/// ## `runtime_metadata_insecure_url = "..."` +/// +/// This attribute can be used instead of `runtime_metadata_path` and will tell the macro to download metadata from a node running +/// at the provided URL, rather than a node running locally. This can be useful in CI, but is **not recommended** in production code, +/// since it runs at compile time and will cause compilation to fail if the node at the given address is unavailable or unresponsive. +/// +/// ```rust,ignore +/// #[subxt::subxt( +/// runtime_metadata_insecure_url = "wss://rpc.polkadot.io:443" +/// )] +/// mod polkadot {} +/// ``` +/// +/// ## `generate_docs` +/// +/// By default, documentation is not generated via the macro, since IDEs do not typically make use of it. This attribute +/// forces documentation to be generated, too. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// generate_docs +/// )] +/// mod polkadot {} +/// ``` +/// +/// ## `runtime_types_only` +/// +/// By default, the macro will generate various interfaces to make using Subxt simpler in addition with any types that need +/// generating to make this possible. This attribute makes the codegen only generate the types and not the Subxt interface. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// runtime_types_only +/// )] +/// mod polkadot {} +/// ``` +/// +/// ## `no_default_derives` +/// +/// By default, the macro will add all derives necessary for the generated code to play nicely with Subxt. Adding this attribute +/// removes all default derives. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// runtime_types_only, +/// no_default_derives, +/// derive_for_all_types="codec::Encode, codec::Decode" +/// )] +/// mod polkadot {} +/// ``` +/// +/// **Note**: At the moment, you must derive at least one of `codec::Encode` or `codec::Decode` or `scale_encode::EncodeAsType` or +/// `scale_decode::DecodeAsType` (because we add `#[codec(..)]` attributes on some fields/types during codegen), and you must use this +/// feature in conjunction with `runtime_types_only` (or manually specify a bunch of defaults to make codegen work properly when +/// generating the subxt interfaces). +/// +/// ## `unstable_metadata` +/// +/// This attribute works only in combination with `runtime_metadata_insecure_url`. By default, the macro will fetch the latest stable +/// version of the metadata from the target node. This attribute makes the codegen attempt to fetch the unstable version of +/// the metadata first. This is **not recommended** in production code, since the unstable metadata a node is providing is likely +/// to be incompatible with Subxt. +/// +/// ```rust,ignore +/// #[subxt::subxt( +/// runtime_metadata_insecure_url = "wss://rpc.polkadot.io:443", +/// unstable_metadata +/// )] +/// mod polkadot {} +/// ``` +pub use subxt_macro::subxt; diff --git a/subxt/expand.txt b/subxt/expand.txt new file mode 100644 index 0000000000..e3eef50a0a --- /dev/null +++ b/subxt/expand.txt @@ -0,0 +1,44181 @@ +#![feature(prelude_import)] +//! Subxt is a library for interacting with Substrate based nodes. Using it looks something like this: +//! +//! ```rust,ignore +/*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let from = dev::alice(); + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} +*/ +//! ``` +//! +//! Take a look at [the Subxt guide](book) to learn more about how to use Subxt. +#[prelude_import] +use std::prelude::rust_2021::*; +#[macro_use] +extern crate std; +pub mod book { + //! # The Subxt Guide + //! + //! Subxt is a library for interacting with Substrate based nodes. It has a focus on **sub**mitting + //! e**xt**rinsics, hence the name, however it's also capable of reading blocks, storage, events and + //! constants from a node. The aim of this guide is to explain key concepts and get you started with + //! using Subxt. + //! + //! 1. [Features](#features-at-a-glance) + //! 2. [Limitations](#limitations) + //! 3. [Quick start](#quick-start) + //! 4. [Usage](#usage) + //! + //! ## Features at a glance + //! + //! Here's a quick overview of the features that Subxt has to offer: + //! + //! - Subxt allows you to generate a static, type safe interface to a node given some metadata; this + //! allows you to catch many errors at compile time rather than runtime. + //! - Subxt also makes heavy use of node metadata to encode/decode the data sent to/from it. This + //! allows it to target almost any node which can output the correct metadata, and allows it some + //! flexibility in encoding and decoding things to account for cross-node differences. + //! - Subxt has a pallet-oriented interface, meaning that code you write to talk to some pallet on + //! one node will often "Just Work" when pointed at different nodes that use the same pallet. + //! - Subxt can work offline; you can generate and sign transactions, access constants from node + //! metadata and more, without a network connection. This is all checked at compile time, so you + //! can be certain it won't try to establish a network connection if you don't want it to. + //! - Subxt can forego the statically generated interface and build transactions, storage queries + //! and constant queries using data provided at runtime, rather than queries constructed + //! statically. + //! - Subxt can be compiled to WASM to run in the browser, allowing it to back Rust based browser + //! apps, or even bind to JS apps. + //! + //! ## Limitations + //! + //! In various places, you can provide a block hash to access data at a particular block, for + //! instance: + //! + //! - [`crate::storage::StorageClient::at`] + //! - [`crate::events::EventsClient::at`] + //! - [`crate::blocks::BlocksClient::at`] + //! - [`crate::runtime_api::RuntimeApiClient::at`] + //! + //! However, Subxt is (by default) only capable of properly working with blocks that were produced + //! after the most recent runtime update. This is because it uses the most recent metadata given + //! back by a node to encode and decode things. It's possible to decode older blocks produced by a + //! runtime that emits compatible (currently, V14) metadata by manually setting the metadata used by + //! the client using [`crate::client::OnlineClient::set_metadata()`]. + //! + //! Subxt does not support working with blocks produced prior to the runtime update that introduces + //! V14 metadata. It may have some success decoding older blocks using newer metadata, but may also + //! completely fail to do so. + //! + //! ## Quick start + //! + //! Here is a simple but complete example of using Subxt to transfer some tokens from the example + //! accounts, Alice to Bob: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let from = dev::alice(); + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} +*/ + //! ``` + //! + //! This example assumes that a Polkadot node is running locally (Subxt endeavors to support all + //! recent releases). Typically, to use Subxt to talk to some custom Substrate node (for example a + //! parachain node), you'll want to: + //! + //! 1. [Generate an interface](setup::codegen) + //! 2. [Create a config](setup::config) + //! 3. [Use the config to instantiate the client](setup::client) + //! + //! Follow the above links to learn more about each step. + //! + //! ## Usage + //! + //! Once Subxt is configured, the next step is interacting with a node. Follow the links + //! below to learn more about how to use Subxt for each of the following things: + //! + //! - [Transactions](usage::transactions): Subxt can build and submit transactions, wait until they are in + //! blocks, and retrieve the associated events. + //! - [Storage](usage::storage): Subxt can query the node storage. + //! - [Events](usage::events): Subxt can read the events emitted for recent blocks. + //! - [Constants](usage::constants): Subxt can access the constant values stored in a node, which + //! remain the same for a given runtime version. + //! - [Blocks](usage::blocks): Subxt can load recent blocks or subscribe to new/finalized blocks, + //! reading the extrinsics, events and storage at these blocks. + //! - [Runtime APIs](usage::runtime_apis): Subxt can make calls into pallet runtime APIs to retrieve + //! data. + //! - [Custom values](usage::custom_values): Subxt can access "custom values" stored in the metadata. + //! - [Raw RPC calls](usage::rpc): Subxt can be used to make raw RPC requests to compatible nodes. + //! + //! ## Examples + //! + //! Some complete, self contained examples which are not a part of this guide: + //! + //! - [`parachain-example`](https://github.com/paritytech/subxt/tree/master/examples/parachain-example) is an example + //! which uses Zombienet to spawn a parachain locally, and then connects to it using Subxt. + //! - [`wasm-example`](https://github.com/paritytech/subxt/tree/master/examples/wasm-example) is an example of writing + //! a Rust app that contains a Yew based UI, uses Subxt to interact with a chain, and compiles to WASM in order to + //! run entirely in the browser. + pub mod setup { + //! This modules contains details on setting up Subxt: + //! + //! - [Codegen](codegen) + //! - [Client](client) + //! + //! Alternately, [go back](super). + pub mod client { + //! # The Subxt client. + //! + //! The client forms the entry point to all of the Subxt APIs. Every client implements one or + //! both of [`crate::client::OfflineClientT`] and [`crate::client::OnlineClientT`]. + //! + //! Subxt ships with three clients which implement one or both of traits: + //! - An [online client](crate::client::OnlineClient). + //! - An [offline client](crate::client::OfflineClient). + //! - A light client (which is currently still unstable). + //! + //! In theory it's possible for users to implement their own clients, although this isn't generally + //! expected. + //! + //! The provided clients are all generic over the [`crate::config::Config`] that they accept, which + //! determines how they will interact with the chain. + //! + //! In the case of the [`crate::OnlineClient`], we have various ways to instantiate it: + //! + //! - [`crate::OnlineClient::new()`] to connect to a node running locally. This uses the default Subxt + //! backend, and the default RPC client. + //! - [`crate::OnlineClient::from_url()`] to connect to a node at a specific URL. This uses the default Subxt + //! backend, and the default RPC client. + //! - [`crate::OnlineClient::from_rpc_client()`] to instantiate the client with a [`crate::backend::rpc::RpcClient`]. + //! - [`crate::OnlineClient::from_backend()`] to instantiate Subxt using a custom backend. Currently there + //! is just one backend, [`crate::backend::legacy::LegacyBackend`]. This backend can be instantiated from + //! a [`crate::backend::rpc::RpcClient`]. + //! + //! [`crate::backend::rpc::RpcClient`] can itself be instantiated from anything that implements the low level + //! [`crate::backend::rpc::RpcClientT`] trait; this allows you to decide how Subxt will attempt to talk to a node + //! if you'd prefer something other default client. We use this approach under the hood to implement the light client. + //! + //! ## Examples + //! + //! Most of the other examples will instantiate a client. Here are a couple of examples for less common + //! cases. + //! + //! ### Writing a custom [`crate::backend::rpc::RpcClientT`] implementation: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use std::{ + fmt::Write, + pin::Pin, + sync::{Arc, Mutex}, +}; +use subxt::{ + backend::rpc::{RawRpcFuture, RawRpcSubscription, RawValue, RpcClient, RpcClientT}, + OnlineClient, PolkadotConfig, +}; + +// A dummy RPC client that doesn't actually handle requests properly +// at all, but instead just logs what requests to it were made. +struct MyLoggingClient { + log: Arc>, +} + +// We have to implement this fairly low level trait to turn [`MyLoggingClient`] +// into an RPC client that we can make use of in Subxt. Here we just log the requests +// made but don't forward them to any real node, and instead just return nonsense. +impl RpcClientT for MyLoggingClient { + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box> { + writeln!( + self.log.lock().unwrap(), + "{method}({})", + params.as_ref().map(|p| p.get()).unwrap_or("[]") + ) + .unwrap(); + + // We've logged the request; just return garbage. Because a boxed future is returned, + // you're able to run whatever async code you'd need to actually talk to a node. + let res = RawValue::from_string("[]".to_string()).unwrap(); + Box::pin(std::future::ready(Ok(res))) + } + + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription> { + writeln!( + self.log.lock().unwrap(), + "{sub}({}) (unsub: {unsub})", + params.as_ref().map(|p| p.get()).unwrap_or("[]") + ) + .unwrap(); + + // We've logged the request; just return garbage. Because a boxed future is returned, + // and that will return a boxed Stream impl, you have a bunch of flexibility to build + // and return whatever type of Stream you see fit. + let res = RawValue::from_string("[]".to_string()).unwrap(); + let stream = futures::stream::once(async move { Ok(res) }); + let stream: Pin + Send>> = Box::pin(stream); + // This subscription does not provide an ID. + Box::pin(std::future::ready(Ok(RawRpcSubscription { + stream, + id: None, + }))) + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Instantiate our replacement RPC client. + let log = Arc::default(); + let rpc_client = { + let inner = MyLoggingClient { + log: Arc::clone(&log), + }; + RpcClient::new(inner) + }; + + // Pass this into our OnlineClient to instantiate it. This will lead to some + // RPC calls being made to fetch chain details/metadata, which will immediately + // fail.. + let _ = OnlineClient::::from_rpc_client(rpc_client).await; + + // But, we can see that the calls were made via our custom RPC client: + println!("Log of calls made:\n\n{}", log.lock().unwrap().as_str()); + Ok(()) +} +*/ + //! ``` + //! + //! ### Creating an [`crate::OfflineClient`]: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::ext::codec::Decode; +use subxt::metadata::Metadata; +use subxt::utils::H256; +use subxt::{config::PolkadotConfig, OfflineClient}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // We need to obtain the following details for an OfflineClient to be instantiated: + + // 1. Genesis hash (RPC call: chain_getBlockHash(0)): + let genesis_hash = { + let h = "91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3"; + let bytes = hex::decode(h).unwrap(); + H256::from_slice(&bytes) + }; + + // 2. A runtime version (system_version constant on a Substrate node has these): + let runtime_version = subxt::backend::RuntimeVersion { + spec_version: 9370, + transaction_version: 20, + }; + + // 3. Metadata (I'll load it from the downloaded metadata, but you can use + // `subxt metadata > file.scale` to download it): + let metadata = { + let bytes = std::fs::read("./artifacts/polkadot_metadata_small.scale").unwrap(); + Metadata::decode(&mut &*bytes).unwrap() + }; + + // Create an offline client using the details obtained above: + let _api = OfflineClient::::new(genesis_hash, runtime_version, metadata); + + Ok(()) +} +*/ + //! ``` + //! + } + pub mod codegen { + //! # Generating an interface + //! + //! The simplest way to use Subxt is to generate an interface to a chain that you'd like to interact + //! with. This generated interface allows you to build transactions and construct queries to access + //! data while leveraging the full type safety of the Rust compiler. + //! + //! ## The `#[subxt]` macro + //! + //! The most common way to generate the interface is to use the [`#[subxt]`](crate::subxt) macro. + //! Using this macro looks something like: + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_tiny.scale")] + //! pub mod polkadot {} + //! ``` + //! + //! The macro takes a path to some node metadata, and uses that to generate the interface you'll use + //! to talk to it. [Go here](crate::subxt) to learn more about the options available to the macro. + //! + //! To obtain this metadata you'll need for the above, you can use the `subxt` CLI tool to download it + //! from a node. The tool can be installed via `cargo`: + //! + //! ```shell + //! cargo install subxt-cli + //! ``` + //! + //! And then it can be used to fetch metadata and save it to a file: + //! + //! ```shell + //! # Download and save all of the metadata: + //! subxt metadata > metadata.scale + //! # Download and save only the pallets you want to generate an interface for: + //! subxt metadata --pallets Balances,System > metadata.scale + //! ``` + //! + //! Explicitly specifying pallets will cause the tool to strip out all unnecessary metadata and type + //! information, making the bundle much smaller in the event that you only need to generate an + //! interface for a subset of the available pallets on the node. + //! + //! ## The CLI tool + //! + //! Using the [`#[subxt]`](crate::subxt) macro carries some downsides: + //! + //! - Using it to generate an interface will have a small impact on compile times (though much less of + //! one if you only need a few pallets). + //! - IDE support for autocompletion and documentation when using the macro interface can be poor. + //! - It's impossible to manually look at the generated code to understand and debug things. + //! + //! If these are an issue, you can manually generate the same code that the macro generates under the hood + //! by using the `subxt codegen` command: + //! + //! ```shell + //! # Install the CLI tool if you haven't already: + //! cargo install subxt-cli + //! # Generate and format rust code, saving it to `interface.rs`: + //! subxt codegen | rustfmt > interface.rs + //! ``` + //! + //! Use `subxt codegen --help` for more options; many of the options available via the macro are + //! also available via the CLI tool, such as the ability to substitute generated types for others, + //! or strip out docs from the generated code. + //! + } + pub mod config { + //! # Creating a Config + //! + //! Subxt requires you to provide a type implementing [`crate::config::Config`] in order to connect to a node. + //! The [`crate::config::Config`] trait for the most part mimics the `frame_system::Config` trait. + //! For most use cases, you can just use one of the following Configs shipped with Subxt: + //! + //! - [`PolkadotConfig`](crate::config::PolkadotConfig) for talking to Polkadot nodes, and + //! - [`SubstrateConfig`](crate::config::SubstrateConfig) for talking to generic nodes built with Substrate. + //! + //! # How to create a Config for a custom chain? + //! + //! Some chains may use config that is not compatible with our [`PolkadotConfig`](crate::config::PolkadotConfig) or + //! [`SubstrateConfig`](crate::config::SubstrateConfig). + //! + //! We now walk through creating a custom [`crate::config::Config`] for a parachain, using the + //! ["Statemint"](https://parachains.info/details/statemint) parachain, also known as "Asset Hub", as an example. It + //! is currently (as of 2023-06-26) deployed on Polkadot and [Kusama (as "Statemine")](https://parachains.info/details/statemine). + //! + //! To construct a valid [`crate::config::Config`] implementation, we need to find out which types to use for `AccountId`, `Hasher`, etc. + //! For this, we need to take a look at the source code of Statemint, which is currently a part of the [Cumulus Github repository](https://github.com/paritytech/cumulus). + //! The crate defining the asset hub runtime can be found [here](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/assets/asset-hub-polkadot). + //! + //! ## `AccountId`, `Hash`, `Hasher` and `Header` + //! + //! For these config types, we need to find out where the parachain runtime implements the `frame_system::Config` trait. + //! Look for a code fragment like `impl frame_system::Config for Runtime { ... }` In the source code. + //! For Statemint it looks like [this](https://github.com/paritytech/cumulus/blob/e2b7ad2061824f490c08df27a922c64f50accd6b/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs#L179) + //! at the time of writing. The `AccountId`, `Hash` and `Header` types of the [frame_system::pallet::Config](https://docs.rs/frame-system/latest/frame_system/pallet/trait.Config.html) + //! correspond to the ones we want to use in our Subxt [crate::Config]. In the Case of Statemint (Asset Hub) they are: + //! + //! - AccountId: `sp_core::crypto::AccountId32` + //! - Hash: `sp_core::H256` + //! - Hasher (type `Hashing` in [frame_system::pallet::Config](https://docs.rs/frame-system/latest/frame_system/pallet/trait.Config.html)): `sp_runtime::traits::BlakeTwo256` + //! - Header: `sp_runtime::generic::Header` + //! + //! Subxt has its own versions of some of these types in order to avoid needing to pull in Substrate dependencies: + //! + //! - `sp_core::crypto::AccountId32` can be swapped with [`crate::utils::AccountId32`]. + //! - `sp_core::H256` is a re-export which subxt also provides as [`crate::config::substrate::H256`]. + //! - `sp_runtime::traits::BlakeTwo256` can be swapped with [`crate::config::substrate::BlakeTwo256`]. + //! - `sp_runtime::generic::Header` can be swapped with [`crate::config::substrate::SubstrateHeader`]. + //! + //! Having a look at how those types are implemented can give some clues as to how to implement other custom types that + //! you may need to use as part of your config. + //! + //! ## `Address`, `Signature` + //! + //! A Substrate runtime is typically constructed by using the [frame_support::construct_runtime](https://docs.rs/frame-support/latest/frame_support/macro.construct_runtime.html) macro. + //! In this macro, we need to specify the type of an `UncheckedExtrinsic`. Most of the time, the `UncheckedExtrinsic` will be of the type + //! `sp_runtime::generic::UncheckedExtrinsic`. + //! The generic parameters `Address` and `Signature` specified when declaring the `UncheckedExtrinsic` type + //! are the types for `Address` and `Signature` we should use with our [crate::Config] implementation. This information can + //! also be obtained from the metadata (see [`frame_metadata::v15::ExtrinsicMetadata`]). In case of Statemint (Polkadot Asset Hub) + //! we see the following types being used in `UncheckedExtrinsic`: + //! + //! - Address: `sp_runtime::MultiAddress` + //! - Signature: `sp_runtime::MultiSignature` + //! + //! As above, Subxt has its own versions of these types that can be used instead to avoid pulling in Substrate dependencies. + //! Using the Subxt versions also makes interacting with generated code (which uses them in some places) a little nicer: + //! + //! - `sp_runtime::MultiAddress` can be swapped with [`crate::utils::MultiAddress`]. + //! - `sp_runtime::MultiSignature` can be swapped with [`crate::utils::MultiSignature`]. + //! + //! ## ExtrinsicParams + //! + //! Chains each have a set of "signed extensions" configured. Signed extensions provide a means to extend how transactions + //! work. Each signed extension can potentially encode some "extra" data which is sent along with a transaction, as well as some + //! "additional" data which is included in the transaction signer payload, but not transmitted along with the transaction. On + //! a node, signed extensions can then perform additional checks on the submitted transactions to ensure their validity. + //! + //! The `ExtrinsicParams` config type expects to be given an implementation of the [`crate::config::ExtrinsicParams`] trait. + //! Implementations of the [`crate::config::ExtrinsicParams`] trait are handed some parameters from Subxt itself, and can + //! accept arbitrary `OtherParams` from users, and are then expected to provide this "extra" and "additional" data when asked + //! via the required [`crate::config::ExtrinsicParamsEncoder`] impl. + //! + //! **In most cases, the default [crate::config::DefaultExtrinsicParams] type will work**: it understands the "standard" + //! signed extensions that are in use, and allows the user to provide things like a tip, and set the extrinsic mortality via + //! [`crate::config::DefaultExtrinsicParamsBuilder`]. It will use the chain metadata to decide which signed extensions to use + //! and in which order. It will return an error if the chain uses a signed extension which it doesn't know how to handle. + //! + //! If the chain uses novel signed extensions (or if you just wish to provide a different interface for users to configure + //! transactions), you can either: + //! + //! 1. Implement a new signed extension and add it to the list. + //! 2. Implement [`crate::config::DefaultExtrinsicParams`] from scratch. + //! + //! See below for examples of each. + //! + //! ### Finding out which signed extensions a chain is using. + //! + //! In either case, you'll want to find out which signed extensions a chain is using. This information can be obtained from + //! the `SignedExtra` parameter of the `UncheckedExtrinsic` of your parachain, which will be a tuple of signed extensions. + //! It can also be obtained from the metadata (see [`frame_metadata::v15::SignedExtensionMetadata`]). + //! + //! For statemint, the signed extensions look like + //! [this](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs#L779): + //! + //! ```rs + //! pub type SignedExtra = ( + //! frame_system::CheckNonZeroSender, + //! frame_system::CheckSpecVersion, + //! frame_system::CheckTxVersion, + //! frame_system::CheckGenesis, + //! frame_system::CheckEra, + //! frame_system::CheckNonce, + //! frame_system::CheckWeight, + //! pallet_asset_tx_payment::ChargeAssetTxPayment, + //! ); + //! ``` + //! + //! Each element of the `SignedExtra` tuple implements [codec::Encode] and `sp_runtime::traits::SignedExtension` + //! which has an associated type `AdditionalSigned` that also implements [codec::Encode]. Let's look at the underlying types + //! for each tuple element. All zero-sized types have been replaced by `()` for simplicity. + //! + //! | tuple element | struct type | `AdditionalSigned` type | + //! | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | + //! | [`frame_system::CheckNonZeroSender`](https://docs.rs/frame-system/latest/frame_system/struct.CheckNonZeroSender.html) | () | () | + //! | [`frame_system::CheckSpecVersion`](https://docs.rs/frame-system/latest/frame_system/struct.CheckSpecVersion.html) | () | [u32] | + //! | [`frame_system::CheckTxVersion`](https://docs.rs/frame-system/latest/frame_system/struct.CheckTxVersion.html) | () | [u32] | + //! | [`frame_system::CheckGenesis`](https://docs.rs/frame-system/latest/frame_system/struct.CheckGenesis.html) | () | `Config::Hash` = `sp_core::H256` | + //! | [`frame_system::CheckMortality`](https://docs.rs/frame-system/latest/frame_system/struct.CheckMortality.html) | `sp_runtime::generic::Era` | `Config::Hash` = `sp_core::H256` | + //! | [`frame_system::CheckNonce`](https://docs.rs/frame-system/latest/frame_system/struct.CheckNonce.html) | `frame_system::pallet::Config::Index` = u32 | () | + //! | [`frame_system::CheckWeight`](https://docs.rs/frame-system/latest/frame_system/struct.CheckWeight.html) | () | () | + //! | [`frame_system::ChargeAssetTxPayment`](https://docs.rs/frame-system/latest/frame_system/struct.ChargeAssetTxPayment.html) | [pallet_asset_tx_payment::ChargeAssetTxPayment](https://docs.rs/pallet-asset-tx-payment/latest/pallet_asset_tx_payment/struct.ChargeAssetTxPayment.html) | () | + //! + //! All types in the `struct type` column make up the "extra" data that we're expected to provide. All types in the + //! `AdditionalSigned` column make up the "additional" data that we're expected to provide. This information will be useful + //! whether we want to implement [`crate::config::SignedExtension`] for a signed extension, or implement + //! [`crate::config::ExtrinsicParams`] from scratch. + //! + //! As it happens, all of the signed extensions in the table are either already exported in [`crate::config::signed_extensions`], + //! or they hand back no "additional" or "extra" data. In both of these cases, the default `ExtrinsicParams` configuration will + //! work out of the box. + //! + //! ### Implementing and adding new signed extensions to the config + //! + //! If you do need to implement a novel signed extension, then you can implement [`crate::config::signed_extensions::SignedExtension`] + //! on a custom type and place it into a new set of signed extensions, like so: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use codec::Encode; +use scale_encode::EncodeAsType; +use scale_info::PortableRegistry; +use subxt::client::OfflineClientT; +use subxt::config::signed_extensions; +use subxt::config::{ + Config, DefaultExtrinsicParamsBuilder, ExtrinsicParams, ExtrinsicParamsEncoder, + ExtrinsicParamsError, +}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod runtime {} + +// We don't need to construct this at runtime, +// so an empty enum is appropriate: +#[derive(EncodeAsType)] +pub enum CustomConfig {} + +impl Config for CustomConfig { + type Hash = subxt::utils::H256; + type AccountId = subxt::utils::AccountId32; + type Address = subxt::utils::MultiAddress; + type Signature = subxt::utils::MultiSignature; + type Hasher = subxt::config::substrate::BlakeTwo256; + type Header = subxt::config::substrate::SubstrateHeader; + type ExtrinsicParams = signed_extensions::AnyOf< + Self, + ( + // Load in the existing signed extensions we're interested in + // (if the extension isn't actually needed it'll just be ignored): + signed_extensions::CheckSpecVersion, + signed_extensions::CheckTxVersion, + signed_extensions::CheckNonce, + signed_extensions::CheckGenesis, + signed_extensions::CheckMortality, + signed_extensions::ChargeAssetTxPayment, + signed_extensions::ChargeTransactionPayment, + // And add a new one of our own: + CustomSignedExtension, + ), + >; + type AssetId = u32; +} + +// Our custom signed extension doesn't do much: +pub struct CustomSignedExtension; + +// Give the extension a name; this allows `AnyOf` to look it +// up in the chain metadata in order to know when and if to use it. +impl signed_extensions::SignedExtension for CustomSignedExtension { + type Decoded = (); + fn matches(identifier: &str, _type_id: u32, _types: &PortableRegistry) -> bool { + identifier == "CustomSignedExtension" + } +} + +// Gather together any params we need for our signed extension, here none. +impl ExtrinsicParams for CustomSignedExtension { + type OtherParams = (); + + fn new>( + _nonce: u64, + _client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CustomSignedExtension) + } +} + +// Encode whatever the extension needs to provide when asked: +impl ExtrinsicParamsEncoder for CustomSignedExtension { + fn encode_extra_to(&self, v: &mut Vec) { + "Hello".encode_to(v); + } + fn encode_additional_to(&self, v: &mut Vec) { + true.encode_to(v) + } +} + +// When composing a tuple of signed extensions, the user parameters we need must +// be able to convert `Into` a tuple of corresponding `OtherParams`. Here, we just +// "hijack" the default param builder, but add the `OtherParams` (`()`) for our +// new signed extension at the end, to make the types line up. IN reality you may wish +// to construct an entirely new interface to provide the relevant `OtherParams`. +pub fn custom( + params: DefaultExtrinsicParamsBuilder, +) -> <::ExtrinsicParams as ExtrinsicParams>::OtherParams { + let (a, b, c, d, e, f, g) = params.build(); + (a, b, c, d, e, f, g, ()) +} + +#[tokio::main] +async fn main() { + // With the config defined, it can be handed to Subxt as follows: + let client = subxt::OnlineClient::::new().await.unwrap(); + + let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); + + // Configure the tx params: + let tx_config = DefaultExtrinsicParamsBuilder::new().tip(1234); + + // And provide them when submitting a transaction: + let _ = client + .tx() + .sign_and_submit_then_watch(&tx_payload, &dev::alice(), custom(tx_config)) + .await; +} +*/ + //! ``` + //! + //! ### Implementing [`crate::config::ExtrinsicParams`] from scratch + //! + //! Alternately, you are free to implement [`crate::config::ExtrinsicParams`] entirely from scratch if you know exactly what "extra" and` + //! "additional" data your node needs and would prefer to craft your own interface. + //! + //! Let's see what this looks like (this config won't work on any real node): + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use codec::Encode; +use subxt::client::OfflineClientT; +use subxt::config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] +pub mod runtime {} + +// We don't need to construct this at runtime, +// so an empty enum is appropriate: +pub enum CustomConfig {} + +impl Config for CustomConfig { + type Hash = subxt::utils::H256; + type AccountId = subxt::utils::AccountId32; + type Address = subxt::utils::MultiAddress; + type Signature = subxt::utils::MultiSignature; + type Hasher = subxt::config::substrate::BlakeTwo256; + type Header = subxt::config::substrate::SubstrateHeader; + type ExtrinsicParams = CustomExtrinsicParams; + type AssetId = u32; +} + +// This represents some arbitrary (and nonsensical) custom parameters that +// will be attached to transaction extra and additional payloads: +pub struct CustomExtrinsicParams { + genesis_hash: T::Hash, + tip: u128, + foo: bool, +} + +// We can provide a "pretty" interface to allow users to provide these: +#[derive(Default)] +pub struct CustomExtrinsicParamsBuilder { + tip: u128, + foo: bool, +} + +impl CustomExtrinsicParamsBuilder { + pub fn new() -> Self { + Default::default() + } + pub fn tip(mut self, value: u128) -> Self { + self.tip = value; + self + } + pub fn enable_foo(mut self) -> Self { + self.foo = true; + self + } +} + +// Describe how to fetch and then encode the params: +impl ExtrinsicParams for CustomExtrinsicParams { + type OtherParams = CustomExtrinsicParamsBuilder; + + // Gather together all of the params we will need to encode: + fn new>( + _nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + Ok(Self { + genesis_hash: client.genesis_hash(), + tip: other_params.tip, + foo: other_params.foo, + }) + } +} + +// Encode the relevant params when asked: +impl ExtrinsicParamsEncoder for CustomExtrinsicParams { + fn encode_extra_to(&self, v: &mut Vec) { + (self.tip, self.foo).encode_to(v); + } + fn encode_additional_to(&self, v: &mut Vec) { + self.genesis_hash.encode_to(v) + } +} + +#[tokio::main] +async fn main() { + // With the config defined, it can be handed to Subxt as follows: + let client = subxt::OnlineClient::::new().await.unwrap(); + + let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); + + // Build your custom "OtherParams": + let tx_config = CustomExtrinsicParamsBuilder::new().tip(1234).enable_foo(); + + // And provide them when submitting a transaction: + let _ = client + .tx() + .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) + .await; +} +*/ + //! ``` + //! + //! ### Using a type from the metadata as a config parameter + //! + //! You can also use types that are generated from chain metadata as type parameters of the Config trait. + //! Just make sure all trait bounds are satisfied. This can often be achieved by using custom derives with the subxt macro. + //! For example, the AssetHub Parachain expects tips to include a `MultiLocation`, which is a type we can draw from the metadata. + //! + //! This example shows what using the `MultiLocation` struct as part of your config would look like in subxt: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::config::{ + Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, PolkadotConfig, SubstrateConfig, +}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt( + runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", + derive_for_type( + path = "xcm::v2::multilocation::MultiLocation", + derive = "Clone", + recursive + ) +)] +pub mod runtime {} +use runtime::runtime_types::xcm::v2::multilocation::{Junctions, MultiLocation}; + +// We don't need to construct this at runtime, so an empty enum is appropriate. +pub enum AssetHubConfig {} + +impl Config for AssetHubConfig { + type Hash = ::Hash; + type AccountId = ::AccountId; + type Address = ::Address; + type Signature = ::Signature; + type Hasher = ::Hasher; + type Header = ::Header; + type ExtrinsicParams = DefaultExtrinsicParams; + // Here we use the MultiLocation from the metadata as a part of the config: + // The `ChargeAssetTxPayment` signed extension that is part of the ExtrinsicParams above, now uses the type: + type AssetId = MultiLocation; +} + +#[tokio::main] +async fn main() { + // With the config defined, we can create an extrinsic with subxt: + let client = subxt::OnlineClient::::new().await.unwrap(); + let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); + + // Build extrinsic params using an asset at this location as a tip: + let location: MultiLocation = MultiLocation { + parents: 3, + interior: Junctions::Here, + }; + let tx_config = DefaultExtrinsicParamsBuilder::::new() + .tip_of(1234, location) + .build(); + + // And provide the extrinsic params including the tip when submitting a transaction: + let _ = client + .tx() + .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) + .await; +} +*/ + //! ``` + } + } + pub mod usage { + //! This modules contains examples of using Subxt; follow the links for more: + //! + //! - [Transactions](transactions) + //! - [Storage](storage) + //! - [Events](events) + //! - [Constants](constants) + //! - [Blocks](blocks) + //! - [Runtime APIs](runtime_apis) + //! - [Unstable Light Client](light_client) + //! - [Custom Values](custom_values) + //! - [RPC calls](rpc) + //! + //! Alternately, [go back](super). + pub mod blocks { + //! # Blocks + //! + //! The [blocks API](crate::blocks::BlocksClient) in Subxt unifies many of the other interfaces, and + //! allows you to: + //! + //! - Access information about specific blocks (see [`crate::blocks::BlocksClient::at()`] and + //! [`crate::blocks::BlocksClient::at_latest()`]). + //! - Subscribe to [all](crate::blocks::BlocksClient::subscribe_all()), + //! [best](crate::blocks::BlocksClient::subscribe_best()) or + //! [finalized](crate::blocks::BlocksClient::subscribe_finalized()) blocks as they are produced. + //! Prefer to subscribe to finalized blocks unless you know what you're doing. + //! + //! In either case, you'll end up with [`crate::blocks::Block`]'s, from which you can access various + //! information about the block, such a the [header](crate::blocks::Block::header()), [block + //! number](crate::blocks::Block::number()) and [body (the extrinsics)](crate::blocks::Block::extrinsics()). + //! [`crate::blocks::Block`]'s also provide shortcuts to other Subxt APIs that will operate at the + //! given block: + //! + //! - [storage](crate::blocks::Block::storage()), + //! - [events](crate::blocks::Block::events()) + //! - [runtime APIs](crate::blocks::Block::runtime_api()) + //! + //! Aside from these links to other Subxt APIs, the main thing that we can do here is iterate over and + //! decode the extrinsics in a block body. + //! + //! ## Decoding Extrinsics + //! + //! Given a block, you can [download the block body](crate::blocks::Block::extrinsics()) and [iterate over + //! the extrinsics](crate::blocks::Extrinsics::iter()) stored within it. The extrinsics yielded are of type + //! [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), which is just a blob of bytes that also stores which + //! pallet and call in that pallet it belongs to. It also contains information about signed extensions that + //! have been used for submitting this extrinsic. + //! + //! To use the extrinsic, you probably want to decode it into a concrete Rust type. These Rust types representing + //! extrinsics from different pallets can be generated from metadata using the subxt macro or the CLI tool. + //! + //! When decoding the extrinsic into a static type you have two options: + //! + //! ### Statically decode the extrinsics into [the root extrinsic type](crate::blocks::ExtrinsicDetails::as_root_extrinsic()) + //! + //! The root extrinsic type generated by subxt is a Rust enum with one variant for each pallet. Each of these + //! variants has a field that is another enum whose variants cover all calls of the respective pallet. + //! If the extrinsic bytes are valid and your metadata matches the chain's metadata, decoding the bytes of an extrinsic into + //! this root extrinsic type should always succeed. + //! + //! This example shows how to subscribe to blocks and decode the extrinsics in each block into the root extrinsic type. + //! Once we get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), we can decode it statically or dynamically. + //! We can also access details about the extrinsic, including the associated events and signed extensions. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Subscribe to all finalized blocks: + let mut blocks_sub = api.blocks().subscribe_finalized().await?; + + // For each block, print a bunch of information about it: + while let Some(block) = blocks_sub.next().await { + let block = block?; + + let block_number = block.header().number; + let block_hash = block.hash(); + + println!("Block #{block_number}:"); + println!(" Hash: {block_hash}"); + println!(" Extrinsics:"); + + // Log each of the extrinsic with it's associated events: + let extrinsics = block.extrinsics().await?; + for ext in extrinsics.iter() { + let ext = ext?; + let idx = ext.index(); + let events = ext.events().await?; + let bytes_hex = format!("0x{}", hex::encode(ext.bytes())); + + // See the API docs for more ways to decode extrinsics: + let decoded_ext = ext.as_root_extrinsic::(); + + println!(" Extrinsic #{idx}:"); + println!(" Bytes: {bytes_hex}"); + println!(" Decoded: {decoded_ext:?}"); + + println!(" Events:"); + for evt in events.iter() { + let evt = evt?; + let pallet_name = evt.pallet_name(); + let event_name = evt.variant_name(); + let event_values = evt.field_values()?; + + println!(" {pallet_name}_{event_name}"); + println!(" {}", event_values); + } + + println!(" Signed Extensions:"); + if let Some(signed_extensions) = ext.signed_extensions() { + for signed_extension in signed_extensions.iter() { + let signed_extension = signed_extension?; + let name = signed_extension.name(); + let value = signed_extension.value()?.to_string(); + println!(" {name}: {value}"); + } + } + } + } + + Ok(()) +} +*/ + //! ``` + //! + //! ### Statically decode the extrinsic into [a specific pallet call](crate::blocks::ExtrinsicDetails::as_extrinsic()) + //! + //! This is useful if you are expecting a specific extrinsic to be part of some block. If the extrinsic you try to decode + //! is a different extrinsic, an `Ok(None)` value is returned from [`as_extrinsic::()`](crate::blocks::ExtrinsicDetails::as_extrinsic()); + //! + //! If you are only interested in finding specific extrinsics in a block, you can also [iterate over all of them](crate::blocks::Extrinsics::find), + //! get only [the first one](crate::blocks::Extrinsics::find_first), or [the last one](crate::blocks::Extrinsics::find_last). + //! + //! The following example monitors `TransferKeepAlive` extrinsics on the Polkadot network. + //! We statically decode them and access the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and [account nonce](crate::blocks::ExtrinsicSignedExtensions::nonce()) signed extensions. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{ + utils::{AccountId32, MultiAddress}, + OnlineClient, PolkadotConfig, +}; + +use codec::Decode; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +use polkadot::balances::calls::types::TransferKeepAlive; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client that subscribes to blocks of the Polkadot network. + let api = OnlineClient::::from_url("wss://rpc.polkadot.io:443").await?; + + // Subscribe to all finalized blocks: + let mut blocks_sub = api.blocks().subscribe_finalized().await?; + + // For each block, print details about the `TransferKeepAlive` transactions we are interested in. + while let Some(block) = blocks_sub.next().await { + let block = block?; + let block_number = block.header().number; + let block_hash = block.hash(); + println!("Block #{block_number} ({block_hash}):"); + + let extrinsics = block.extrinsics().await?; + for transfer in extrinsics.find::() { + let transfer = transfer?; + + let Some(extensions) = transfer.details.signed_extensions() else { + panic!("TransferKeepAlive should be signed") + }; + + let addr_bytes = transfer + .details + .address_bytes() + .expect("TransferKeepAlive should be signed"); + let sender = MultiAddress::::decode(&mut &addr_bytes[..]) + .expect("Decoding should work"); + let sender = display_address(&sender); + let receiver = display_address(&transfer.value.dest); + let value = transfer.value.value; + let tip = extensions.tip().expect("Should have tip"); + let nonce = extensions.nonce().expect("Should have nonce"); + + println!( + " Transfer of {value} DOT:\n {sender} (Tip: {tip}, Nonce: {nonce}) ---> {receiver}", + ); + } + } + + Ok(()) +} + +fn display_address(addr: &MultiAddress) -> String { + if let MultiAddress::Id(id32) = addr { + format!("{id32}") + } else { + "MultiAddress::...".into() + } +} +*/ + //! ``` + //! + //! ### Dynamically decode the extrinsic + //! + //! Sometimes you might use subxt with metadata that is not known at compile time. In this case, you do not have access to a statically generated + //! interface module that contains the relevant Rust types. You can [decode ExtrinsicDetails dynamically](crate::blocks::ExtrinsicDetails::field_values()), + //! which gives you access to it's fields as a [scale value composite](scale_value::Composite). + //! The following example looks for signed extrinsics on the Polkadot network and retrieves their pallet name, variant name, data fields and signed extensions dynamically. + //! Notice how we do not need to use code generation via the subxt macro. The only fixed component we provide is the [PolkadotConfig](crate::config::PolkadotConfig). + //! Other than that it works in a chain-agnostic way: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client that subscribes to blocks of the Polkadot network. + let api = OnlineClient::::from_url("wss://rpc.polkadot.io:443").await?; + + // Subscribe to all finalized blocks: + let mut blocks_sub = api.blocks().subscribe_finalized().await?; + while let Some(block) = blocks_sub.next().await { + let block = block?; + let block_number = block.header().number; + let block_hash = block.hash(); + println!("Block #{block_number} ({block_hash})"); + + // Decode each signed extrinsic in the block dynamically + let extrinsics = block.extrinsics().await?; + for ext in extrinsics.iter() { + let ext = ext?; + + let Some(signed_extensions) = ext.signed_extensions() else { + continue; // we do not look at inherents in this example + }; + + let meta = ext.extrinsic_metadata()?; + let fields = ext.field_values()?; + + println!(" {}/{}", meta.pallet.name(), meta.variant.name); + println!(" Signed Extensions:"); + for signed_ext in signed_extensions.iter() { + let signed_ext = signed_ext?; + // We only want to take a look at these 3 signed extensions, because the others all just have unit fields. + if ["CheckMortality", "CheckNonce", "ChargeTransactionPayment"] + .contains(&signed_ext.name()) + { + println!(" {}: {}", signed_ext.name(), signed_ext.value()?); + } + } + println!(" Fields:"); + println!(" {}\n", fields); + } + } + + Ok(()) +} +*/ + //! ``` + //! + //! ## Decoding signed extensions + //! + //! Extrinsics can contain signed extensions. The signed extensions can be different across chains. + //! The [Config](crate::Config) implementation for your chain defines which signed extensions you expect. + //! Once you get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails) for an extrinsic you are interested in, + //! you can try to [get its signed extensions](crate::blocks::ExtrinsicDetails::signed_extensions()). + //! These are only available on signed extrinsics. You can try to [find a specific signed extension](crate::blocks::ExtrinsicSignedExtensions::find), + //! in the returned [signed extensions](crate::blocks::ExtrinsicSignedExtensions). + //! + //! Subxt also provides utility functions to get the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and the + //! [account nonce](crate::blocks::ExtrinsicSignedExtensions::tip()) associated with an extrinsic, given its signed extensions. + //! If you prefer to do things dynamically you can get the data of the signed extension as a [scale value](crate::blocks::ExtrinsicSignedExtension::value()). + //! + } + pub mod constants { + //! # Constants + //! + //! There are various constants stored in a node; the types and values of these are defined in a + //! runtime, and can only change when the runtime is updated. Much like [`super::storage`], we can + //! query these using Subxt by taking the following steps: + //! + //! 1. [Constructing a constant query](#constructing-a-query). + //! 2. [Submitting the query to get back the associated value](#submitting-it). + //! + //! ## Constructing a constant query + //! + //! We can use the statically generated interface to build constant queries: + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] + //! pub mod polkadot {} + //! + //! let constant_query = polkadot::constants().system().block_length(); + //! ``` + //! + //! Alternately, we can dynamically construct a constant query: + //! + //! ```rust,no_run + //! use subxt::dynamic::Value; + //! + //! let storage_query = subxt::dynamic::constant("System", "BlockLength"); + //! ``` + //! + //! Static queries also have a static return type, so the constant is decoded appropriately. In + //! addition, they are validated at runtime to ensure that they align with the current node state. + //! Dynamic queries must be decoded into some static type manually, or into the dynamic + //! [`crate::dynamic::Value`] type. + //! + //! ## Submitting it + //! + //! Constant queries are handed to Subxt via [`crate::constants::ConstantsClient::at()`]. It's worth + //! noting that constant values are pulled directly out of the node metadata which Subxt has + //! already acquired, and so this function requires no network access and is available from a + //! [`crate::OfflineClient`]. + //! + //! Here's an example using a static query: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // A query to obtain some contant: + let constant_query = polkadot::constants().system().block_length(); + + // Obtain the value: + let value = api.constants().at(&constant_query)?; + + println!("Block length: {value:?}"); + Ok(()) +} +*/ + //! ``` + //! + //! And here's one using a dynamic query: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // A dynamic query to obtain some contant: + let constant_query = subxt::dynamic::constant("System", "BlockLength"); + + // Obtain the value: + let value = api.constants().at(&constant_query)?; + + println!("Constant bytes: {:?}", value.encoded()); + println!("Constant value: {}", value.to_value()?); + Ok(()) +} +*/ + //! ``` + //! + } + pub mod custom_values { + //! # Custom Values + //! + //! Substrate-based chains can expose custom values in their metadata. + //! Each of these values: + //! + //! - can be accessed by a unique __name__. + //! - refers to a concrete __type__ stored in the metadata. + //! - contains a scale encoded __value__ of that type. + //! + //! ## Getting a custom value + //! + //! Custom values can be accessed via a [`CustomValuesClient`](crate::custom_values::CustomValuesClient). + //! The client exposes an `at` function by which a custom value can be fetched, given an address to this custom value. + //! An address can be as simple as the aforementioned __name__ as a [str]. This will return a dynamic value, that you can manually decode into the type you want. + //! Suppose, the custom types contain a value of type `Foo` under the name `"foo"` you can access it like in this example: + //! + //! ```rust,ignore + //! use subxt::{OnlineClient, PolkadotConfig, ext::{codec::Decode, scale_decode::DecodeAsType}}; + //! + //! #[derive(Decode, DecodeAsType, Debug)] + //! struct Foo { + //! n: u8, + //! b: bool, + //! } + //! + //! let api = OnlineClient::::new().await?; + //! let custom_value_client = api.custom_values(); + //! let foo_dynamic = custom_value_client.at("foo")?; + //! let foo: Foo = foo_dynamic.as_type()?; + //! + //! ``` + //! + //! Alternatively we also provide a statically generated api for custom values: + //! + //! ```rust,ignore + //! #[subxt::subxt(runtime_metadata_path = "some_metadata.scale")] + //! pub mod interface {} + //! + //! let static_address = interface::custom().foo(); + //! + //! let api = OnlineClient::::new().await?; + //! let custom_value_client = api.custom_values(); + //! + //! // Now the `at()` function already decodes the value into the Foo type: + //! let foo = custom_value_client.at(&static_address)?; + //! ``` + //! + //! Note: Names of custom values are converted to __snake_case__ to produce a valid function name during code generation. + //! If there are multiple values where the names would be equal when converted to __snake_case__, functions might not be statically generated for some of them, because of naming conflicts. + //! Make sure names in the custom values of your metadata differ significantly. + } + pub mod events { + //! # Events + //! + //! In the process of adding extrinsics to a block, they are executed. When extrinsics are executed, + //! they normally produce events describing what's happening (at the very least, an event dictating whether + //! the extrinsic has succeeded or failed). The node may also emit some events of its own as the block is + //! processed. + //! + //! Events live in a single location in node storage which is overwritten at each block. Normal nodes tend to + //! keep a snapshot of the state at a small number of previous blocks, so you can sometimes access + //! older events by using [`crate::events::EventsClient::at()`] and providing an older block hash. + //! + //! When we submit transactions using Subxt, methods like [`crate::tx::TxProgress::wait_for_finalized_success()`] + //! return [`crate::blocks::ExtrinsicEvents`], which can be used to iterate and inspect the events produced + //! by that transaction being executed. We can also access _all_ of the events produced in a single block using one + //! of these two interfaces: + //! + //! ```rust,no_run + //! # #[tokio::main] + //! # async fn main() -> Result<(), Box> { + //! use subxt::client::OnlineClient; + //! use subxt::config::PolkadotConfig; + //! + //! // Create client: + //! let client = OnlineClient::::new().await?; + //! + //! // Get events from the latest block (use .at() to specify a block hash): + //! let events = client.blocks().at_latest().await?.events().await?; + //! // We can use this shorthand too: + //! let events = client.events().at_latest().await?; + //! # Ok(()) + //! # } + //! ``` + //! + //! Once we've loaded our events, we can iterate all events or search for specific events via + //! methods like [`crate::events::Events::iter()`] and [`crate::events::Events::find()`]. See + //! [`crate::events::Events`] and [`crate::events::EventDetails`] for more information. + //! + //! ## Example + //! + //! Here's an example which puts this all together: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Get events for the latest block: + let events = api.events().at_latest().await?; + + // We can dynamically decode events: + println!("Dynamic event details:"); + for event in events.iter() { + let event = event?; + + let pallet = event.pallet_name(); + let variant = event.variant_name(); + let field_values = event.field_values()?; + + println!("{pallet}::{variant}: {field_values}"); + } + + // Or we can attempt to statically decode them into the root Event type: + println!("Static event details:"); + for event in events.iter() { + let event = event?; + + if let Ok(ev) = event.as_root_event::() { + println!("{ev:?}"); + } else { + println!(""); + } + } + + // Or we can look for specific events which match our statically defined ones: + let transfer_event = events.find_first::()?; + if let Some(ev) = transfer_event { + println!(" - Balance transfer success: value: {:?}", ev.amount); + } else { + println!(" - No balance transfer event found in this block"); + } + + Ok(()) +} +*/ + //! ``` + //! + } + pub mod light_client { + //! # Light Client + //! + //! The light client based interface uses _Smoldot_ to connect to a _chain_, rather than an individual + //! node. This means that you don't have to trust a specific node when interacting with some chain. + //! + //! This feature is currently unstable. Use the `unstable-light-client` feature flag to enable it. + //! To use this in WASM environments, also enable the `web` feature flag. + //! + //! To connect to a blockchain network, the Light Client requires a trusted sync state of the network, + //! known as a _chain spec_. One way to obtain this is by making a `sync_state_genSyncSpec` RPC call to a + //! trusted node belonging to the chain that you wish to interact with. + //! + //! The following is an example of fetching the chain spec from a local running node on port 9933: + //! + //! ```bash + //! curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "sync_state_genSyncSpec", "params":[true]}' http://localhost:9933/ | jq .result > chain_spec.json + //! ``` + //! + //! Alternately, you can have the `LightClient` download the chain spec from a trusted node when it + //! initializes, which is not recommended in production but is useful for examples and testing, as below. + //! + //! ## Examples + //! + //! ### Basic Example + //! + //! This example connects to a local chain and submits a transaction. To run this, you first need + //! to have a local polkadot node running using the following command: + //! + //! ```text + //! polkadot --dev --node-key 0000000000000000000000000000000000000000000000000000000000000001 + //! ``` + //! + //! Leave that running for a minute, and then you can run the example using the following command + //! in the `subxt` crate: + //! + //! ```bash + //! cargo run --example light_client_tx_basic --features=unstable-light-client + //! ``` + //! + //! This is the code that will be executed: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{client::LightClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // The smoldot logs are informative: + tracing_subscriber::fmt::init(); + + // Create a light client by fetching the chain spec of a local running node. + // In this case, because we start one single node, the bootnodes must be overwritten + // for the light client to connect to the local node. + // + // The `12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp` is the P2P address + // from a local polkadot node starting with + // `--node-key 0000000000000000000000000000000000000000000000000000000000000001` + let api = LightClient::::builder() + .bootnodes([ + "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp", + ]) + .build_from_url("ws://127.0.0.1:9944") + .await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let from = dev::alice(); + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} +*/ + //! ``` + //! + //! ### Connecting to a parachain + //! + //! This example connects to a parachain using the light client. Currently, it's quite verbose to do this. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use futures::StreamExt; +use std::{iter, num::NonZeroU32}; +use subxt::{ + client::{LightClient, RawLightClient}, + PolkadotConfig, +}; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +const POLKADOT_SPEC: &str = include_str!("../../artifacts/demo_chain_specs/polkadot.json"); +const ASSET_HUB_SPEC: &str = + include_str!("../../artifacts/demo_chain_specs/polkadot_asset_hub.json"); + +#[tokio::main] +async fn main() -> Result<(), Box> { + // The smoldot logs are informative: + tracing_subscriber::fmt::init(); + + // Connecting to a parachain is a multi step process. + + // Step 1. Construct a new smoldot client. + let mut client = + subxt_lightclient::smoldot::Client::new(subxt_lightclient::smoldot::DefaultPlatform::new( + "subxt-example-light-client".into(), + "version-0".into(), + )); + + // Step 2. Connect to the relay chain of the parachain. For this example, the Polkadot relay chain. + let polkadot_connection = client + .add_chain(subxt_lightclient::smoldot::AddChainConfig { + specification: POLKADOT_SPEC, + json_rpc: subxt_lightclient::smoldot::AddChainConfigJsonRpc::Enabled { + max_pending_requests: NonZeroU32::new(128).unwrap(), + max_subscriptions: 1024, + }, + potential_relay_chains: iter::empty(), + database_content: "", + user_data: (), + }) + .expect("Light client chain added with valid spec; qed"); + let polkadot_json_rpc_responses = polkadot_connection + .json_rpc_responses + .expect("Light client configured with json rpc enabled; qed"); + let polkadot_chain_id = polkadot_connection.chain_id; + + // Step 3. Connect to the parachain. For this example, the Asset hub parachain. + let assethub_connection = client + .add_chain(subxt_lightclient::smoldot::AddChainConfig { + specification: ASSET_HUB_SPEC, + json_rpc: subxt_lightclient::smoldot::AddChainConfigJsonRpc::Enabled { + max_pending_requests: NonZeroU32::new(128).unwrap(), + max_subscriptions: 1024, + }, + // The chain specification of the asset hub parachain mentions that the identifier + // of its relay chain is `polkadot`. + potential_relay_chains: [polkadot_chain_id].into_iter(), + database_content: "", + user_data: (), + }) + .expect("Light client chain added with valid spec; qed"); + let parachain_json_rpc_responses = assethub_connection + .json_rpc_responses + .expect("Light client configured with json rpc enabled; qed"); + let parachain_chain_id = assethub_connection.chain_id; + + // Step 4. Turn the smoldot client into a raw client. + let raw_light_client = RawLightClient::builder() + .add_chain(polkadot_chain_id, polkadot_json_rpc_responses) + .add_chain(parachain_chain_id, parachain_json_rpc_responses) + .build(client) + .await?; + + // Step 5. Obtain a client to target the relay chain and the parachain. + let polkadot_api: LightClient = + raw_light_client.for_chain(polkadot_chain_id).await?; + let parachain_api: LightClient = + raw_light_client.for_chain(parachain_chain_id).await?; + + // Step 6. Subscribe to the finalized blocks of the chains. + let polkadot_sub = polkadot_api + .blocks() + .subscribe_finalized() + .await? + .map(|block| ("Polkadot", block)); + let parachain_sub = parachain_api + .blocks() + .subscribe_finalized() + .await? + .map(|block| ("AssetHub", block)); + let mut stream_combinator = futures::stream::select(polkadot_sub, parachain_sub); + + while let Some((chain, block)) = stream_combinator.next().await { + let block = block?; + + println!(" Chain {:?} hash={:?}", chain, block.hash()); + } + + Ok(()) +} +*/ + //! ``` + } + pub mod rpc { + //! # RPC calls + //! + //! Subxt exposes low level interfaces that can be used to make RPC requests; [`crate::backend::legacy::rpc_methods`] + //! and [`crate::backend::unstable::rpc_methods`]. + //! + //! These interfaces cannot be accessed directly through an [`crate::OnlineClient`]; this is so that the high level + //! Subxt APIs can target either the "legacy" or the more modern "unstable" sets of RPC methods by selecting an appropriate + //! [`crate::backend::Backend`]. It also means that there could exist a backend in the future that doesn't use JSON-RPC at all. + //! + //! # Example + //! + //! Here's an example which calls some legacy JSON-RPC methods, and reuses the same connection to run a full Subxt client + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::backend::{legacy::LegacyRpcMethods, rpc::RpcClient}; +use subxt::config::DefaultExtrinsicParamsBuilder as Params; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // First, create a raw RPC client: + let rpc_client = RpcClient::from_url("ws://127.0.0.1:9944").await?; + + // Use this to construct our RPC methods: + let rpc = LegacyRpcMethods::::new(rpc_client.clone()); + + // We can use the same client to drive our full Subxt interface too: + let api = OnlineClient::::from_rpc_client(rpc_client.clone()).await?; + + // Now, we can make some RPC calls using some legacy RPC methods. + println!( + "📛 System Name: {:?}\n🩺 Health: {:?}\n🖫 Properties: {:?}\n🔗 Chain: {:?}\n", + rpc.system_name().await?, + rpc.system_health().await?, + rpc.system_properties().await?, + rpc.system_chain().await? + ); + + // We can also interleave RPC calls and using the full Subxt client, here to submit multiple + // transactions using the legacy `system_account_next_index` RPC call, which returns a nonce + // that is adjusted for any transactions already in the pool: + + let alice = dev::alice(); + let bob = dev::bob(); + + loop { + let current_nonce = rpc + .system_account_next_index(&alice.public_key().into()) + .await?; + let current_header = rpc.chain_get_header(None).await?.unwrap(); + + let ext_params = Params::new().mortal(¤t_header, 8).build(); + + let balance_transfer = polkadot::tx() + .balances() + .transfer_allow_death(bob.public_key().into(), 1_000_000); + + let ext_hash = api + .tx() + .create_signed_with_nonce(&balance_transfer, &alice, current_nonce, ext_params)? + .submit() + .await?; + + println!("Submitted ext {ext_hash} with nonce {current_nonce}"); + + // Sleep less than block time, but long enough to ensure + // not all transactions end up in the same block. + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + } +} +*/ + //! ``` + } + pub mod runtime_apis { + //! # Runtime API interface + //! + //! The Runtime API interface allows Subxt to call runtime APIs exposed by certain pallets in order + //! to obtain information. Much like [`super::storage`] and [`super::transactions`], Making a runtime + //! call to a node and getting the response back takes the following steps: + //! + //! 1. [Constructing a runtime call](#constructing-a-runtime-call) + //! 2. [Submitting it to get back the response](#submitting-it) + //! + //! **Note:** Runtime APIs are only available when using V15 metadata, which is currently unstable. + //! You'll need to use `subxt metadata --version unstable` command to download the unstable V15 metadata, + //! and activate the `unstable-metadata` feature in Subxt for it to also use this metadata from a node. The + //! metadata format is unstable because it may change and break compatibility with Subxt at any moment, so + //! use at your own risk. + //! + //! ## Constructing a runtime call + //! + //! We can use the statically generated interface to build runtime calls: + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] + //! pub mod polkadot {} + //! + //! let runtime_call = polkadot::apis().metadata().metadata_versions(); + //! ``` + //! + //! Alternately, we can dynamically construct a runtime call: + //! + //! ```rust,no_run + //! use subxt::dynamic::Value; + //! + //! let runtime_call = subxt::dynamic::runtime_api_call( + //! "Metadata", + //! "metadata_versions", + //! Vec::>::new() + //! ); + //! ``` + //! + //! All valid runtime calls implement [`crate::runtime_api::RuntimeApiPayload`], a trait which + //! describes how to encode the runtime call arguments and what return type to decode from the + //! response. + //! + //! ## Submitting it + //! + //! Runtime calls can be handed to [`crate::runtime_api::RuntimeApi::call()`], which will submit + //! them and hand back the associated response. + //! + //! ### Making a static Runtime API call + //! + //! The easiest way to make a runtime API call is to use the statically generated interface. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{config::PolkadotConfig, OnlineClient}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Create a runtime API payload that calls into + // `AccountNonceApi_account_nonce` function. + let account = dev::alice().public_key().into(); + let runtime_api_call = polkadot::apis().account_nonce_api().account_nonce(account); + + // Submit the call and get back a result. + let nonce = api + .runtime_api() + .at_latest() + .await? + .call(runtime_api_call) + .await; + + println!("AccountNonceApi_account_nonce for Alice: {:?}", nonce); + Ok(()) +} +*/ + //! ``` + //! + //! ### Making a dynamic Runtime API call + //! + //! If you'd prefer to construct the call at runtime, you can do this using the + //! [`crate::dynamic::runtime_api_call`] method. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::dynamic::Value; +use subxt::{config::PolkadotConfig, OnlineClient}; +use subxt_signer::sr25519::dev; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Create a dynamically runtime API payload that calls the + // `AccountNonceApi_account_nonce` function. + let account = dev::alice().public_key(); + let runtime_api_call = subxt::dynamic::runtime_api_call( + "AccountNonceApi", + "account_nonce", + vec![Value::from_bytes(account)], + ); + + // Submit the call to get back a result. + let nonce = api + .runtime_api() + .at_latest() + .await? + .call(runtime_api_call) + .await?; + + println!("Account nonce: {:#?}", nonce.to_value()); + Ok(()) +} +*/ + //! ``` + //! + //! ### Making a raw call + //! + //! This is generally discouraged in favour of one of the above, but may be necessary (especially if + //! the node you're talking to does not yet serve V15 metadata). Here, you must manually encode + //! the argument bytes and manually provide a type for the response bytes to be decoded into. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::ext::codec::Compact; +use subxt::ext::frame_metadata::RuntimeMetadataPrefixed; +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client to use: + let api = OnlineClient::::new().await?; + + // Use runtime APIs at the latest block: + let runtime_apis = api.runtime_api().at_latest().await?; + + // Ask for metadata and decode it: + let (_, meta): (Compact, RuntimeMetadataPrefixed) = + runtime_apis.call_raw("Metadata_metadata", None).await?; + + println!("{meta:?}"); + Ok(()) +} +*/ + //! ``` + //! + } + pub mod storage { + //! # Storage + //! + //! A Substrate based chain can be seen as a key/value database which starts off at some initial + //! state, and is modified by the extrinsics in each block. This database is referred to as the + //! node storage. With Subxt, you can query this key/value storage with the following steps: + //! + //! 1. [Constructing a storage query](#constructing-a-storage-query). + //! 2. [Submitting the query to get back the associated values](#submitting-it). + //! + //! ## Constructing a storage query + //! + //! We can use the statically generated interface to build storage queries: + //! + //! ```rust,no_run + //! use subxt_signer::sr25519::dev; + //! + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] + //! pub mod polkadot {} + //! + //! let account = dev::alice().public_key().into(); + //! let storage_query = polkadot::storage().system().account(&account); + //! ``` + //! + //! Alternately, we can dynamically construct a storage query. This will not be type checked or + //! validated until it's submitted: + //! + //! ```rust,no_run + //! use subxt_signer::sr25519::dev; + //! use subxt::dynamic::Value; + //! + //! let account = dev::alice().public_key(); + //! let storage_query = subxt::dynamic::storage("System", "Account", vec![ + //! Value::from_bytes(account) + //! ]); + //! ``` + //! + //! As well as accessing specific entries, some storage locations can also be iterated over (such as + //! the map of account information). To do this, suffix `_iter` onto the query constructor (this + //! will only be available on static constructors when iteration is actually possible): + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] + //! pub mod polkadot {} + //! + //! // A static query capable of iterating over accounts: + //! let storage_query = polkadot::storage().system().account_iter(); + //! // A dynamic query to do the same: + //! let storage_query = subxt::dynamic::storage("System", "Account", ()); + //! ``` + //! + //! Some storage entries are maps with multiple keys. As an example, we might end up with + //! an API like `runtime::storage().foo().bar(u8, bool, u16, String)` to fetch some entry "bar". + //! When this is the case, the codegen will generate multiple iterator query functions alongside + //! the function to fetch an individual value: + //! + //! - `runtime::storage().foo().bar(u8, bool, u16, String)`: fetch a single entry from the "bar" map. + //! - `runtime::storage().foo().bar_iter()`: iterate over all of the entries in the "bar" map. + //! - `runtime::storage().foo().bar_iter1(u8)`: iterate over all of the entries in the "bar" map under + //! a given `u8`. + //! - `runtime::storage().foo().bar_iter2(u8, bool)`: iterate over all of the entries in the "bar" map under + //! a given `u8` and `bool` value. + //! - `runtime::storage().foo().bar_iter3(u8, bool, u16)`: iterate over all of the entries in the "bar" map under + //! a given `u8`, `bool` and `u16` value. + //! + //! All valid storage queries implement [`crate::storage::StorageAddress`]. As well as describing + //! how to build a valid storage query, this trait also has some associated types that determine the + //! shape of the result you'll get back, and determine what you can do with it (ie, can you iterate + //! over storage entries using it). + //! + //! Static queries set appropriate values for these associated types, and can therefore only be used + //! where it makes sense. Dynamic queries don't know any better and can be used in more places, but + //! may fail at runtime instead if they are invalid in those places. + //! + //! ## Submitting it + //! + //! Storage queries can be handed to various functions in [`crate::storage::Storage`] in order to + //! obtain the associated values (also referred to as storage entries) back. + //! + //! ### Fetching storage entries + //! + //! The simplest way to access storage entries is to construct a query and then call either + //! [`crate::storage::Storage::fetch()`] or [`crate::storage::Storage::fetch_or_default()`] (the + //! latter will only work for storage queries that have a default value when empty): + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a storage query to access account information. + let account = dev::alice().public_key().into(); + let storage_query = polkadot::storage().system().account(&account); + + // Use that query to `fetch` a result. This returns an `Option<_>`, which will be + // `None` if no value exists at the given address. You can also use `fetch_default` + // where applicable, which will return the default value if none exists. + let result = api + .storage() + .at_latest() + .await? + .fetch(&storage_query) + .await?; + + println!("Alice has free balance: {}", result.unwrap().data.free); + Ok(()) +} +*/ + //! ``` + //! + //! For completeness, below is an example using a dynamic query instead. The return type from a + //! dynamic query is a [`crate::dynamic::DecodedValueThunk`], which can be decoded into a + //! [`crate::dynamic::Value`], or else the raw bytes can be accessed instead. + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::dynamic::{At, Value}; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a dynamic storage query to access account information. + let account = dev::alice().public_key(); + let storage_query = + subxt::dynamic::storage("System", "Account", vec![Value::from_bytes(account)]); + + // Use that query to `fetch` a result. Because the query is dynamic, we don't know what the result + // type will be either, and so we get a type back that can be decoded into a dynamic Value type. + let result = api + .storage() + .at_latest() + .await? + .fetch(&storage_query) + .await?; + let value = result.unwrap().to_value()?; + + println!("Alice has free balance: {:?}", value.at("data").at("free")); + Ok(()) +} +*/ + //! ``` + //! + //! ### Iterating storage entries + //! + //! Many storage entries are maps of values; as well as fetching individual values, it's possible to + //! iterate over all of the values stored at that location: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a storage query to iterate over account information. + let storage_query = polkadot::storage().system().account_iter(); + + // Get back an iterator of results (here, we are fetching 10 items at + // a time from the node, but we always iterate over one at a time). + let mut results = api.storage().at_latest().await?.iter(storage_query).await?; + + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value); + } + + Ok(()) +} +*/ + //! ``` + //! + //! Here's the same logic but using dynamically constructed values instead: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a dynamic storage query to iterate account information. + // With a dynamic query, we can just provide an empty vector as the keys to iterate over all entries. + let keys: Vec = vec![]; + let storage_query = subxt::dynamic::storage("System", "Account", keys); + + // Use that query to return an iterator over the results. + let mut results = api.storage().at_latest().await?.iter(storage_query).await?; + + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value.to_value()?); + } + + Ok(()) +} +*/ + //! ``` + //! + //! Here is an example of iterating over partial keys. In this example some multi-signature operations + //! are sent to the node. We can iterate over the pending multisig operations of a single multisig account: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use polkadot::multisig::events::NewMultisig; +use polkadot::runtime_types::{ + frame_system::pallet::Call, rococo_runtime::RuntimeCall, sp_weights::weight_v2::Weight, +}; +use subxt::utils::AccountId32; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::{dev, Keypair}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Prepare the chain to have 3 open multisig requests (2 of them are alice + bob): + let alice_signer = dev::alice(); + let bob = AccountId32(dev::bob().public_key().0); + let charlie = AccountId32(dev::charlie().public_key().0); + + let new_multisig_1 = submit_remark_as_multi(&alice_signer, &bob, b"Hello", &api).await?; + let new_multisig_2 = submit_remark_as_multi(&alice_signer, &bob, b"Hi", &api).await?; + let new_multisig_3 = submit_remark_as_multi(&alice_signer, &charlie, b"Hello", &api).await?; + + // Note: the NewMultisig event contains the multisig address we need to use for the storage queries: + assert_eq!(new_multisig_1.multisig, new_multisig_2.multisig); + assert_ne!(new_multisig_1.multisig, new_multisig_3.multisig); + + // Build a storage query to iterate over open multisig extrinsics from + // new_multisig_1.multisig which is the AccountId of the alice + bob multisig account + let alice_bob_account_id = &new_multisig_1.multisig; + let storage_query = polkadot::storage() + .multisig() + .multisigs_iter1(alice_bob_account_id); + + // Get back an iterator of results. + let mut results = api.storage().at_latest().await?.iter(storage_query).await?; + + while let Some(Ok(kv)) = results.next().await { + println!("Keys decoded: {:?}", kv.keys); + println!("Key: 0x{}", hex::encode(&kv.key_bytes)); + println!("Value: {:?}", kv.value); + } + Ok(()) +} + +async fn submit_remark_as_multi( + signer: &Keypair, + other: &AccountId32, + remark: &[u8], + api: &OnlineClient, +) -> Result> { + let multisig_remark_tx = polkadot::tx().multisig().as_multi( + 2, + vec![other.clone()], + None, + RuntimeCall::System(Call::remark { + remark: remark.to_vec(), + }), + Weight { + ref_time: 0, + proof_size: 0, + }, + ); + let events = api + .tx() + .sign_and_submit_then_watch_default(&multisig_remark_tx, signer) + .await? + .wait_for_finalized_success() + .await?; + let new_multisig = events + .find_first::()? + .expect("should contain event"); + Ok(new_multisig) +} +*/ + //! ``` + //! + //! ### Advanced + //! + //! For more advanced use cases, have a look at [`crate::storage::Storage::fetch_raw`] and + //! [`crate::storage::Storage::fetch_raw_keys`]. Both of these take raw bytes as arguments, which can be + //! obtained from a [`crate::storage::StorageAddress`] by using + //! [`crate::storage::StorageClient::address_bytes()`] or + //! [`crate::storage::StorageClient::address_root_bytes()`]. + //! + } + pub mod transactions { + //! # Transactions + //! + //! A transaction is an extrinsic that's signed (ie it originates from a given address). The purpose + //! of extrinsics is to modify the node storage in a deterministic way, and so being able to submit + //! transactions to a node is one of the core features of Subxt. + //! + //! > Note: the documentation tends to use the terms _extrinsic_ and _transaction_ interchangeably; + //! > An extrinsic is some data that can be added to a block, and is either signed (a _transaction_) + //! > or unsigned (an _inherent_). Subxt can construct either, but overwhelmingly you'll need to + //! > sign the payload you'd like to submit. + //! + //! Submitting a transaction to a node consists of the following steps: + //! + //! 1. [Constructing a transaction payload to submit](#constructing-a-transaction-payload). + //! 2. [Signing it](#signing-it). + //! 3. [Submitting it (optionally with some additional parameters)](#submitting-it). + //! + //! We'll look at each of these steps in turn. + //! + //! ## Constructing a transaction payload + //! + //! We can use the statically generated interface to build transaction payloads: + //! + //! ```rust,no_run + //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] + //! pub mod polkadot {} + //! + //! let remark = "Hello there".as_bytes().to_vec(); + //! let tx_payload = polkadot::tx().system().remark(remark); + //! ``` + //! + //! > If you're not sure what types to import and use to build a given payload, you can use the + //! > `subxt` CLI tool to generate the interface by using something like `subxt codegen | rustfmt > + //! > interface.rs`, to see what types and things are available (or even just to use directly + //! > instead of the [`#[subxt]`](crate::subxt) macro). + //! + //! Alternately, we can dynamically construct a transaction payload. This will not be type checked or + //! validated until it's submitted: + //! + //! ```rust,no_run + //! use subxt::dynamic::Value; + //! + //! let tx_payload = subxt::dynamic::tx("System", "remark", vec![ + //! Value::from_bytes("Hello there") + //! ]); + //! ``` + //! + //! The [`crate::dynamic::Value`] type is a dynamic type much like a `serde_json::Value` but instead + //! represents any type of data that can be SCALE encoded or decoded. It can be serialized, + //! deserialized and parsed from/to strings. + //! + //! A valid transaction payload is just something that implements the [`crate::tx::TxPayload`] trait; + //! you can implement this trait on your own custom types if the built-in ones are not suitable for + //! your needs. + //! + //! ## Signing it + //! + //! You'll normally need to sign an extrinsic to prove that it originated from an account that you + //! control. To do this, you will typically first create a [`crate::tx::Signer`] instance, which tells + //! Subxt who the extrinsic is from, and takes care of signing the relevant details to prove this. + //! + //! There are two main ways to create a compatible signer instance: + //! 1. The `subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`] + //! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled). + //! 2. Alternately, Subxt can use instances of Substrate's `sp_core::Pair` to sign things by wrapping + //! them in a `crate::tx::PairSigner` (requires the `substrate-compat` feature to be enabled). + //! + //! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via + //! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or + //! need additional signing algorithms that `subxt_signer` doesn't support, and don't care about WASM + //! compatibility. + //! + //! Let's see how to use each of these approaches: + //! + //! ```rust + //! # #[cfg(feature = "substrate-compat")] + //! # { + //! use subxt::config::PolkadotConfig; + //! use std::str::FromStr; + //! + //! //// 1. Use a `subxt_signer` impl: + //! use subxt_signer::{ SecretUri, sr25519 }; + //! + //! // Get hold of a `Signer` for a test account: + //! let alice = sr25519::dev::alice(); + //! + //! // Or generate a keypair, here from an SURI: + //! let uri = SecretUri::from_str("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password") + //! .expect("valid URI"); + //! let keypair = sr25519::Keypair::from_uri(&uri) + //! .expect("valid keypair"); + //! + //! //// 2. Use the corresponding `sp_core::Pair` impl: + //! use subxt::tx::PairSigner; + //! use sp_core::Pair; + //! + //! // Get hold of a `Signer` for a test account: + //! let alice = sp_keyring::AccountKeyring::Alice.pair(); + //! let alice = PairSigner::::new(alice); + //! + //! // Or generate a keypair, here from an SURI: + //! let keypair = sp_core::sr25519::Pair::from_string("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password", None) + //! .expect("valid URI"); + //! let keypair = PairSigner::::new(keypair); + //! # + //! # // Test that these all impl Signer trait while we're here: + //! # + //! # fn is_subxt_signer(_signer: impl subxt::tx::Signer) {} + //! # is_subxt_signer(subxt_signer::sr25519::dev::alice()); + //! # is_subxt_signer(subxt_signer::ecdsa::dev::alice()); + //! # is_subxt_signer(PairSigner::::new(sp_keyring::AccountKeyring::Alice.pair())); + //! # } + //! ``` + //! + //! See the `subxt_signer` crate or the `sp_core::Pair` docs for more ways to construct + //! and work with key pairs. + //! + //! If this isn't suitable/available, you can either implement [`crate::tx::Signer`] yourself to use + //! custom signing logic, or you can use some external signing logic, like so: + //! + //! ```rust,no_run + //! # #[tokio::main] + //! # async fn main() -> Result<(), Box> { + //! use subxt::client::OnlineClient; + //! use subxt::config::PolkadotConfig; + //! use subxt::dynamic::Value; + //! + //! // Create client: + //! let client = OnlineClient::::new().await?; + //! + //! // Create a dummy tx payload to sign: + //! let payload = subxt::dynamic::tx("System", "remark", vec![ + //! Value::from_bytes("Hello there") + //! ]); + //! + //! // Construct the tx but don't sign it. You need to provide the nonce + //! // here, or can use `create_partial_signed` to fetch the correct nonce. + //! let partial_tx = client.tx().create_partial_signed_with_nonce( + //! &payload, + //! 0u64, + //! Default::default() + //! )?; + //! + //! // Fetch the payload that needs to be signed: + //! let signer_payload = partial_tx.signer_payload(); + //! + //! // ... At this point, we can hand off the `signer_payload` to be signed externally. + //! // Ultimately we need to be given back a `signature` (or really, anything + //! // that can be SCALE encoded) and an `address`: + //! let signature; + //! let address; + //! # use subxt::tx::Signer; + //! # let signer = subxt_signer::sr25519::dev::alice(); + //! # signature = signer.sign(&signer_payload).into(); + //! # address = signer.public_key().to_address(); + //! + //! // Now we can build an tx, which one can call `submit` or `submit_and_watch` + //! // on to submit to a node and optionally watch the status. + //! let tx = partial_tx.sign_with_address_and_signature( + //! &address, + //! &signature + //! ); + //! # Ok(()) + //! # } + //! ``` + //! + //! ## Submitting it + //! + //! Once we have signed the transaction, we need to submit it. + //! + //! ### The high level API + //! + //! The highest level approach to doing this is to call + //! [`crate::tx::TxClient::sign_and_submit_then_watch_default`]. This hands back a + //! [`crate::tx::TxProgress`] struct which will monitor the transaction status. We can then call + //! [`crate::tx::TxProgress::wait_for_finalized_success()`] to wait for this transaction to make it + //! into a finalized block, check for an `ExtrinsicSuccess` event, and then hand back the events for + //! inspection. This looks like: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let from = dev::alice(); + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} +*/ + //! ``` + //! + //! ### Providing transaction parameters + //! + //! If you'd like to provide parameters (such as mortality) to the transaction, you can use + //! [`crate::tx::TxClient::sign_and_submit_then_watch`] instead: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::config::polkadot::PolkadotExtrinsicParamsBuilder as Params; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + let latest_block = api.blocks().at_latest().await?; + + // Configure the transaction parameters; we give a small tip and set the + // transaction to live for 32 blocks from the `latest_block` above. + let tx_params = Params::new() + .tip(1_000) + .mortal(latest_block.header(), 32) + .build(); + + // submit the transaction: + let from = dev::alice(); + let hash = api.tx().sign_and_submit(&tx, &from, tx_params).await?; + println!("Balance transfer extrinsic submitted with hash : {hash}"); + + Ok(()) +} +*/ + //! ``` + //! + //! This example doesn't wait for the transaction to be included in a block; it just submits it and + //! hopes for the best! + //! + //! ### Custom handling of transaction status updates + //! + //! If you'd like more control or visibility over exactly which status updates are being emitted for + //! the transaction, you can monitor them as they are emitted and react however you choose: + //! + //! ```rust,ignore + /*!#![allow(missing_docs)] +use subxt::{tx::TxStatus, OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +// Generate an interface that we can use from the node's metadata. +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + // Build a balance transfer extrinsic. + let dest = dev::bob().public_key().into(); + let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); + + // Submit the balance transfer extrinsic from Alice, and then monitor the + // progress of it. + let from = dev::alice(); + let mut balance_transfer_progress = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) + .await?; + + while let Some(status) = balance_transfer_progress.next().await { + match status? { + // It's finalized in a block! + TxStatus::InFinalizedBlock(in_block) => { + println!( + "Transaction {:?} is finalized in block {:?}", + in_block.extrinsic_hash(), + in_block.block_hash() + ); + + // grab the events and fail if no ExtrinsicSuccess event seen: + let events = in_block.wait_for_success().await?; + // We can look for events (this uses the static interface; we can also iterate + // over them and dynamically decode them): + let transfer_event = events.find_first::()?; + + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } else { + println!("Failed to find Balances::Transfer Event"); + } + } + // Just log any other status we encounter: + other => { + println!("Status: {other:?}"); + } + } + } + Ok(()) +} +*/ + //! ``` + //! + //! Take a look at the API docs for [`crate::tx::TxProgress`], [`crate::tx::TxStatus`] and + //! [`crate::tx::TxInBlock`] for more options. + //! + } + } +} +pub mod backend { + //! This module exposes a backend trait for Subxt which allows us to get and set + //! the necessary information (probably from a JSON-RPC API, but that's up to the + //! implementation). + pub mod legacy { + //! This module exposes a legacy backend implementation, which relies + //! on the legacy RPC API methods. + pub mod rpc_methods { + //! An interface to call the raw legacy RPC methods. + use crate::backend::rpc::{rpc_params, RpcClient, RpcSubscription}; + use crate::metadata::Metadata; + use crate::{Config, Error}; + use codec::Decode; + use derivative::Derivative; + use primitive_types::U256; + use serde::{Deserialize, Serialize}; + /// An interface to call the legacy RPC methods. This interface is instantiated with + /// some `T: Config` trait which determines some of the types that the RPC methods will + /// take or hand back. + #[derivative(Clone(bound = ""), Debug(bound = ""))] + pub struct LegacyRpcMethods { + client: RpcClient, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for LegacyRpcMethods { + fn clone(&self) -> Self { + match *self { + LegacyRpcMethods { + client: ref __arg_0, + _marker: ref __arg_1, + } => { + LegacyRpcMethods { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for LegacyRpcMethods { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + LegacyRpcMethods { + client: ref __arg_0, + _marker: ref __arg_1, + } => { + let mut __debug_trait_builder = __f + .debug_struct("LegacyRpcMethods"); + let _ = __debug_trait_builder.field("client", &&(*__arg_0)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + impl LegacyRpcMethods { + /// Instantiate the legacy RPC method interface. + pub fn new(client: RpcClient) -> Self { + LegacyRpcMethods { + client, + _marker: std::marker::PhantomData, + } + } + /// Fetch the raw bytes for a given storage key + pub async fn state_get_storage( + &self, + key: &[u8], + hash: Option, + ) -> Result, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(key)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let data: Option = self + .client + .request("state_getStorage", params) + .await?; + Ok(data.map(|b| b.0)) + } + /// Returns the keys with prefix with pagination support. + /// Up to `count` keys will be returned. + /// If `start_key` is passed, return next keys in storage in lexicographic order. + pub async fn state_get_keys_paged( + &self, + key: &[u8], + count: u32, + start_key: Option<&[u8]>, + at: Option, + ) -> Result, Error> { + let start_key = start_key.map(to_hex); + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(key)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(count) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(start_key) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let data: Vec = self + .client + .request("state_getKeysPaged", params) + .await?; + Ok(data.into_iter().map(|b| b.0).collect()) + } + /// Query historical storage entries in the range from the start block to the end block, + /// defaulting the end block to the current best block if it's not given. The first + /// [`StorageChangeSet`] returned has all of the values for each key, and subsequent ones + /// only contain values for any keys which have changed since the last. + pub async fn state_query_storage( + &self, + keys: impl IntoIterator, + from: T::Hash, + to: Option, + ) -> Result>, Error> { + let keys: Vec = keys.into_iter().map(to_hex).collect(); + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(keys) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(from) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(to) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client + .request("state_queryStorage", params) + .await + .map_err(Into::into) + } + /// Query storage entries at some block, using the best block if none is given. + /// This essentially provides a way to ask for a batch of values given a batch of keys, + /// despite the name of the [`StorageChangeSet`] type. + pub async fn state_query_storage_at( + &self, + keys: impl IntoIterator, + at: Option, + ) -> Result>, Error> { + let keys: Vec = keys.into_iter().map(to_hex).collect(); + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(keys) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client + .request("state_queryStorageAt", params) + .await + .map_err(Into::into) + } + /// Fetch the genesis hash + pub async fn genesis_hash(&self) -> Result { + let block_zero = 0u32; + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(block_zero) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let genesis_hash: Option = self + .client + .request("chain_getBlockHash", params) + .await?; + genesis_hash.ok_or_else(|| "Genesis hash not found".into()) + } + /// Fetch the metadata via the legacy `state_getMetadata` RPC method. + pub async fn state_get_metadata( + &self, + at: Option, + ) -> Result { + let bytes: Bytes = self + .client + .request( + "state_getMetadata", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + let metadata = Metadata::decode(&mut &bytes[..])?; + Ok(metadata) + } + /// Fetch system health + pub async fn system_health(&self) -> Result { + self.client + .request( + "system_health", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch system chain + pub async fn system_chain(&self) -> Result { + self.client + .request( + "system_chain", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch system name + pub async fn system_name(&self) -> Result { + self.client + .request( + "system_name", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch system version + pub async fn system_version(&self) -> Result { + self.client + .request( + "system_version", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch system properties + pub async fn system_properties( + &self, + ) -> Result { + self.client + .request( + "system_properties", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Fetch next nonce for an Account + /// + /// Return account nonce adjusted for extrinsics currently in transaction pool + pub async fn system_account_next_index( + &self, + account_id: &T::AccountId, + ) -> Result + where + T::AccountId: Serialize, + { + self.client + .request( + "system_accountNextIndex", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(&account_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await + } + /// Get a header + pub async fn chain_get_header( + &self, + hash: Option, + ) -> Result, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let header = self.client.request("chain_getHeader", params).await?; + Ok(header) + } + /// Get a block hash, returns hash of latest _best_ block by default. + pub async fn chain_get_block_hash( + &self, + block_number: Option, + ) -> Result, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(block_number) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let block_hash = self + .client + .request("chain_getBlockHash", params) + .await?; + Ok(block_hash) + } + /// Get a block hash of the latest finalized block + pub async fn chain_get_finalized_head(&self) -> Result { + let hash = self + .client + .request( + "chain_getFinalizedHead", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await?; + Ok(hash) + } + /// Get a Block + pub async fn chain_get_block( + &self, + hash: Option, + ) -> Result>, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let block = self.client.request("chain_getBlock", params).await?; + Ok(block) + } + /// Reexecute the specified `block_hash` and gather statistics while doing so. + /// + /// This function requires the specified block and its parent to be available + /// at the queried node. If either the specified block or the parent is pruned, + /// this function will return `None`. + pub async fn dev_get_block_stats( + &self, + block_hash: T::Hash, + ) -> Result, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(block_hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let stats = self.client.request("dev_getBlockStats", params).await?; + Ok(stats) + } + /// Get proof of storage entries at a specific block's state. + pub async fn state_get_read_proof( + &self, + keys: impl IntoIterator, + hash: Option, + ) -> Result, Error> { + let keys: Vec = keys.into_iter().map(to_hex).collect(); + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(keys) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let proof = self.client.request("state_getReadProof", params).await?; + Ok(proof) + } + /// Fetch the runtime version + pub async fn state_get_runtime_version( + &self, + at: Option, + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let version = self + .client + .request("state_getRuntimeVersion", params) + .await?; + Ok(version) + } + /// Subscribe to all new best block headers. + pub async fn chain_subscribe_new_heads( + &self, + ) -> Result, Error> { + let subscription = self + .client + .subscribe( + "chain_subscribeNewHeads", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + "chain_unsubscribeNewHeads", + ) + .await?; + Ok(subscription) + } + /// Subscribe to all new block headers. + pub async fn chain_subscribe_all_heads( + &self, + ) -> Result, Error> { + let subscription = self + .client + .subscribe( + "chain_subscribeAllHeads", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + "chain_unsubscribeAllHeads", + ) + .await?; + Ok(subscription) + } + /// Subscribe to finalized block headers. + /// + /// Note: this may not produce _every_ block in the finalized chain; + /// sometimes multiple blocks are finalized at once, and in this case only the + /// latest one is returned. the higher level APIs that use this "fill in" the + /// gaps for us. + pub async fn chain_subscribe_finalized_heads( + &self, + ) -> Result, Error> { + let subscription = self + .client + .subscribe( + "chain_subscribeFinalizedHeads", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + "chain_unsubscribeFinalizedHeads", + ) + .await?; + Ok(subscription) + } + /// Subscribe to runtime version updates that produce changes in the metadata. + /// The first item emitted by the stream is the current runtime version. + pub async fn state_subscribe_runtime_version( + &self, + ) -> Result, Error> { + let subscription = self + .client + .subscribe( + "state_subscribeRuntimeVersion", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + "state_unsubscribeRuntimeVersion", + ) + .await?; + Ok(subscription) + } + /// Create and submit an extrinsic and return corresponding Hash if successful + pub async fn author_submit_extrinsic( + &self, + extrinsic: &[u8], + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(extrinsic)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let xt_hash = self + .client + .request("author_submitExtrinsic", params) + .await?; + Ok(xt_hash) + } + /// Create and submit an extrinsic and return a subscription to the events triggered. + pub async fn author_submit_and_watch_extrinsic( + &self, + extrinsic: &[u8], + ) -> Result>, Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(extrinsic)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let subscription = self + .client + .subscribe( + "author_submitAndWatchExtrinsic", + params, + "author_unwatchExtrinsic", + ) + .await?; + Ok(subscription) + } + /// Insert a key into the keystore. + pub async fn author_insert_key( + &self, + key_type: String, + suri: String, + public: Vec, + ) -> Result<(), Error> { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(key_type) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(suri) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(Bytes(public)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client.request("author_insertKey", params).await?; + Ok(()) + } + /// Generate new session keys and returns the corresponding public keys. + pub async fn author_rotate_keys(&self) -> Result, Error> { + let bytes: Bytes = self + .client + .request( + "author_rotateKeys", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await?; + Ok(bytes.0) + } + /// Checks if the keystore has private keys for the given session public keys. + /// + /// `session_keys` is the SCALE encoded session keys object from the runtime. + /// + /// Returns `true` if all private keys could be found. + pub async fn author_has_session_keys( + &self, + session_keys: Vec, + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(Bytes(session_keys)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client.request("author_hasSessionKeys", params).await + } + /// Checks if the keystore has private keys for the given public key and key type. + /// + /// Returns `true` if a private key could be found. + pub async fn author_has_key( + &self, + public_key: Vec, + key_type: String, + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(Bytes(public_key)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(key_type) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + self.client.request("author_hasKey", params).await + } + /// Execute a runtime API call via `state_call` RPC method. + pub async fn state_call( + &self, + function: &str, + call_parameters: Option<&[u8]>, + at: Option, + ) -> Result, Error> { + let call_parameters = call_parameters.unwrap_or_default(); + let bytes: Bytes = self + .client + .request( + "state_call", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(function) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(to_hex(call_parameters)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(bytes.0) + } + /// Submits the extrinsic to the dry_run RPC, to test if it would succeed. + /// + /// Returns a [`DryRunResult`], which is the result of performing the dry run. + pub async fn dry_run( + &self, + encoded_signed: &[u8], + at: Option, + ) -> Result { + let params = { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(encoded_signed)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(at) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }; + let result_bytes: Bytes = self + .client + .request("system_dryRun", params) + .await?; + Ok(DryRunResultBytes(result_bytes.0)) + } + } + /// Storage key. + pub type StorageKey = Vec; + /// Storage data. + pub type StorageData = Vec; + /// Health struct returned by the RPC + #[serde(rename_all = "camelCase")] + pub struct SystemHealth { + /// Number of connected peers + pub peers: usize, + /// Is the node syncing + pub is_syncing: bool, + /// Should this node have any peers + /// + /// Might be false for local chains or when running without discovery. + pub should_have_peers: bool, + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for SystemHealth { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "peers" => _serde::__private::Ok(__Field::__field0), + "isSyncing" => _serde::__private::Ok(__Field::__field1), + "shouldHavePeers" => { + _serde::__private::Ok(__Field::__field2) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"peers" => _serde::__private::Ok(__Field::__field0), + b"isSyncing" => _serde::__private::Ok(__Field::__field1), + b"shouldHavePeers" => { + _serde::__private::Ok(__Field::__field2) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = SystemHealth; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct SystemHealth", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + usize, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SystemHealth with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + bool, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct SystemHealth with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + bool, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct SystemHealth with 3 elements", + ), + ); + } + }; + _serde::__private::Ok(SystemHealth { + peers: __field0, + is_syncing: __field1, + should_have_peers: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("peers"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "isSyncing", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "shouldHavePeers", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("peers")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("isSyncing")? + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("shouldHavePeers")? + } + }; + _serde::__private::Ok(SystemHealth { + peers: __field0, + is_syncing: __field1, + should_have_peers: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "peers", + "isSyncing", + "shouldHavePeers", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SystemHealth", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for SystemHealth { + #[inline] + fn clone(&self) -> SystemHealth { + SystemHealth { + peers: ::core::clone::Clone::clone(&self.peers), + is_syncing: ::core::clone::Clone::clone(&self.is_syncing), + should_have_peers: ::core::clone::Clone::clone( + &self.should_have_peers, + ), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for SystemHealth { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "SystemHealth", + "peers", + &self.peers, + "is_syncing", + &self.is_syncing, + "should_have_peers", + &&self.should_have_peers, + ) + } + } + /// System properties; an arbitrary JSON object. + pub type SystemProperties = serde_json::Map; + /// A block number + pub type BlockNumber = NumberOrHex; + /// The response from `chain_getBlock` + #[serde(bound = "T: Config")] + pub struct BlockDetails { + /// The block itself. + pub block: Block, + /// Block justification. + pub justifications: Option>, + } + #[automatically_derived] + impl ::core::fmt::Debug for BlockDetails { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "BlockDetails", + "block", + &self.block, + "justifications", + &&self.justifications, + ) + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, T: Config> _serde::Deserialize<'de> for BlockDetails + where + T: Config, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "block" => _serde::__private::Ok(__Field::__field0), + "justifications" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"block" => _serde::__private::Ok(__Field::__field0), + b"justifications" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, T: Config> + where + T: Config, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, T: Config> _serde::de::Visitor<'de> + for __Visitor<'de, T> + where + T: Config, + { + type Value = BlockDetails; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct BlockDetails", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Block, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct BlockDetails with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Option>, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct BlockDetails with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(BlockDetails { + block: __field0, + justifications: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option> = _serde::__private::None; + let mut __field1: _serde::__private::Option< + Option>, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("block"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "justifications", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option>, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("block")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("justifications")? + } + }; + _serde::__private::Ok(BlockDetails { + block: __field0, + justifications: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "block", + "justifications", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "BlockDetails", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Block details in the [`BlockDetails`]. + pub struct Block { + /// The block header. + pub header: T::Header, + /// The accompanying extrinsics. + pub extrinsics: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for Block + where + T::Header: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Block", + "header", + &self.header, + "extrinsics", + &&self.extrinsics, + ) + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, T: Config> _serde::Deserialize<'de> for Block + where + T::Header: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "header" => _serde::__private::Ok(__Field::__field0), + "extrinsics" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"header" => _serde::__private::Ok(__Field::__field0), + b"extrinsics" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, T: Config> + where + T::Header: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, T: Config> _serde::de::Visitor<'de> + for __Visitor<'de, T> + where + T::Header: _serde::Deserialize<'de>, + { + type Value = Block; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct Block", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + T::Header, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Block with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Block with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(Block { + header: __field0, + extrinsics: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option> = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("header"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "extrinsics", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("header")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("extrinsics")? + } + }; + _serde::__private::Ok(Block { + header: __field0, + extrinsics: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "header", + "extrinsics", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Block", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// An abstraction over justification for a block's validity under a consensus algorithm. + pub type BlockJustification = (ConsensusEngineId, EncodedJustification); + /// Consensus engine unique ID. + pub type ConsensusEngineId = [u8; 4]; + /// The encoded justification specific to a consensus engine. + pub type EncodedJustification = Vec; + /// This contains the runtime version information necessary to make transactions, as obtained from + /// the RPC call `state_getRuntimeVersion`, + #[serde(rename_all = "camelCase")] + pub struct RuntimeVersion { + /// Version of the runtime specification. A full-node will not attempt to use its native + /// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, + /// `spec_version` and `authoring_version` are the same between Wasm and native. + pub spec_version: u32, + /// All existing dispatches are fully compatible when this number doesn't change. If this + /// number changes, then `spec_version` must change, also. + /// + /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, + /// either through an alteration in its user-level semantics, a parameter + /// added/removed/changed, a dispatchable being removed, a module being removed, or a + /// dispatchable/module changing its index. + /// + /// It need *not* change when a new module is added or when a dispatchable is added. + pub transaction_version: u32, + /// Fields unnecessary to Subxt are written out to this map. + #[serde(flatten)] + pub other: std::collections::HashMap, + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeVersion { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "RuntimeVersion", + "spec_version", + &self.spec_version, + "transaction_version", + &self.transaction_version, + "other", + &&self.other, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeVersion { + #[inline] + fn clone(&self) -> RuntimeVersion { + RuntimeVersion { + spec_version: ::core::clone::Clone::clone(&self.spec_version), + transaction_version: ::core::clone::Clone::clone( + &self.transaction_version, + ), + other: ::core::clone::Clone::clone(&self.other), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeVersion {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeVersion { + #[inline] + fn eq(&self, other: &RuntimeVersion) -> bool { + self.spec_version == other.spec_version + && self.transaction_version == other.transaction_version + && self.other == other.other + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeVersion { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq< + std::collections::HashMap, + >; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RuntimeVersion { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field<'de> { + __field0, + __field1, + __other(_serde::__private::de::Content<'de>), + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field<'de>; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_bool<__E>( + self, + __value: bool, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::Bool(__value), + ), + ) + } + fn visit_i8<__E>( + self, + __value: i8, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I8(__value), + ), + ) + } + fn visit_i16<__E>( + self, + __value: i16, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I16(__value), + ), + ) + } + fn visit_i32<__E>( + self, + __value: i32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I32(__value), + ), + ) + } + fn visit_i64<__E>( + self, + __value: i64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I64(__value), + ), + ) + } + fn visit_u8<__E>( + self, + __value: u8, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U8(__value), + ), + ) + } + fn visit_u16<__E>( + self, + __value: u16, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U16(__value), + ), + ) + } + fn visit_u32<__E>( + self, + __value: u32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U32(__value), + ), + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U64(__value), + ), + ) + } + fn visit_f32<__E>( + self, + __value: f32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::F32(__value), + ), + ) + } + fn visit_f64<__E>( + self, + __value: f64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::F64(__value), + ), + ) + } + fn visit_char<__E>( + self, + __value: char, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::Char(__value), + ), + ) + } + fn visit_unit<__E>( + self, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other(_serde::__private::de::Content::Unit), + ) + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "specVersion" => _serde::__private::Ok(__Field::__field0), + "transactionVersion" => { + _serde::__private::Ok(__Field::__field1) + } + _ => { + let __value = _serde::__private::de::Content::String( + _serde::__private::ToString::to_string(__value), + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"specVersion" => _serde::__private::Ok(__Field::__field0), + b"transactionVersion" => { + _serde::__private::Ok(__Field::__field1) + } + _ => { + let __value = _serde::__private::de::Content::ByteBuf( + __value.to_vec(), + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_borrowed_str<__E>( + self, + __value: &'de str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "specVersion" => _serde::__private::Ok(__Field::__field0), + "transactionVersion" => { + _serde::__private::Ok(__Field::__field1) + } + _ => { + let __value = _serde::__private::de::Content::Str(__value); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_borrowed_bytes<__E>( + self, + __value: &'de [u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"specVersion" => _serde::__private::Ok(__Field::__field0), + b"transactionVersion" => { + _serde::__private::Ok(__Field::__field1) + } + _ => { + let __value = _serde::__private::de::Content::Bytes( + __value, + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field<'de> { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = RuntimeVersion; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct RuntimeVersion", + ) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __collect = _serde::__private::Vec::< + _serde::__private::Option< + ( + _serde::__private::de::Content, + _serde::__private::de::Content, + ), + >, + >::new(); + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "specVersion", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "transactionVersion", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__other(__name) => { + __collect + .push( + _serde::__private::Some(( + __name, + _serde::de::MapAccess::next_value(&mut __map)?, + )), + ); + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("specVersion")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("transactionVersion")? + } + }; + let __field2: std::collections::HashMap< + String, + serde_json::Value, + > = _serde::de::Deserialize::deserialize( + _serde::__private::de::FlatMapDeserializer( + &mut __collect, + _serde::__private::PhantomData, + ), + )?; + _serde::__private::Ok(RuntimeVersion { + spec_version: __field0, + transaction_version: __field1, + other: __field2, + }) + } + } + _serde::Deserializer::deserialize_map( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Possible transaction status events. + /// + /// # Note + /// + /// This is copied from `sp-transaction-pool` to avoid a dependency on that crate. Therefore it + /// must be kept compatible with that type from the target substrate version. + #[serde(rename_all = "camelCase")] + pub enum TransactionStatus { + /// Transaction is part of the future queue. + Future, + /// Transaction is part of the ready queue. + Ready, + /// The transaction has been broadcast to the given peers. + Broadcast(Vec), + /// Transaction has been included in block with given hash. + InBlock(Hash), + /// The block this transaction was included in has been retracted. + Retracted(Hash), + /// Maximum number of finality watchers has been reached, + /// old watchers are being removed. + FinalityTimeout(Hash), + /// Transaction has been finalized by a finality-gadget, e.g GRANDPA + Finalized(Hash), + /// Transaction has been replaced in the pool, by another transaction + /// that provides the same tags. (e.g. same (sender, nonce)). + Usurped(Hash), + /// Transaction has been dropped from the pool because of the limit. + Dropped, + /// Transaction is no longer valid in the current state. + Invalid, + } + #[automatically_derived] + impl ::core::fmt::Debug + for TransactionStatus { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionStatus::Future => { + ::core::fmt::Formatter::write_str(f, "Future") + } + TransactionStatus::Ready => { + ::core::fmt::Formatter::write_str(f, "Ready") + } + TransactionStatus::Broadcast(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Broadcast", + &__self_0, + ) + } + TransactionStatus::InBlock(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InBlock", + &__self_0, + ) + } + TransactionStatus::Retracted(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Retracted", + &__self_0, + ) + } + TransactionStatus::FinalityTimeout(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "FinalityTimeout", + &__self_0, + ) + } + TransactionStatus::Finalized(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Finalized", + &__self_0, + ) + } + TransactionStatus::Usurped(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Usurped", + &__self_0, + ) + } + TransactionStatus::Dropped => { + ::core::fmt::Formatter::write_str(f, "Dropped") + } + TransactionStatus::Invalid => { + ::core::fmt::Formatter::write_str(f, "Invalid") + } + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for TransactionStatus + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __field6, + __field7, + __field8, + __field9, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + 5u64 => _serde::__private::Ok(__Field::__field5), + 6u64 => _serde::__private::Ok(__Field::__field6), + 7u64 => _serde::__private::Ok(__Field::__field7), + 8u64 => _serde::__private::Ok(__Field::__field8), + 9u64 => _serde::__private::Ok(__Field::__field9), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 10", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "future" => _serde::__private::Ok(__Field::__field0), + "ready" => _serde::__private::Ok(__Field::__field1), + "broadcast" => _serde::__private::Ok(__Field::__field2), + "inBlock" => _serde::__private::Ok(__Field::__field3), + "retracted" => _serde::__private::Ok(__Field::__field4), + "finalityTimeout" => { + _serde::__private::Ok(__Field::__field5) + } + "finalized" => _serde::__private::Ok(__Field::__field6), + "usurped" => _serde::__private::Ok(__Field::__field7), + "dropped" => _serde::__private::Ok(__Field::__field8), + "invalid" => _serde::__private::Ok(__Field::__field9), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"future" => _serde::__private::Ok(__Field::__field0), + b"ready" => _serde::__private::Ok(__Field::__field1), + b"broadcast" => _serde::__private::Ok(__Field::__field2), + b"inBlock" => _serde::__private::Ok(__Field::__field3), + b"retracted" => _serde::__private::Ok(__Field::__field4), + b"finalityTimeout" => { + _serde::__private::Ok(__Field::__field5) + } + b"finalized" => _serde::__private::Ok(__Field::__field6), + b"usurped" => _serde::__private::Ok(__Field::__field7), + b"dropped" => _serde::__private::Ok(__Field::__field8), + b"invalid" => _serde::__private::Ok(__Field::__field9), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "enum TransactionStatus", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(TransactionStatus::Future) + } + (__Field::__field1, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(TransactionStatus::Ready) + } + (__Field::__field2, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Vec, + >(__variant), + TransactionStatus::Broadcast, + ) + } + (__Field::__field3, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::InBlock, + ) + } + (__Field::__field4, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::Retracted, + ) + } + (__Field::__field5, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::FinalityTimeout, + ) + } + (__Field::__field6, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::Finalized, + ) + } + (__Field::__field7, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Hash, + >(__variant), + TransactionStatus::Usurped, + ) + } + (__Field::__field8, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(TransactionStatus::Dropped) + } + (__Field::__field9, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(TransactionStatus::Invalid) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "future", + "ready", + "broadcast", + "inBlock", + "retracted", + "finalityTimeout", + "finalized", + "usurped", + "dropped", + "invalid", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "TransactionStatus", + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The decoded result returned from calling `system_dryRun` on some extrinsic. + pub enum DryRunResult { + /// The transaction could be included in the block and executed. + Success, + /// The transaction could be included in the block, but the call failed to dispatch. + DispatchError(crate::error::DispatchError), + /// The transaction could not be included in the block. + TransactionValidityError, + } + #[automatically_derived] + impl ::core::fmt::Debug for DryRunResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + DryRunResult::Success => { + ::core::fmt::Formatter::write_str(f, "Success") + } + DryRunResult::DispatchError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "DispatchError", + &__self_0, + ) + } + DryRunResult::TransactionValidityError => { + ::core::fmt::Formatter::write_str( + f, + "TransactionValidityError", + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DryRunResult {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DryRunResult { + #[inline] + fn eq(&self, other: &DryRunResult) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + DryRunResult::DispatchError(__self_0), + DryRunResult::DispatchError(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DryRunResult { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + /// The bytes representing an error dry running an extrinsic. call [`DryRunResultBytes::into_dry_run_result`] + /// to attempt to decode this into something more meaningful. + pub struct DryRunResultBytes(pub Vec); + impl DryRunResultBytes { + /// Attempt to decode the error bytes into a [`DryRunResult`] using the provided [`Metadata`]. + pub fn into_dry_run_result( + self, + metadata: &crate::metadata::Metadata, + ) -> Result { + let bytes = self.0; + if bytes[0] == 0 && bytes[1] == 0 { + Ok(DryRunResult::Success) + } else if bytes[0] == 0 && bytes[1] == 1 { + let dispatch_error = crate::error::DispatchError::decode_from( + &bytes[2..], + metadata.clone(), + )?; + Ok(DryRunResult::DispatchError(dispatch_error)) + } else if bytes[0] == 1 { + Ok(DryRunResult::TransactionValidityError) + } else { + Err(crate::Error::Unknown(bytes)) + } + } + } + /// Storage change set + #[serde(rename_all = "camelCase")] + pub struct StorageChangeSet { + /// Block hash + pub block: Hash, + /// A list of changes; tuples of storage key and optional storage data. + pub changes: Vec<(Bytes, Option)>, + } + #[automatically_derived] + impl ::core::clone::Clone + for StorageChangeSet { + #[inline] + fn clone(&self) -> StorageChangeSet { + StorageChangeSet { + block: ::core::clone::Clone::clone(&self.block), + changes: ::core::clone::Clone::clone(&self.changes), + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for StorageChangeSet + where + Hash: _serde::Serialize, + { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "StorageChangeSet", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "block", + &self.block, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "changes", + &self.changes, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for StorageChangeSet + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "block" => _serde::__private::Ok(__Field::__field0), + "changes" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"block" => _serde::__private::Ok(__Field::__field0), + b"changes" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + StorageChangeSet, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = StorageChangeSet; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct StorageChangeSet", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct StorageChangeSet with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec<(Bytes, Option)>, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct StorageChangeSet with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(StorageChangeSet { + block: __field0, + changes: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + Vec<(Bytes, Option)>, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("block"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "changes", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Vec<(Bytes, Option)>, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("block")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("changes")? + } + }; + _serde::__private::Ok(StorageChangeSet { + block: __field0, + changes: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["block", "changes"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "StorageChangeSet", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + StorageChangeSet, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageChangeSet {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for StorageChangeSet { + #[inline] + fn eq(&self, other: &StorageChangeSet) -> bool { + self.block == other.block && self.changes == other.changes + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageChangeSet { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq)>>; + } + } + #[automatically_derived] + impl ::core::fmt::Debug + for StorageChangeSet { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "StorageChangeSet", + "block", + &self.block, + "changes", + &&self.changes, + ) + } + } + /// Statistics of a block returned by the `dev_getBlockStats` RPC. + #[serde(rename_all = "camelCase")] + pub struct BlockStats { + /// The length in bytes of the storage proof produced by executing the block. + pub witness_len: u64, + /// The length in bytes of the storage proof after compaction. + pub witness_compact_len: u64, + /// Length of the block in bytes. + /// + /// This information can also be acquired by downloading the whole block. This merely + /// saves some complexity on the client side. + pub block_len: u64, + /// Number of extrinsics in the block. + /// + /// This information can also be acquired by downloading the whole block. This merely + /// saves some complexity on the client side. + pub num_extrinsics: u64, + } + #[automatically_derived] + impl ::core::clone::Clone for BlockStats { + #[inline] + fn clone(&self) -> BlockStats { + BlockStats { + witness_len: ::core::clone::Clone::clone(&self.witness_len), + witness_compact_len: ::core::clone::Clone::clone( + &self.witness_compact_len, + ), + block_len: ::core::clone::Clone::clone(&self.block_len), + num_extrinsics: ::core::clone::Clone::clone(&self.num_extrinsics), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for BlockStats { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "BlockStats", + "witness_len", + &self.witness_len, + "witness_compact_len", + &self.witness_compact_len, + "block_len", + &self.block_len, + "num_extrinsics", + &&self.num_extrinsics, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BlockStats {} + #[automatically_derived] + impl ::core::cmp::PartialEq for BlockStats { + #[inline] + fn eq(&self, other: &BlockStats) -> bool { + self.witness_len == other.witness_len + && self.witness_compact_len == other.witness_compact_len + && self.block_len == other.block_len + && self.num_extrinsics == other.num_extrinsics + } + } + #[automatically_derived] + impl ::core::cmp::Eq for BlockStats { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for BlockStats { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "BlockStats", + false as usize + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "witnessLen", + &self.witness_len, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "witnessCompactLen", + &self.witness_compact_len, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "blockLen", + &self.block_len, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "numExtrinsics", + &self.num_extrinsics, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for BlockStats { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "witnessLen" => _serde::__private::Ok(__Field::__field0), + "witnessCompactLen" => { + _serde::__private::Ok(__Field::__field1) + } + "blockLen" => _serde::__private::Ok(__Field::__field2), + "numExtrinsics" => _serde::__private::Ok(__Field::__field3), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"witnessLen" => _serde::__private::Ok(__Field::__field0), + b"witnessCompactLen" => { + _serde::__private::Ok(__Field::__field1) + } + b"blockLen" => _serde::__private::Ok(__Field::__field2), + b"numExtrinsics" => _serde::__private::Ok(__Field::__field3), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = BlockStats; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct BlockStats", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct BlockStats with 4 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct BlockStats with 4 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct BlockStats with 4 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct BlockStats with 4 elements", + ), + ); + } + }; + _serde::__private::Ok(BlockStats { + witness_len: __field0, + witness_compact_len: __field1, + block_len: __field2, + num_extrinsics: __field3, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option = _serde::__private::None; + let mut __field3: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "witnessLen", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "witnessCompactLen", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "blockLen", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private::Option::is_some(&__field3) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "numExtrinsics", + ), + ); + } + __field3 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("witnessLen")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("witnessCompactLen")? + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("blockLen")? + } + }; + let __field3 = match __field3 { + _serde::__private::Some(__field3) => __field3, + _serde::__private::None => { + _serde::__private::de::missing_field("numExtrinsics")? + } + }; + _serde::__private::Ok(BlockStats { + witness_len: __field0, + witness_compact_len: __field1, + block_len: __field2, + num_extrinsics: __field3, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "witnessLen", + "witnessCompactLen", + "blockLen", + "numExtrinsics", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "BlockStats", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// ReadProof struct returned by the RPC + /// + /// # Note + /// + /// This is copied from `sc-rpc-api` to avoid a dependency on that crate. Therefore it + /// must be kept compatible with that type from the target substrate version. + #[serde(rename_all = "camelCase")] + pub struct ReadProof { + /// Block hash used to generate the proof + pub at: Hash, + /// A proof used to prove that storage entries are included in the storage trie + pub proof: Vec, + } + #[automatically_derived] + impl ::core::clone::Clone for ReadProof { + #[inline] + fn clone(&self) -> ReadProof { + ReadProof { + at: ::core::clone::Clone::clone(&self.at), + proof: ::core::clone::Clone::clone(&self.proof), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ReadProof { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "ReadProof", + "at", + &self.at, + "proof", + &&self.proof, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ReadProof {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for ReadProof { + #[inline] + fn eq(&self, other: &ReadProof) -> bool { + self.at == other.at && self.proof == other.proof + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ReadProof { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for ReadProof + where + Hash: _serde::Serialize, + { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "ReadProof", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "at", + &self.at, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "proof", + &self.proof, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for ReadProof + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "at" => _serde::__private::Ok(__Field::__field0), + "proof" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"at" => _serde::__private::Ok(__Field::__field0), + b"proof" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = ReadProof; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct ReadProof", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ReadProof with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct ReadProof with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(ReadProof { + at: __field0, + proof: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option> = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("at"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("proof"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("at")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("proof")? + } + }; + _serde::__private::Ok(ReadProof { + at: __field0, + proof: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["at", "proof"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ReadProof", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// A number type that can be serialized both as a number or a string that encodes a number in a + /// string. + /// + /// We allow two representations of the block number as input. Either we deserialize to the type + /// that is specified in the block type or we attempt to parse given hex value. + /// + /// The primary motivation for having this type is to avoid overflows when using big integers in + /// JavaScript (which we consider as an important RPC API consumer). + #[serde(untagged)] + pub enum NumberOrHex { + /// The number represented directly. + Number(u64), + /// Hex representation of the number. + Hex(U256), + } + #[automatically_derived] + impl ::core::marker::Copy for NumberOrHex {} + #[automatically_derived] + impl ::core::clone::Clone for NumberOrHex { + #[inline] + fn clone(&self) -> NumberOrHex { + let _: ::core::clone::AssertParamIsClone; + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for NumberOrHex { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + NumberOrHex::Number(ref __field0) => { + _serde::Serialize::serialize(__field0, __serializer) + } + NumberOrHex::Hex(ref __field0) => { + _serde::Serialize::serialize(__field0, __serializer) + } + } + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for NumberOrHex { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + let __content = <_serde::__private::de::Content as _serde::Deserialize>::deserialize( + __deserializer, + )?; + let __deserializer = _serde::__private::de::ContentRefDeserializer::< + __D::Error, + >::new(&__content); + if let _serde::__private::Ok(__ok) + = _serde::__private::Result::map( + ::deserialize(__deserializer), + NumberOrHex::Number, + ) { + return _serde::__private::Ok(__ok); + } + if let _serde::__private::Ok(__ok) + = _serde::__private::Result::map( + ::deserialize(__deserializer), + NumberOrHex::Hex, + ) { + return _serde::__private::Ok(__ok); + } + _serde::__private::Err( + _serde::de::Error::custom( + "data did not match any variant of untagged enum NumberOrHex", + ), + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for NumberOrHex { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + NumberOrHex::Number(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Number", + &__self_0, + ) + } + NumberOrHex::Hex(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Hex", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for NumberOrHex {} + #[automatically_derived] + impl ::core::cmp::PartialEq for NumberOrHex { + #[inline] + fn eq(&self, other: &NumberOrHex) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + NumberOrHex::Number(__self_0), + NumberOrHex::Number(__arg1_0), + ) => *__self_0 == *__arg1_0, + (NumberOrHex::Hex(__self_0), NumberOrHex::Hex(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for NumberOrHex { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + impl NumberOrHex { + /// Converts this number into an U256. + pub fn into_u256(self) -> U256 { + match self { + NumberOrHex::Number(n) => n.into(), + NumberOrHex::Hex(h) => h, + } + } + } + impl From for U256 { + fn from(num_or_hex: NumberOrHex) -> U256 { + num_or_hex.into_u256() + } + } + impl From for NumberOrHex { + fn from(x: u8) -> Self { + NumberOrHex::Number(x.into()) + } + } + impl From for NumberOrHex { + fn from(x: u16) -> Self { + NumberOrHex::Number(x.into()) + } + } + impl From for NumberOrHex { + fn from(x: u32) -> Self { + NumberOrHex::Number(x.into()) + } + } + impl From for NumberOrHex { + fn from(x: u64) -> Self { + NumberOrHex::Number(x.into()) + } + } + impl From for NumberOrHex { + fn from(n: u128) -> Self { + NumberOrHex::Hex(n.into()) + } + } + impl From for NumberOrHex { + fn from(n: U256) -> Self { + NumberOrHex::Hex(n) + } + } + /// A quick helper to encode some bytes to hex. + fn to_hex(bytes: impl AsRef<[u8]>) -> String { + { + let res = ::alloc::fmt::format( + format_args!("0x{0}", hex::encode(bytes.as_ref())), + ); + res + } + } + /// Hex-serialized shim for `Vec`. + pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec); + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Bytes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Bytes { + #[inline] + fn eq(&self, other: &Bytes) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Bytes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Bytes { + #[inline] + fn clone(&self) -> Bytes { + Bytes(::core::clone::Clone::clone(&self.0)) + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Bytes { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "Bytes", + { + #[doc(hidden)] + struct __SerializeWith<'__a> { + values: (&'__a Vec,), + phantom: _serde::__private::PhantomData, + } + impl<'__a> _serde::Serialize for __SerializeWith<'__a> { + fn serialize<__S>( + &self, + __s: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + impl_serde::serialize::serialize(self.values.0, __s) + } + } + &__SerializeWith { + values: (&self.0,), + phantom: _serde::__private::PhantomData::, + } + }, + ) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Bytes { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Bytes; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "tuple struct Bytes", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: Vec = impl_serde::serialize::deserialize( + __e, + )?; + _serde::__private::Ok(Bytes(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match { + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: Vec, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: impl_serde::serialize::deserialize(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct Bytes with 1 element", + ), + ); + } + }; + _serde::__private::Ok(Bytes(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "Bytes", + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::hash::Hash for Bytes { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Bytes { + #[inline] + fn partial_cmp( + &self, + other: &Bytes, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Bytes { + #[inline] + fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Bytes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Bytes", + &&self.0, + ) + } + } + impl std::ops::Deref for Bytes { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.0[..] + } + } + impl From> for Bytes { + fn from(s: Vec) -> Self { + Bytes(s) + } + } + } + use self::rpc_methods::TransactionStatus as RpcTransactionStatus; + use crate::backend::{ + rpc::RpcClient, Backend, BlockRef, RuntimeVersion, StorageResponse, StreamOf, + StreamOfResults, TransactionStatus, + }; + use crate::{config::Header, Config, Error}; + use async_trait::async_trait; + use futures::{ + future, future::Either, stream, Future, FutureExt, Stream, StreamExt, + }; + use std::collections::VecDeque; + use std::pin::Pin; + use std::task::{Context, Poll}; + pub use rpc_methods::LegacyRpcMethods; + /// The legacy backend. + pub struct LegacyBackend { + methods: LegacyRpcMethods, + } + #[automatically_derived] + impl ::core::fmt::Debug for LegacyBackend { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "LegacyBackend", + "methods", + &&self.methods, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for LegacyBackend { + #[inline] + fn clone(&self) -> LegacyBackend { + LegacyBackend { + methods: ::core::clone::Clone::clone(&self.methods), + } + } + } + impl LegacyBackend { + /// Instantiate a new backend which uses the legacy API methods. + pub fn new(client: RpcClient) -> Self { + Self { + methods: LegacyRpcMethods::new(client), + } + } + } + impl super::sealed::Sealed for LegacyBackend {} + impl Backend for LegacyBackend { + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_values<'life0, 'async_trait>( + &'life0 self, + keys: Vec>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let keys = keys; + let at = at; + let __ret: Result, Error> = { + let methods = __self.methods.clone(); + let iter = keys + .into_iter() + .map(move |key| { + let methods = methods.clone(); + async move { + let res = methods.state_get_storage(&key, Some(at)).await?; + Ok(res.map(|value| StorageResponse { key, value })) + } + }); + let s = stream::iter(iter) + .then(|fut| fut) + .filter_map(|r| future::ready(r.transpose())); + Ok(StreamOf(Box::pin(s))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_descendant_keys<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>, Error>, + > { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result>, Error> = { + let keys = StorageFetchDescendantKeysStream { + at, + key, + methods: __self.methods.clone(), + done: Default::default(), + keys_fut: Default::default(), + pagination_start_key: None, + }; + let keys = keys + .flat_map(|keys| { + match keys { + Err(e) => { + Either::Left(stream::iter(std::iter::once(Err(e)))) + } + Ok(keys) => { + Either::Right(stream::iter(keys.into_iter().map(Ok))) + } + } + }); + Ok(StreamOf(Box::pin(keys))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_descendant_values<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result, Error> = { + let keys_stream = StorageFetchDescendantKeysStream { + at, + key, + methods: __self.methods.clone(), + done: Default::default(), + keys_fut: Default::default(), + pagination_start_key: None, + }; + Ok( + StreamOf( + Box::pin(StorageFetchDescendantValuesStream { + keys: keys_stream, + results_fut: None, + results: Default::default(), + }), + ), + ) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn genesis_hash<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let __ret: Result = { + __self.methods.genesis_hash().await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn block_header<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result, Error> = { + __self.methods.chain_get_header(Some(at)).await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn block_body<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>>, Error>, + > { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result>>, Error> = { + let Some(details) = __self + .methods + .chain_get_block(Some(at)) + .await? else { return Ok(None); + }; + Ok( + Some( + details.block.extrinsics.into_iter().map(|b| b.0).collect(), + ), + ) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn latest_finalized_block_ref<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result, Error> = { + let hash = __self.methods.chain_get_finalized_head().await?; + Ok(BlockRef::from_hash(hash)) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn current_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let __ret: Result = { + let details = __self + .methods + .state_get_runtime_version(None) + .await?; + Ok(RuntimeVersion { + spec_version: details.spec_version, + transaction_version: details.transaction_version, + }) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result, Error> = { + let sub = __self + .methods + .state_subscribe_runtime_version() + .await?; + let sub = sub + .map(|r| { + r.map(|v| RuntimeVersion { + spec_version: v.spec_version, + transaction_version: v.transaction_version, + }) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_all_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + let sub = __self.methods.chain_subscribe_all_heads().await?; + let sub = sub + .map(|r| { + r.map(|h| { + let hash = h.hash(); + (h, BlockRef::from_hash(hash)) + }) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_best_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + let sub = __self.methods.chain_subscribe_new_heads().await?; + let sub = sub + .map(|r| { + r.map(|h| { + let hash = h.hash(); + (h, BlockRef::from_hash(hash)) + }) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_finalized_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + let sub: super::rpc::RpcSubscription<::Header> = __self + .methods + .chain_subscribe_finalized_heads() + .await?; + let last_finalized_block_ref = __self + .latest_finalized_block_ref() + .await?; + let last_finalized_block_num = __self + .block_header(last_finalized_block_ref.hash()) + .await? + .map(|h| h.number().into()); + let sub = subscribe_to_block_headers_filling_in_gaps( + __self.methods.clone(), + sub, + last_finalized_block_num, + ); + let sub = sub + .map(|r| { + r.map(|h| { + let hash = h.hash(); + (h, BlockRef::from_hash(hash)) + }) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn submit_transaction<'life0, 'life1, 'async_trait>( + &'life0 self, + extrinsic: &'life1 [u8], + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults>, + Error, + > = { + let sub = __self + .methods + .author_submit_and_watch_extrinsic(extrinsic) + .await?; + let sub = sub + .filter_map(|r| { + let mapped = r + .map(|tx| { + match tx { + RpcTransactionStatus::Future => None, + RpcTransactionStatus::Retracted(_) => None, + RpcTransactionStatus::Ready => { + Some(TransactionStatus::Validated) + } + RpcTransactionStatus::Broadcast(peers) => { + Some(TransactionStatus::Broadcasted { + num_peers: peers.len() as u32, + }) + } + RpcTransactionStatus::InBlock(hash) => { + Some(TransactionStatus::InBestBlock { + hash: BlockRef::from_hash(hash), + }) + } + RpcTransactionStatus::FinalityTimeout(_) => { + Some(TransactionStatus::Invalid { + message: "Finality timeout".into(), + }) + } + RpcTransactionStatus::Finalized(hash) => { + Some(TransactionStatus::InFinalizedBlock { + hash: BlockRef::from_hash(hash), + }) + } + RpcTransactionStatus::Usurped(_) => { + Some(TransactionStatus::Invalid { + message: "Transaction was usurped by another with the same nonce" + .into(), + }) + } + RpcTransactionStatus::Dropped => { + Some(TransactionStatus::Dropped { + message: "Transaction was dropped".into(), + }) + } + RpcTransactionStatus::Invalid => { + Some(TransactionStatus::Invalid { + message: "Transaction is invalid (eg because of a bad nonce, signature etc)" + .into(), + }) + } + } + }) + .transpose(); + future::ready(mapped) + }); + Ok(StreamOf(Box::pin(sub))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn call<'life0, 'life1, 'life2, 'async_trait>( + &'life0 self, + method: &'life1 str, + call_parameters: Option<&'life2 [u8]>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + 'life2: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::, Error>> { + return __ret; + } + let __self = self; + let call_parameters = call_parameters; + let at = at; + let __ret: Result, Error> = { + __self + .methods + .state_call(method, call_parameters, Some(at)) + .await + }; + #[allow(unreachable_code)] __ret + }) + } + } + /// Note: This is exposed for testing but is not considered stable and may change + /// without notice in a patch release. + #[doc(hidden)] + pub fn subscribe_to_block_headers_filling_in_gaps( + methods: LegacyRpcMethods, + sub: S, + mut last_block_num: Option, + ) -> impl Stream> + Send + where + T: Config, + S: Stream> + Send, + E: Into + Send + 'static, + { + sub.flat_map(move |s| { + let header = match s { + Ok(header) => header, + Err(e) => return Either::Left(stream::once(async { Err(e.into()) })), + }; + let end_block_num = header.number().into(); + let start_block_num = last_block_num + .map(|n| n + 1) + .unwrap_or(end_block_num); + let methods = methods.clone(); + let previous_headers = stream::iter(start_block_num..end_block_num) + .then(move |n| { + let methods = methods.clone(); + async move { + let hash = methods + .chain_get_block_hash(Some(n.into())) + .await?; + let header = methods.chain_get_header(hash).await?; + Ok::<_, Error>(header) + } + }) + .filter_map(|h| async { h.transpose() }); + last_block_num = Some(end_block_num); + Either::Right(previous_headers.chain(stream::once(async { Ok(header) }))) + }) + } + /// How many keys/values to fetch at once. + const STORAGE_PAGE_SIZE: u32 = 32; + /// This provides a stream of values given some prefix `key`. It + /// internally manages pagination and such. + #[allow(clippy::type_complexity)] + pub struct StorageFetchDescendantKeysStream { + methods: LegacyRpcMethods, + key: Vec, + at: T::Hash, + pagination_start_key: Option>, + keys_fut: Option< + Pin< + Box< + dyn Future>, Error>> + Send + 'static, + >, + >, + >, + done: bool, + } + impl std::marker::Unpin for StorageFetchDescendantKeysStream {} + impl Stream for StorageFetchDescendantKeysStream { + type Item = Result>, Error>; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let mut this = self.as_mut(); + loop { + if this.done { + return Poll::Ready(None); + } + if let Some(mut keys_fut) = this.keys_fut.take() { + let Poll::Ready(keys) = keys_fut.poll_unpin(cx) else { + this.keys_fut = Some(keys_fut); + return Poll::Pending; + }; + match keys { + Ok(keys) => { + if keys.is_empty() { + this.done = true; + return Poll::Ready(None); + } + this.pagination_start_key = keys.last().cloned(); + return Poll::Ready(Some(Ok(keys))); + } + Err(e) => { + return Poll::Ready(Some(Err(e))); + } + } + } + let methods = this.methods.clone(); + let key = this.key.clone(); + let at = this.at; + let pagination_start_key = this.pagination_start_key.take(); + let keys_fut = async move { + methods + .state_get_keys_paged( + &key, + STORAGE_PAGE_SIZE, + pagination_start_key.as_deref(), + Some(at), + ) + .await + }; + this.keys_fut = Some(Box::pin(keys_fut)); + } + } + } + /// This provides a stream of values given some stream of keys. + #[allow(clippy::type_complexity)] + pub struct StorageFetchDescendantValuesStream { + keys: StorageFetchDescendantKeysStream, + results_fut: Option< + Pin< + Box< + dyn Future< + Output = Result, Vec)>>, Error>, + > + Send + 'static, + >, + >, + >, + results: VecDeque<(Vec, Vec)>, + } + impl Stream for StorageFetchDescendantValuesStream { + type Item = Result; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let mut this = self.as_mut(); + loop { + if let Some((key, value)) = this.results.pop_front() { + let res = StorageResponse { key, value }; + return Poll::Ready(Some(Ok(res))); + } + if let Some(mut results_fut) = this.results_fut.take() { + match results_fut.poll_unpin(cx) { + Poll::Ready(Ok(Some(results))) => { + this.results = results; + continue; + } + Poll::Ready(Ok(None)) => { + continue; + } + Poll::Ready(Err(e)) => return Poll::Ready(Some(Err(e))), + Poll::Pending => { + this.results_fut = Some(results_fut); + return Poll::Pending; + } + } + } + match this.keys.poll_next_unpin(cx) { + Poll::Ready(Some(Ok(keys))) => { + let methods = this.keys.methods.clone(); + let at = this.keys.at; + let results_fut = async move { + let keys = keys.iter().map(|k| &**k); + let values = methods + .state_query_storage_at(keys, Some(at)) + .await?; + let values: VecDeque<_> = values + .into_iter() + .flat_map(|v| { + v.changes + .into_iter() + .filter_map(|(k, v)| { + let v = v?; + Some((k.0, v.0)) + }) + }) + .collect(); + Ok(Some(values)) + }; + this.results_fut = Some(Box::pin(results_fut)); + continue; + } + Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(e))), + Poll::Ready(None) => return Poll::Ready(None), + Poll::Pending => return Poll::Pending, + } + } + } + } + } + pub mod rpc { + //! RPC types and client for interacting with a substrate node. + //! + //! These are used behind the scenes by Subxt backend implementations, for + //! example [`crate::backend::legacy::LegacyBackend`]. If you need an RPC client, + //! then you can manually instantiate one, and then hand it to Subxt if you'd like + //! to re-use it for the Subxt connection. + //! + //! - [`RpcClientT`] is the underlying dynamic RPC implementation. This provides + //! the low level [`RpcClientT::request_raw`] and [`RpcClientT::subscribe_raw`] + //! methods. + //! - [`RpcClient`] is the higher level wrapper around this, offering + //! the [`RpcClient::request`] and [`RpcClient::subscribe`] methods. + //! + //! # Example + //! + //! Fetching the genesis hash. + //! + //! ```no_run + //! # #[tokio::main] + //! # async fn main() { + //! use subxt::{ + //! client::OnlineClient, + //! config::SubstrateConfig, + //! backend::rpc::RpcClient, + //! backend::legacy::LegacyRpcMethods, + //! }; + //! + //! // Instantiate a default RPC client pointing at some URL. + //! let rpc_client = RpcClient::from_url("ws://localhost:9944") + //! .await + //! .unwrap(); + //! + //! // Instantiate the legacy RPC interface, providing an appropriate + //! // config so that it uses the correct types for your chain. + //! let rpc_methods = LegacyRpcMethods::::new(rpc_client.clone()); + //! + //! // Use it to make RPC calls, here using the legacy genesis_hash method. + //! let genesis_hash = rpc_methods + //! .genesis_hash() + //! .await + //! .unwrap(); + //! + //! println!("{genesis_hash}"); + //! + //! // Instantiate the Subxt interface using the same client and config if you + //! // want to reuse the same connection: + //! let client = OnlineClient::::from_rpc_client(rpc_client); + //! # } + //! ``` + #![allow(clippy::module_inception)] + #[cfg(feature = "jsonrpsee")] + mod jsonrpsee_impl { + use super::{RawRpcFuture, RawRpcSubscription, RpcClientT}; + use crate::error::RpcError; + use futures::stream::{StreamExt, TryStreamExt}; + use jsonrpsee::{ + core::{ + client::{Client, ClientT, SubscriptionClientT, SubscriptionKind}, + traits::ToRpcParams, + }, + types::SubscriptionId, + }; + use serde_json::value::RawValue; + struct Params(Option>); + impl ToRpcParams for Params { + fn to_rpc_params( + self, + ) -> Result>, serde_json::Error> { + Ok(self.0) + } + } + impl RpcClientT for Client { + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box> { + Box::pin(async move { + let res = ClientT::request(self, method, Params(params)) + .await + .map_err(|e| RpcError::ClientError(Box::new(e)))?; + Ok(res) + }) + } + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription> { + Box::pin(async move { + let stream = SubscriptionClientT::subscribe::< + Box, + _, + >(self, sub, Params(params), unsub) + .await + .map_err(|e| RpcError::ClientError(Box::new(e)))?; + let id = match stream.kind() { + SubscriptionKind::Subscription(SubscriptionId::Str(id)) => { + Some(id.clone().into_owned()) + } + _ => None, + }; + let stream = stream + .map_err(|e| RpcError::ClientError(Box::new(e))) + .boxed(); + Ok(RawRpcSubscription { stream, id }) + }) + } + } + } + mod rpc_client { + use super::{RawRpcSubscription, RpcClientT}; + use crate::error::Error; + use futures::{Stream, StreamExt}; + use serde::{de::DeserializeOwned, Serialize}; + use serde_json::value::RawValue; + use std::{pin::Pin, sync::Arc, task::Poll}; + /// A concrete wrapper around an [`RpcClientT`] which provides some higher level helper methods, + /// is cheaply cloneable, and can be handed to things like [`crate::client::OnlineClient`] to + /// instantiate it. + pub struct RpcClient { + client: Arc, + } + #[automatically_derived] + impl ::core::clone::Clone for RpcClient { + #[inline] + fn clone(&self) -> RpcClient { + RpcClient { + client: ::core::clone::Clone::clone(&self.client), + } + } + } + impl RpcClient { + #[cfg(feature = "jsonrpsee")] + /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. + /// + /// Errors if an insecure URL is provided. In this case, use [`RpcClient::from_insecure_url`] instead. + pub async fn from_url>(url: U) -> Result { + crate::utils::validate_url_is_secure(url.as_ref())?; + RpcClient::from_insecure_url(url).await + } + #[cfg(feature = "jsonrpsee")] + /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. + /// + /// Allows insecure URLs without SSL encryption, e.g. (http:// and ws:// URLs). + pub async fn from_insecure_url>( + url: U, + ) -> Result { + let client = jsonrpsee_helpers::client(url.as_ref()) + .await + .map_err(|e| crate::error::RpcError::ClientError(Box::new(e)))?; + Ok(Self::new(client)) + } + /// Create a new [`RpcClient`] from an arbitrary [`RpcClientT`] implementation. + pub fn new(client: R) -> Self { + RpcClient { + client: Arc::new(client), + } + } + /// Make an RPC request, given a method name and some parameters. + /// + /// See [`RpcParams`] and the [`rpc_params!`] macro for an example of how to + /// construct the parameters. + pub async fn request( + &self, + method: &str, + params: RpcParams, + ) -> Result { + let res = self.client.request_raw(method, params.build()).await?; + let val = serde_json::from_str(res.get())?; + Ok(val) + } + /// Subscribe to an RPC endpoint, providing the parameters and the method to call to + /// unsubscribe from it again. + /// + /// See [`RpcParams`] and the [`rpc_params!`] macro for an example of how to + /// construct the parameters. + pub async fn subscribe( + &self, + sub: &str, + params: RpcParams, + unsub: &str, + ) -> Result, Error> { + let sub = self + .client + .subscribe_raw(sub, params.build(), unsub) + .await?; + Ok(RpcSubscription::new(sub)) + } + } + impl std::fmt::Debug for RpcClient { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("RpcClient").finish() + } + } + impl std::ops::Deref for RpcClient { + type Target = dyn RpcClientT; + fn deref(&self) -> &Self::Target { + &*self.client + } + } + pub use rpc_params; + /// This represents the parameters passed to an [`RpcClient`], and exists to + /// enforce that parameters are provided in the correct format. + /// + /// Prefer to use the [`rpc_params!`] macro for simpler creation of these. + /// + /// # Example + /// + /// ```rust + /// use subxt::backend::rpc::RpcParams; + /// + /// let mut params = RpcParams::new(); + /// params.push(1).unwrap(); + /// params.push(true).unwrap(); + /// params.push("foo").unwrap(); + /// + /// assert_eq!(params.build().unwrap().get(), "[1,true,\"foo\"]"); + /// ``` + pub struct RpcParams(Vec); + #[automatically_derived] + impl ::core::fmt::Debug for RpcParams { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "RpcParams", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RpcParams { + #[inline] + fn clone(&self) -> RpcParams { + RpcParams(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::default::Default for RpcParams { + #[inline] + fn default() -> RpcParams { + RpcParams(::core::default::Default::default()) + } + } + impl RpcParams { + /// Create a new empty set of [`RpcParams`]. + pub fn new() -> Self { + Self(Vec::new()) + } + /// Push a parameter into our [`RpcParams`]. This serializes it to JSON + /// in the process, and so will return an error if this is not possible. + pub fn push(&mut self, param: P) -> Result<(), Error> { + if self.0.is_empty() { + self.0.push(b'['); + } else { + self.0.push(b',') + } + serde_json::to_writer(&mut self.0, ¶m)?; + Ok(()) + } + /// Build a [`RawValue`] from our params, returning `None` if no parameters + /// were provided. + pub fn build(mut self) -> Option> { + if self.0.is_empty() { + None + } else { + self.0.push(b']'); + let s = unsafe { String::from_utf8_unchecked(self.0) }; + Some(RawValue::from_string(s).expect("Should be valid JSON")) + } + } + } + /// A generic RPC Subscription. This implements [`Stream`], and so most of + /// the functionality you'll need to interact with it comes from the + /// [`StreamExt`] extension trait. + pub struct RpcSubscription { + inner: RawRpcSubscription, + _marker: std::marker::PhantomData, + } + impl std::fmt::Debug for RpcSubscription { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("RpcSubscription") + .field("inner", &"RawRpcSubscription") + .field("_marker", &self._marker) + .finish() + } + } + impl RpcSubscription { + /// Creates a new [`RpcSubscription`]. + pub fn new(inner: RawRpcSubscription) -> Self { + Self { + inner, + _marker: std::marker::PhantomData, + } + } + /// Obtain the ID associated with this subscription. + pub fn subscription_id(&self) -> Option<&str> { + self.inner.id.as_deref() + } + } + impl RpcSubscription { + /// Returns the next item in the stream. This is just a wrapper around + /// [`StreamExt::next()`] so that you can avoid the extra import. + pub async fn next(&mut self) -> Option> { + StreamExt::next(self).await + } + } + impl std::marker::Unpin for RpcSubscription {} + impl Stream for RpcSubscription { + type Item = Result; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let res = match self.inner.stream.poll_next_unpin(cx) { + ::futures_core::task::Poll::Ready(t) => t, + ::futures_core::task::Poll::Pending => { + return ::futures_core::task::Poll::Pending; + } + }; + let res = res + .map(|r| { + r.map_err(|e| e.into()) + .and_then(|raw_val| { + serde_json::from_str(raw_val.get()).map_err(|e| e.into()) + }) + }); + Poll::Ready(res) + } + } + #[cfg(all(feature = "jsonrpsee", feature = "native"))] + mod jsonrpsee_helpers { + pub use jsonrpsee::{ + client_transport::ws::{ + self, EitherStream, Url, WsTransportClientBuilder, + }, + core::client::{Client, Error}, + }; + use tokio_util::compat::Compat; + pub type Sender = ws::Sender>; + pub type Receiver = ws::Receiver>; + /// Build WS RPC client from URL + pub async fn client(url: &str) -> Result { + let (sender, receiver) = ws_transport(url).await?; + Ok( + Client::builder() + .max_buffer_capacity_per_subscription(4096) + .build_with_tokio(sender, receiver), + ) + } + async fn ws_transport(url: &str) -> Result<(Sender, Receiver), Error> { + let url = Url::parse(url).map_err(|e| Error::Transport(e.into()))?; + WsTransportClientBuilder::default() + .build(url) + .await + .map_err(|e| Error::Transport(e.into())) + } + } + } + mod rpc_client_t { + use crate::error::RpcError; + use futures::Stream; + use std::{future::Future, pin::Pin}; + pub use serde_json::value::RawValue; + /// A trait describing low level JSON-RPC interactions. Implementations of this can be + /// used to instantiate a [`super::RpcClient`], which can be passed to [`crate::OnlineClient`] + /// or used for lower level RPC calls via eg [`crate::backend::legacy::LegacyRpcMethods`]. + /// + /// This is a low level interface whose methods expect an already-serialized set of params, + /// and return an owned but still-serialized [`RawValue`], deferring deserialization to + /// the caller. This is the case because we want the methods to be object-safe (which prohibits + /// generics), and want to avoid any unnecessary allocations in serializing/deserializing + /// parameters. + /// + /// # Panics + /// + /// Implementations are free to panic if the `RawValue`'s passed to `request_raw` or + /// `subscribe_raw` are not JSON arrays. Internally, we ensure that this is always the case. + pub trait RpcClientT: Send + Sync + 'static { + /// Make a raw request for which we expect a single response back from. Implementations + /// should expect that the params will either be `None`, or be an already-serialized + /// JSON array of parameters. + /// + /// See [`super::RpcParams`] and the [`super::rpc_params!`] macro for an example of how to + /// construct the parameters. + /// + /// Prefer to use the interface provided on [`super::RpcClient`] where possible. + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box>; + /// Subscribe to some method. Implementations should expect that the params will + /// either be `None`, or be an already-serialized JSON array of parameters. + /// + /// See [`super::RpcParams`] and the [`super::rpc_params!`] macro for an example of how to + /// construct the parameters. + /// + /// Prefer to use the interface provided on [`super::RpcClient`] where possible. + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription>; + } + /// A boxed future that is returned from the [`RpcClientT`] methods. + pub type RawRpcFuture<'a, T> = Pin< + Box> + Send + 'a>, + >; + /// The RPC subscription returned from [`RpcClientT`]'s `subscription` method. + pub struct RawRpcSubscription { + /// The subscription stream. + pub stream: Pin< + Box< + dyn Stream< + Item = Result, RpcError>, + > + Send + 'static, + >, + >, + /// The ID associated with the subscription. + pub id: Option, + } + impl RpcClientT for std::sync::Arc { + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box> { + (**self).request_raw(method, params) + } + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription> { + (**self).subscribe_raw(sub, params, unsub) + } + } + impl RpcClientT for Box { + fn request_raw<'a>( + &'a self, + method: &'a str, + params: Option>, + ) -> RawRpcFuture<'a, Box> { + (**self).request_raw(method, params) + } + fn subscribe_raw<'a>( + &'a self, + sub: &'a str, + params: Option>, + unsub: &'a str, + ) -> RawRpcFuture<'a, RawRpcSubscription> { + (**self).subscribe_raw(sub, params, unsub) + } + } + } + pub use rpc_client::{rpc_params, RpcClient, RpcParams, RpcSubscription}; + pub use rpc_client_t::{RawRpcFuture, RawRpcSubscription, RawValue, RpcClientT}; + } + pub mod unstable { + //! This module will expose a backend implementation based on the new APIs + //! described at . See + //! [`rpc_methods`] for the raw API calls. + //! + //! # Warning + //! + //! Everything in this module is **unstable**, meaning that it could change without + //! warning at any time. + mod follow_stream { + use super::rpc_methods::{FollowEvent, UnstableRpcMethods}; + use crate::config::Config; + use crate::error::Error; + use futures::{FutureExt, Stream, StreamExt}; + use std::future::Future; + use std::pin::Pin; + use std::task::{Context, Poll}; + /// A `Stream` whose goal is to remain subscribed to `chainHead_follow`. It will re-subscribe if the subscription + /// is ended for any reason, and it will return the current `subscription_id` as an event, along with the other + /// follow events. + pub struct FollowStream { + stream_getter: FollowEventStreamGetter, + stream: InnerStreamState, + } + impl std::fmt::Debug for FollowStream { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("FollowStream") + .field("stream_getter", &"..") + .field("stream", &self.stream) + .finish() + } + } + /// A getter function that returns an [`FollowEventStreamFut`]. + pub type FollowEventStreamGetter = Box< + dyn FnMut() -> FollowEventStreamFut + Send, + >; + /// The future which will return a stream of follow events and the subscription ID for it. + pub type FollowEventStreamFut = Pin< + Box< + dyn Future< + Output = Result<(FollowEventStream, String), Error>, + > + Send + 'static, + >, + >; + /// The stream of follow events. + pub type FollowEventStream = Pin< + Box, Error>> + Send + 'static>, + >; + /// Either a ready message with the current subscription ID, or + /// an event from the stream itself. + pub enum FollowStreamMsg { + /// The stream is ready (and has a subscription ID) + Ready(String), + /// An event from the stream. + Event(FollowEvent), + } + #[automatically_derived] + impl ::core::fmt::Debug for FollowStreamMsg { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + FollowStreamMsg::Ready(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Ready", + &__self_0, + ) + } + FollowStreamMsg::Event(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Event", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone + for FollowStreamMsg { + #[inline] + fn clone(&self) -> FollowStreamMsg { + match self { + FollowStreamMsg::Ready(__self_0) => { + FollowStreamMsg::Ready(::core::clone::Clone::clone(__self_0)) + } + FollowStreamMsg::Event(__self_0) => { + FollowStreamMsg::Event(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for FollowStreamMsg {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for FollowStreamMsg { + #[inline] + fn eq(&self, other: &FollowStreamMsg) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + FollowStreamMsg::Ready(__self_0), + FollowStreamMsg::Ready(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowStreamMsg::Event(__self_0), + FollowStreamMsg::Event(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for FollowStreamMsg { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + impl FollowStreamMsg { + /// Return an event, or none if the message is a "ready" one. + pub fn into_event(self) -> Option> { + match self { + FollowStreamMsg::Ready(_) => None, + FollowStreamMsg::Event(e) => Some(e), + } + } + } + enum InnerStreamState { + /// We've just created the stream; we'll start Initializing it + New, + /// We're fetching the inner subscription. Move to Ready when we have one. + Initializing(FollowEventStreamFut), + /// Report back the subscription ID here, and then start ReceivingEvents. + Ready(Option<(FollowEventStream, String)>), + /// We are polling for, and receiving events from the stream. + ReceivingEvents(FollowEventStream), + /// We received a stop event. We'll send one on and restart the stream. + Stopped, + /// The stream is finished and will not restart (likely due to an error). + Finished, + } + impl std::fmt::Debug for InnerStreamState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::New => f.write_fmt(format_args!("New")), + Self::Initializing(_) => { + f.write_fmt(format_args!("Initializing(..)")) + } + Self::Ready(_) => f.write_fmt(format_args!("Ready(..)")), + Self::ReceivingEvents(_) => { + f.write_fmt(format_args!("ReceivingEvents(..)")) + } + Self::Stopped => f.write_fmt(format_args!("Stopped")), + Self::Finished => f.write_fmt(format_args!("Finished")), + } + } + } + impl FollowStream { + /// Create a new [`FollowStream`] given a function which returns the stream. + pub fn new(stream_getter: FollowEventStreamGetter) -> Self { + Self { + stream_getter, + stream: InnerStreamState::New, + } + } + /// Create a new [`FollowStream`] given the RPC methods. + pub fn from_methods( + methods: UnstableRpcMethods, + ) -> FollowStream { + FollowStream { + stream_getter: Box::new(move || { + let methods = methods.clone(); + Box::pin(async move { + let stream = methods.chainhead_unstable_follow(true).await?; + let Some(sub_id) = stream + .subscription_id() + .map(ToOwned::to_owned) else { + return Err( + Error::Other( + "Subscription ID expected for chainHead_follow response, but not given" + .to_owned(), + ), + ); + }; + let stream: FollowEventStream = Box::pin(stream); + Ok((stream, sub_id)) + }) + }), + stream: InnerStreamState::New, + } + } + } + impl std::marker::Unpin for FollowStream {} + impl Stream for FollowStream { + type Item = Result, Error>; + fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let this = self.get_mut(); + loop { + match &mut this.stream { + InnerStreamState::New => { + let fut = (this.stream_getter)(); + this.stream = InnerStreamState::Initializing(fut); + continue; + } + InnerStreamState::Initializing(fut) => { + match fut.poll_unpin(cx) { + Poll::Pending => { + return Poll::Pending; + } + Poll::Ready(Ok(sub_with_id)) => { + this.stream = InnerStreamState::Ready(Some(sub_with_id)); + continue; + } + Poll::Ready(Err(e)) => { + this.stream = InnerStreamState::Finished; + return Poll::Ready(Some(Err(e))); + } + } + } + InnerStreamState::Ready(stream) => { + let (sub, sub_id) = stream + .take() + .expect("should always be Some"); + this.stream = InnerStreamState::ReceivingEvents(sub); + return Poll::Ready( + Some(Ok(FollowStreamMsg::Ready(sub_id))), + ); + } + InnerStreamState::ReceivingEvents(stream) => { + match stream.poll_next_unpin(cx) { + Poll::Pending => { + return Poll::Pending; + } + Poll::Ready(None) => { + this.stream = InnerStreamState::Stopped; + continue; + } + Poll::Ready(Some(Ok(ev))) => { + if let FollowEvent::Stop = ev { + this.stream = InnerStreamState::Stopped; + continue; + } + return Poll::Ready(Some(Ok(FollowStreamMsg::Event(ev)))); + } + Poll::Ready(Some(Err(e))) => { + this.stream = InnerStreamState::Finished; + return Poll::Ready(Some(Err(e))); + } + } + } + InnerStreamState::Stopped => { + this.stream = InnerStreamState::New; + return Poll::Ready( + Some(Ok(FollowStreamMsg::Event(FollowEvent::Stop))), + ); + } + InnerStreamState::Finished => { + return Poll::Ready(None); + } + } + } + } + } + } + mod follow_stream_driver { + use super::follow_stream_unpin::{ + BlockRef, FollowStreamMsg, FollowStreamUnpin, + }; + use crate::backend::unstable::rpc_methods::{ + FollowEvent, Initialized, RuntimeEvent, + }; + use crate::config::BlockHash; + use crate::error::Error; + use futures::stream::{Stream, StreamExt}; + use std::collections::{HashMap, HashSet, VecDeque}; + use std::ops::DerefMut; + use std::pin::Pin; + use std::sync::{Arc, Mutex}; + use std::task::{Context, Poll, Waker}; + /// A `Stream` which builds on `FollowStreamDriver`, and allows multiple subscribers to obtain events + /// from the single underlying subscription (each being provided an `Initialized` message and all new + /// blocks since then, as if they were each creating a unique `chainHead_follow` subscription). This + /// is the "top" layer of our follow stream subscriptions, and the one that's interacted with elsewhere. + pub struct FollowStreamDriver { + inner: FollowStreamUnpin, + shared: Shared, + } + #[automatically_derived] + impl ::core::fmt::Debug + for FollowStreamDriver { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "FollowStreamDriver", + "inner", + &self.inner, + "shared", + &&self.shared, + ) + } + } + impl FollowStreamDriver { + /// Create a new [`FollowStreamDriver`]. This must be polled by some executor + /// in order for any progress to be made. Things can subscribe to events. + pub fn new(follow_unpin: FollowStreamUnpin) -> Self { + Self { + inner: follow_unpin, + shared: Shared::default(), + } + } + /// Return a handle from which we can create new subscriptions to follow events. + pub fn handle(&self) -> FollowStreamDriverHandle { + FollowStreamDriverHandle { + shared: self.shared.clone(), + } + } + } + impl Stream for FollowStreamDriver { + type Item = Result<(), Error>; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + match self.inner.poll_next_unpin(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(None) => { + self.shared.done(); + Poll::Ready(None) + } + Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))), + Poll::Ready(Some(Ok(item))) => { + self.shared.push_item(item); + Poll::Ready(Some(Ok(()))) + } + } + } + } + /// A handle that can be used to create subscribers, but that doesn't + /// itself subscribe to events. + pub struct FollowStreamDriverHandle { + shared: Shared, + } + #[automatically_derived] + impl ::core::fmt::Debug + for FollowStreamDriverHandle { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "FollowStreamDriverHandle", + "shared", + &&self.shared, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for FollowStreamDriverHandle { + #[inline] + fn clone(&self) -> FollowStreamDriverHandle { + FollowStreamDriverHandle { + shared: ::core::clone::Clone::clone(&self.shared), + } + } + } + impl FollowStreamDriverHandle { + /// Subscribe to follow events. + pub fn subscribe(&self) -> FollowStreamDriverSubscription { + self.shared.subscribe() + } + } + /// A subscription to events from the [`FollowStreamDriver`]. All subscriptions + /// begin first with a `Ready` event containing the current subscription ID, and + /// then with an `Initialized` event containing the latest finalized block and latest + /// runtime information, and then any new/best block events and so on received since + /// the latest finalized block. + pub struct FollowStreamDriverSubscription { + id: usize, + done: bool, + shared: Shared, + local_items: VecDeque>>, + } + #[automatically_derived] + impl ::core::fmt::Debug + for FollowStreamDriverSubscription { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "FollowStreamDriverSubscription", + "id", + &self.id, + "done", + &self.done, + "shared", + &self.shared, + "local_items", + &&self.local_items, + ) + } + } + impl Stream for FollowStreamDriverSubscription { + type Item = FollowStreamMsg>; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + if self.done { + return Poll::Ready(None); + } + loop { + if let Some(item) = self.local_items.pop_front() { + return Poll::Ready(Some(item)); + } + let items = self + .shared + .take_items_and_save_waker(self.id, cx.waker()); + let Some(items) = items else { self.done = true; + return Poll::Ready(None); + }; + if items.is_empty() { + return Poll::Pending; + } else { + self.local_items = items; + } + } + } + } + impl FollowStreamDriverSubscription { + /// Return the current subscription ID. If the subscription has stopped, then this will + /// wait until a new subscription has started with a new ID. + pub async fn subscription_id(self) -> Option { + let ready_event = self + .skip_while(|ev| std::future::ready( + !match ev { + FollowStreamMsg::Ready(_) => true, + _ => false, + }, + )) + .next() + .await?; + match ready_event { + FollowStreamMsg::Ready(sub_id) => Some(sub_id), + _ => None, + } + } + /// Subscribe to the follow events, ignoring any other messages. + pub fn events( + self, + ) -> impl Stream>> + Send + Sync { + self.filter_map(|ev| std::future::ready(ev.into_event())) + } + } + impl Clone for FollowStreamDriverSubscription { + fn clone(&self) -> Self { + self.shared.subscribe() + } + } + impl Drop for FollowStreamDriverSubscription { + fn drop(&mut self) { + self.shared.remove_sub(self.id); + } + } + /// Locked shared state. The driver stream will access this state to push + /// events to any subscribers, and subscribers will access it to pull the + /// events destined for themselves. + struct Shared(Arc>>); + #[automatically_derived] + impl ::core::fmt::Debug + for Shared { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Shared", + &&self.0, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for Shared { + #[inline] + fn clone(&self) -> Shared { + Shared(::core::clone::Clone::clone(&self.0)) + } + } + struct SharedState { + done: bool, + next_id: usize, + subscribers: HashMap>, + /// Keep a buffer of all events that should be handed to a new subscription. + block_events_for_new_subscriptions: VecDeque< + FollowEvent>, + >, + current_subscription_id: Option, + current_init_message: Option>>, + seen_runtime_events: HashMap, + } + #[automatically_derived] + impl ::core::fmt::Debug + for SharedState { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "done", + "next_id", + "subscribers", + "block_events_for_new_subscriptions", + "current_subscription_id", + "current_init_message", + "seen_runtime_events", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.done, + &self.next_id, + &self.subscribers, + &self.block_events_for_new_subscriptions, + &self.current_subscription_id, + &self.current_init_message, + &&self.seen_runtime_events, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "SharedState", + names, + values, + ) + } + } + impl Default for Shared { + fn default() -> Self { + Shared( + Arc::new( + Mutex::new(SharedState { + next_id: 1, + done: false, + subscribers: HashMap::new(), + current_init_message: None, + current_subscription_id: None, + seen_runtime_events: HashMap::new(), + block_events_for_new_subscriptions: VecDeque::new(), + }), + ), + ) + } + } + impl Shared { + /// Set the shared state to "done"; no more items will be handed to it. + pub fn done(&self) { + let mut shared = self.0.lock().unwrap(); + shared.done = true; + } + /// Cleanup a subscription. + pub fn remove_sub(&self, sub_id: usize) { + let mut shared = self.0.lock().unwrap(); + shared.subscribers.remove(&sub_id); + } + /// Take items for some subscription ID and save the waker. + pub fn take_items_and_save_waker( + &self, + sub_id: usize, + waker: &Waker, + ) -> Option>>> { + let mut shared = self.0.lock().unwrap(); + let is_done = shared.done; + let details = shared.subscribers.get_mut(&sub_id)?; + if details.items.is_empty() && is_done { + return None; + } + let items = std::mem::take(&mut details.items); + if !is_done { + details.waker = Some(waker.clone()); + } + Some(items) + } + /// Push a new item out to subscribers. + pub fn push_item(&self, item: FollowStreamMsg>) { + let mut shared = self.0.lock().unwrap(); + let shared = shared.deref_mut(); + for details in shared.subscribers.values_mut() { + details.items.push_back(item.clone()); + if let Some(waker) = details.waker.take() { + waker.wake(); + } + } + match item { + FollowStreamMsg::Ready(sub_id) => { + shared.current_subscription_id = Some(sub_id); + } + FollowStreamMsg::Event(FollowEvent::Initialized(ev)) => { + shared.current_init_message = Some(ev.clone()); + shared.block_events_for_new_subscriptions.clear(); + } + FollowStreamMsg::Event(FollowEvent::Finalized(finalized_ev)) => { + if let Some(init_message) = &mut shared.current_init_message + { + let newest_runtime = finalized_ev + .finalized_block_hashes + .iter() + .rev() + .filter_map(|h| { + shared.seen_runtime_events.get(&h.hash()).cloned() + }) + .next(); + shared.seen_runtime_events.clear(); + if let Some(finalized) + = finalized_ev.finalized_block_hashes.last() + { + init_message.finalized_block_hash = finalized.clone(); + } + if let Some(runtime_ev) = newest_runtime { + init_message.finalized_block_runtime = Some(runtime_ev); + } + } + let to_remove: HashSet = finalized_ev + .finalized_block_hashes + .iter() + .chain(finalized_ev.pruned_block_hashes.iter()) + .map(|h| h.hash()) + .collect(); + shared + .block_events_for_new_subscriptions + .retain(|ev| match ev { + FollowEvent::NewBlock(new_block_ev) => { + !to_remove.contains(&new_block_ev.block_hash.hash()) + } + FollowEvent::BestBlockChanged(best_block_ev) => { + !to_remove.contains(&best_block_ev.best_block_hash.hash()) + } + _ => true, + }); + } + FollowStreamMsg::Event(FollowEvent::NewBlock(new_block_ev)) => { + if let Some(runtime_event) = &new_block_ev.new_runtime { + shared + .seen_runtime_events + .insert( + new_block_ev.block_hash.hash(), + runtime_event.clone(), + ); + } + shared + .block_events_for_new_subscriptions + .push_back(FollowEvent::NewBlock(new_block_ev)); + } + FollowStreamMsg::Event( + ev @ FollowEvent::BestBlockChanged(_), + ) => { + shared.block_events_for_new_subscriptions.push_back(ev); + } + FollowStreamMsg::Event(FollowEvent::Stop) => { + shared.block_events_for_new_subscriptions.clear(); + shared.current_subscription_id = None; + shared.current_init_message = None; + } + _ => {} + } + } + /// Create a new subscription. + pub fn subscribe(&self) -> FollowStreamDriverSubscription { + let mut shared = self.0.lock().unwrap(); + let id = shared.next_id; + shared.next_id += 1; + shared + .subscribers + .insert( + id, + SubscriberDetails { + items: VecDeque::new(), + waker: None, + }, + ); + let mut local_items = VecDeque::new(); + if let Some(sub_id) = &shared.current_subscription_id { + local_items.push_back(FollowStreamMsg::Ready(sub_id.clone())); + } + if let Some(init_msg) = &shared.current_init_message { + local_items + .push_back( + FollowStreamMsg::Event( + FollowEvent::Initialized(init_msg.clone()), + ), + ); + } + for ev in &shared.block_events_for_new_subscriptions { + local_items.push_back(FollowStreamMsg::Event(ev.clone())); + } + drop(shared); + FollowStreamDriverSubscription { + id, + done: false, + shared: self.clone(), + local_items, + } + } + } + /// Details for a given subscriber: any items it's not yet claimed, + /// and a way to wake it up when there are more items for it. + struct SubscriberDetails { + items: VecDeque>>, + waker: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug + for SubscriberDetails { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "SubscriberDetails", + "items", + &self.items, + "waker", + &&self.waker, + ) + } + } + } + mod follow_stream_unpin { + use super::follow_stream::FollowStream; + use super::UnstableRpcMethods; + use crate::backend::unstable::rpc_methods::{ + BestBlockChanged, Finalized, FollowEvent, Initialized, NewBlock, + }; + use crate::config::{BlockHash, Config}; + use crate::error::Error; + use futures::stream::{FuturesUnordered, Stream, StreamExt}; + use std::collections::{HashMap, HashSet}; + use std::future::Future; + use std::pin::Pin; + use std::sync::{Arc, Mutex}; + use std::task::{Context, Poll, Waker}; + /// The type of stream item. + pub use super::follow_stream::FollowStreamMsg; + /// A `Stream` which builds on `FollowStream`, and handles pinning. It replaces any block hash seen in + /// the follow events with a `BlockRef` which, when all clones are dropped, will lead to an "unpin" call + /// for that block hash being queued. It will also automatically unpin any blocks that exceed a given max + /// age, to try and prevent the underlying stream from ending (and _all_ blocks from being unpinned as a + /// result). Put simply, it tries to keep every block pinned as long as possible until the block is no longer + /// used anywhere. + pub struct FollowStreamUnpin { + inner: FollowStream, + unpin_method: UnpinMethodHolder, + unpin_futs: FuturesUnordered, + rel_block_num: usize, + subscription_id: Option>, + max_block_life: usize, + pinned: HashMap>, + unpin_flags: UnpinFlags, + } + #[automatically_derived] + impl ::core::fmt::Debug + for FollowStreamUnpin { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "inner", + "unpin_method", + "unpin_futs", + "rel_block_num", + "subscription_id", + "max_block_life", + "pinned", + "unpin_flags", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.inner, + &self.unpin_method, + &self.unpin_futs, + &self.rel_block_num, + &self.subscription_id, + &self.max_block_life, + &self.pinned, + &&self.unpin_flags, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "FollowStreamUnpin", + names, + values, + ) + } + } + struct UnpinMethodHolder(UnpinMethod); + impl std::fmt::Debug for UnpinMethodHolder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt( + format_args!( + "UnpinMethodHolder(Box) -> UnpinFut>)" + ), + ) + } + } + /// The type of the unpin method that we need to provide. + pub type UnpinMethod = Box< + dyn FnMut(Hash, Arc) -> UnpinFut + Send, + >; + /// The future returned from [`UnpinMethod`]. + pub type UnpinFut = Pin + Send + 'static>>; + impl std::marker::Unpin for FollowStreamUnpin {} + impl Stream for FollowStreamUnpin { + type Item = Result>, Error>; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + let mut this = self.as_mut(); + loop { + let unpin_futs_are_pending = match this + .unpin_futs + .poll_next_unpin(cx) + { + Poll::Ready(Some(())) => continue, + Poll::Ready(None) => false, + Poll::Pending => true, + }; + let Poll::Ready(ev) = this.inner.poll_next_unpin(cx) else { + return Poll::Pending; + }; + let Some(ev) = ev else { + return match unpin_futs_are_pending { + true => Poll::Pending, + false => Poll::Ready(None), + }; + }; + let ev = match ev { + Ok(ev) => ev, + Err(e) => { + return Poll::Ready(Some(Err(e))); + } + }; + let ev = match ev { + FollowStreamMsg::Ready(subscription_id) => { + this.subscription_id = Some(subscription_id.clone().into()); + FollowStreamMsg::Ready(subscription_id) + } + FollowStreamMsg::Event( + FollowEvent::Initialized(details), + ) => { + let rel_block_num = this.rel_block_num; + let block_ref = this + .pin_unpinnable_block_at( + rel_block_num, + details.finalized_block_hash, + ); + FollowStreamMsg::Event( + FollowEvent::Initialized(Initialized { + finalized_block_hash: block_ref, + finalized_block_runtime: details.finalized_block_runtime, + }), + ) + } + FollowStreamMsg::Event(FollowEvent::NewBlock(details)) => { + let parent_rel_block_num = this + .pinned + .get(&details.parent_block_hash) + .map(|p| p.rel_block_num) + .unwrap_or(this.rel_block_num); + let block_ref = this + .pin_block_at(parent_rel_block_num + 1, details.block_hash); + let parent_block_ref = this + .pin_block_at( + parent_rel_block_num, + details.parent_block_hash, + ); + FollowStreamMsg::Event( + FollowEvent::NewBlock(NewBlock { + block_hash: block_ref, + parent_block_hash: parent_block_ref, + new_runtime: details.new_runtime, + }), + ) + } + FollowStreamMsg::Event( + FollowEvent::BestBlockChanged(details), + ) => { + let rel_block_num = this.rel_block_num + 1; + let block_ref = this + .pin_block_at(rel_block_num, details.best_block_hash); + FollowStreamMsg::Event( + FollowEvent::BestBlockChanged(BestBlockChanged { + best_block_hash: block_ref, + }), + ) + } + FollowStreamMsg::Event(FollowEvent::Finalized(details)) => { + let finalized_block_refs: Vec<_> = details + .finalized_block_hashes + .into_iter() + .enumerate() + .map(|(idx, hash)| { + let rel_block_num = this.rel_block_num + idx + 1; + this.pin_unpinnable_block_at(rel_block_num, hash) + }) + .collect(); + this.rel_block_num += finalized_block_refs.len(); + let pruned_block_refs: Vec<_> = details + .pruned_block_hashes + .into_iter() + .map(|hash| { + let rel_block_num = this.rel_block_num + 1; + this.pin_unpinnable_block_at(rel_block_num, hash) + }) + .collect(); + this.unpin_blocks(cx.waker()); + FollowStreamMsg::Event( + FollowEvent::Finalized(Finalized { + finalized_block_hashes: finalized_block_refs, + pruned_block_hashes: pruned_block_refs, + }), + ) + } + FollowStreamMsg::Event(FollowEvent::Stop) => { + this.subscription_id = None; + this.pinned.clear(); + this.unpin_futs.clear(); + this.unpin_flags.lock().unwrap().clear(); + this.rel_block_num = 0; + FollowStreamMsg::Event(FollowEvent::Stop) + } + FollowStreamMsg::Event( + FollowEvent::OperationBodyDone(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationBodyDone(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationCallDone(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationCallDone(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationStorageItems(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationStorageItems(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationWaitingForContinue(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationWaitingForContinue(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationStorageDone(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationStorageDone(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationInaccessible(details), + ) => { + FollowStreamMsg::Event( + FollowEvent::OperationInaccessible(details), + ) + } + FollowStreamMsg::Event( + FollowEvent::OperationError(details), + ) => { + FollowStreamMsg::Event(FollowEvent::OperationError(details)) + } + }; + return Poll::Ready(Some(Ok(ev))); + } + } + } + impl FollowStreamUnpin { + /// Create a new [`FollowStreamUnpin`]. + pub fn new( + follow_stream: FollowStream, + unpin_method: UnpinMethod, + max_block_life: usize, + ) -> Self { + Self { + inner: follow_stream, + unpin_method: UnpinMethodHolder(unpin_method), + max_block_life, + pinned: Default::default(), + subscription_id: None, + rel_block_num: 0, + unpin_flags: Default::default(), + unpin_futs: Default::default(), + } + } + /// Create a new [`FollowStreamUnpin`] given the RPC methods. + pub fn from_methods( + follow_stream: FollowStream, + methods: UnstableRpcMethods, + max_block_life: usize, + ) -> FollowStreamUnpin { + let unpin_method = Box::new(move |hash: T::Hash, sub_id: Arc| { + let methods = methods.clone(); + let fut: UnpinFut = Box::pin(async move { + let _ = methods + .chainhead_unstable_unpin(&sub_id, hash) + .await; + }); + fut + }); + FollowStreamUnpin::new(follow_stream, unpin_method, max_block_life) + } + /// Is the block hash currently pinned. + pub fn is_pinned(&self, hash: &Hash) -> bool { + self.pinned.contains_key(hash) + } + /// Pin a block, or return the reference to an already-pinned block. If the block has been registered to + /// be unpinned, we'll clear those flags, so that it won't be unpinned. If the unpin request has already + /// been sent though, then the block will be unpinned. + fn pin_block_at( + &mut self, + rel_block_num: usize, + hash: Hash, + ) -> BlockRef { + self.pin_block_at_setting_unpinnable_flag(rel_block_num, hash, false) + } + /// Pin a block, or return the reference to an already-pinned block. + /// + /// This is the same as [`Self::pin_block_at`], except that it also marks the block as being unpinnable now, + /// which should be done for any block that will no longer be seen in future events. + fn pin_unpinnable_block_at( + &mut self, + rel_block_num: usize, + hash: Hash, + ) -> BlockRef { + self.pin_block_at_setting_unpinnable_flag(rel_block_num, hash, true) + } + fn pin_block_at_setting_unpinnable_flag( + &mut self, + rel_block_num: usize, + hash: Hash, + can_be_unpinned: bool, + ) -> BlockRef { + let entry = self + .pinned + .entry(hash) + .and_modify(|entry| { + entry + .can_be_unpinned = entry.can_be_unpinned || can_be_unpinned; + self.unpin_flags.lock().unwrap().remove(&hash); + }) + .or_insert_with(|| PinnedDetails { + rel_block_num, + block_ref: BlockRef { + inner: Arc::new(BlockRefInner { + hash, + unpin_flags: self.unpin_flags.clone(), + }), + }, + can_be_unpinned, + }); + entry.block_ref.clone() + } + /// Unpin any blocks that are either too old, or have the unpin flag set and are old enough. + fn unpin_blocks(&mut self, waker: &Waker) { + let mut unpin_flags = self.unpin_flags.lock().unwrap(); + let rel_block_num = self.rel_block_num; + let Some(sub_id) = &self.subscription_id else { return; + }; + let mut blocks_to_unpin = ::alloc::vec::Vec::new(); + for (hash, details) in &self.pinned { + if rel_block_num.saturating_sub(details.rel_block_num) + >= self.max_block_life + || (unpin_flags.contains(hash) && details.can_be_unpinned) + { + blocks_to_unpin.push(*hash); + unpin_flags.remove(hash); + } + } + drop(unpin_flags); + if blocks_to_unpin.is_empty() { + return; + } + for hash in blocks_to_unpin { + self.pinned.remove(&hash); + let fut = (self.unpin_method.0)(hash, sub_id.clone()); + self.unpin_futs.push(fut); + } + waker.wake_by_ref(); + } + } + type UnpinFlags = Arc>>; + struct PinnedDetails { + /// How old is the block? + rel_block_num: usize, + /// A block ref we can hand out to keep blocks pinned. + /// Because we store one here until it's unpinned, the live count + /// will only drop to 1 when no external refs are left. + block_ref: BlockRef, + /// Has this block showed up in the list of pruned blocks, or has it + /// been finalized? In this case, it can now been pinned as it won't + /// show up again in future events (except as a "parent block" of some + /// new block, which we're currently ignoring). + can_be_unpinned: bool, + } + #[automatically_derived] + impl ::core::fmt::Debug + for PinnedDetails { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "PinnedDetails", + "rel_block_num", + &self.rel_block_num, + "block_ref", + &self.block_ref, + "can_be_unpinned", + &&self.can_be_unpinned, + ) + } + } + /// All blocks reported will be wrapped in this. + pub struct BlockRef { + inner: Arc>, + } + #[automatically_derived] + impl ::core::fmt::Debug + for BlockRef { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "BlockRef", + "inner", + &&self.inner, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for BlockRef { + #[inline] + fn clone(&self) -> BlockRef { + BlockRef { + inner: ::core::clone::Clone::clone(&self.inner), + } + } + } + struct BlockRefInner { + hash: Hash, + unpin_flags: UnpinFlags, + } + #[automatically_derived] + impl ::core::fmt::Debug for BlockRefInner { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "BlockRefInner", + "hash", + &self.hash, + "unpin_flags", + &&self.unpin_flags, + ) + } + } + impl BlockRef { + /// Return the hash for this block. + pub fn hash(&self) -> Hash { + self.inner.hash + } + } + impl PartialEq for BlockRef { + fn eq(&self, other: &Self) -> bool { + self.inner.hash == other.inner.hash + } + } + impl PartialEq for BlockRef { + fn eq(&self, other: &Hash) -> bool { + &self.inner.hash == other + } + } + impl Drop for BlockRef { + fn drop(&mut self) { + if Arc::strong_count(&self.inner) == 2 { + if let Ok(mut unpin_flags) = self.inner.unpin_flags.lock() { + unpin_flags.insert(self.inner.hash); + } + } + } + } + } + mod storage_items { + use super::follow_stream_driver::FollowStreamDriverHandle; + use super::follow_stream_unpin::BlockRef; + use super::rpc_methods::{ + FollowEvent, MethodResponse, StorageQuery, StorageResult, + UnstableRpcMethods, + }; + use crate::config::Config; + use crate::error::{Error, RpcError}; + use futures::{FutureExt, Stream, StreamExt}; + use std::collections::VecDeque; + use std::future::Future; + use std::pin::Pin; + use std::sync::Arc; + use std::task::{Context, Poll}; + /// Obtain a stream of storage items given some query. this handles continuing + /// and stopping under the hood, and returns a stream of `StorageResult`s. + pub struct StorageItems { + done: bool, + operation_id: Arc, + buffered_responses: VecDeque, + continue_call: ContinueFutGetter, + continue_fut: Option, + follow_event_stream: FollowEventStream, + } + impl StorageItems { + pub async fn from_methods( + queries: impl Iterator>, + at: T::Hash, + follow_handle: &FollowStreamDriverHandle, + methods: UnstableRpcMethods, + ) -> Result { + let sub_id = super::get_subscription_id(follow_handle).await?; + let follow_events = follow_handle.subscribe().events(); + let status = methods + .chainhead_unstable_storage(&sub_id, at, queries, None) + .await?; + let operation_id: Arc = match status { + MethodResponse::LimitReached => { + return Err( + RpcError::request_rejected("limit reached").into(), + ); + } + MethodResponse::Started(s) => s.operation_id.into(), + }; + let continue_call: ContinueFutGetter = { + let operation_id = operation_id.clone(); + Box::new(move || { + let sub_id = sub_id.clone(); + let operation_id = operation_id.clone(); + let methods = methods.clone(); + Box::pin(async move { + methods + .chainhead_unstable_continue(&sub_id, &operation_id) + .await + }) + }) + }; + Ok( + StorageItems::new( + operation_id, + continue_call, + Box::pin(follow_events), + ), + ) + } + fn new( + operation_id: Arc, + continue_call: ContinueFutGetter, + follow_event_stream: FollowEventStream, + ) -> Self { + Self { + done: false, + buffered_responses: VecDeque::new(), + operation_id, + continue_call, + continue_fut: None, + follow_event_stream, + } + } + } + pub type FollowEventStream = Pin< + Box>> + Send + 'static>, + >; + pub type ContinueFutGetter = Box ContinueFut + Send + 'static>; + pub type ContinueFut = Pin< + Box> + Send + 'static>, + >; + impl Stream for StorageItems { + type Item = Result; + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + loop { + if self.done { + return Poll::Ready(None); + } + if let Some(item) = self.buffered_responses.pop_front() { + return Poll::Ready(Some(Ok(item))); + } + if let Some(mut fut) = self.continue_fut.take() { + match fut.poll_unpin(cx) { + Poll::Pending => { + self.continue_fut = Some(fut); + return Poll::Pending; + } + Poll::Ready(Err(e)) => { + self.done = true; + return Poll::Ready(Some(Err(e))); + } + Poll::Ready(Ok(())) => {} + } + } + let ev = match self.follow_event_stream.poll_next_unpin(cx) { + Poll::Pending => return Poll::Pending, + Poll::Ready(None) => return Poll::Ready(None), + Poll::Ready(Some(ev)) => ev, + }; + match ev { + FollowEvent::OperationWaitingForContinue( + id, + ) if id.operation_id == *self.operation_id => { + self.continue_fut = Some((self.continue_call)()); + continue; + } + FollowEvent::OperationStorageDone( + id, + ) if id.operation_id == *self.operation_id => { + self.done = true; + return Poll::Ready(None); + } + FollowEvent::OperationStorageItems( + items, + ) if items.operation_id == *self.operation_id => { + self.buffered_responses = items.items; + continue; + } + _ => { + continue; + } + } + } + } + } + } + pub mod rpc_methods { + //! An interface to call the API methods. See + //! for details of the API + //! methods exposed here. + use crate::backend::rpc::{rpc_params, RpcClient, RpcSubscription}; + use crate::config::BlockHash; + use crate::{Config, Error}; + use derivative::Derivative; + use futures::{Stream, StreamExt}; + use serde::{Deserialize, Serialize}; + use std::collections::{HashMap, VecDeque}; + use std::task::Poll; + /// An interface to call the unstable RPC methods. This interface is instantiated with + /// some `T: Config` trait which determines some of the types that the RPC methods will + /// take or hand back. + #[derivative(Clone(bound = ""), Debug(bound = ""))] + pub struct UnstableRpcMethods { + client: RpcClient, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for UnstableRpcMethods { + fn clone(&self) -> Self { + match *self { + UnstableRpcMethods { + client: ref __arg_0, + _marker: ref __arg_1, + } => { + UnstableRpcMethods { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for UnstableRpcMethods { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + UnstableRpcMethods { + client: ref __arg_0, + _marker: ref __arg_1, + } => { + let mut __debug_trait_builder = __f + .debug_struct("UnstableRpcMethods"); + let _ = __debug_trait_builder.field("client", &&(*__arg_0)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + impl UnstableRpcMethods { + /// Instantiate the legacy RPC method interface. + pub fn new(client: RpcClient) -> Self { + UnstableRpcMethods { + client, + _marker: std::marker::PhantomData, + } + } + /// Subscribe to `chainHead_unstable_follow` to obtain all reported blocks by the chain. + /// + /// The subscription ID can be used to make queries for the + /// block's body ([`chainhead_unstable_body`](UnstableRpcMethods::chainhead_unstable_follow)), + /// block's header ([`chainhead_unstable_header`](UnstableRpcMethods::chainhead_unstable_header)), + /// block's storage ([`chainhead_unstable_storage`](UnstableRpcMethods::chainhead_unstable_storage)) and submitting + /// runtime API calls at this block ([`chainhead_unstable_call`](UnstableRpcMethods::chainhead_unstable_call)). + /// + /// # Note + /// + /// When the user is no longer interested in a block, the user is responsible + /// for calling the [`chainhead_unstable_unpin`](UnstableRpcMethods::chainhead_unstable_unpin) method. + /// Failure to do so will result in the subscription being stopped by generating the `Stop` event. + pub async fn chainhead_unstable_follow( + &self, + with_runtime: bool, + ) -> Result, Error> { + let sub = self + .client + .subscribe( + "chainHead_unstable_follow", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(with_runtime) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + "chainHead_unstable_unfollow", + ) + .await?; + Ok(FollowSubscription { + sub, + done: false, + }) + } + /// Resumes a storage fetch started with chainHead_unstable_storage after it has generated an + /// `operationWaitingForContinue` event. + /// + /// Has no effect if the operationId is invalid or refers to an operation that has emitted a + /// `{"event": "operationInaccessible"` event, or if the followSubscription is invalid or stale. + pub async fn chainhead_unstable_continue( + &self, + follow_subscription: &str, + operation_id: &str, + ) -> Result<(), Error> { + self.client + .request( + "chainHead_unstable_continue", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(follow_subscription) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(operation_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(()) + } + /// Stops an operation started with `chainHead_unstable_body`, `chainHead_unstable_call`, or + /// `chainHead_unstable_storage¦. If the operation was still in progress, this interrupts it. + /// If the operation was already finished, this call has no effect. + /// + /// Has no effect if the `followSubscription` is invalid or stale. + pub async fn chainhead_unstable_stop_operation( + &self, + follow_subscription: &str, + operation_id: &str, + ) -> Result<(), Error> { + self.client + .request( + "chainHead_unstable_stopOperation", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(follow_subscription) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(operation_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(()) + } + /// Call the `chainHead_unstable_body` method and return an operation ID to obtain the block's body. + /// + /// The response events are provided on the `chainHead_follow` subscription and identified by + /// the returned operation ID. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_body( + &self, + subscription_id: &str, + hash: T::Hash, + ) -> Result { + let response = self + .client + .request( + "chainHead_unstable_body", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(response) + } + /// Get the block's header using the `chainHead_unstable_header` method. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_header( + &self, + subscription_id: &str, + hash: T::Hash, + ) -> Result, Error> { + let header: Option = self + .client + .request( + "chainHead_unstable_header", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + let header = header + .map(|h| codec::Decode::decode(&mut &*h.0)) + .transpose()?; + Ok(header) + } + /// Call the `chainhead_unstable_storage` method and return an operation ID to obtain the block's storage. + /// + /// The response events are provided on the `chainHead_follow` subscription and identified by + /// the returned operation ID. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_storage( + &self, + subscription_id: &str, + hash: T::Hash, + items: impl IntoIterator>, + child_key: Option<&[u8]>, + ) -> Result { + let items: Vec> = items + .into_iter() + .map(|item| StorageQuery { + key: to_hex(item.key), + query_type: item.query_type, + }) + .collect(); + let response = self + .client + .request( + "chainHead_unstable_storage", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(items) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(child_key.map(to_hex)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(response) + } + /// Call the `chainhead_unstable_storage` method and return an operation ID to obtain the runtime API result. + /// + /// The response events are provided on the `chainHead_follow` subscription and identified by + /// the returned operation ID. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_call( + &self, + subscription_id: &str, + hash: T::Hash, + function: &str, + call_parameters: &[u8], + ) -> Result { + let response = self + .client + .request( + "chainHead_unstable_call", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(function) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(to_hex(call_parameters)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(response) + } + /// Unpin a block reported by the `chainHead_follow` subscription. + /// + /// # Note + /// + /// The subscription ID is obtained from an open subscription created by + /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). + pub async fn chainhead_unstable_unpin( + &self, + subscription_id: &str, + hash: T::Hash, + ) -> Result<(), Error> { + self.client + .request( + "chainHead_unstable_unpin", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(subscription_id) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + .push(hash) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + ) + .await?; + Ok(()) + } + /// Return the genesis hash. + pub async fn chainspec_v1_genesis_hash(&self) -> Result { + let hash = self + .client + .request( + "chainSpec_v1_genesisHash", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await?; + Ok(hash) + } + /// Return a string containing the human-readable name of the chain. + pub async fn chainspec_v1_chain_name(&self) -> Result { + let hash = self + .client + .request( + "chainSpec_v1_chainName", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await?; + Ok(hash) + } + /// Returns the JSON payload found in the chain specification under the key properties. + /// No guarantee is offered about the content of this object, and so it's up to the caller + /// to decide what to deserialize it into. + pub async fn chainspec_v1_properties( + &self, + ) -> Result { + self.client + .request( + "chainSpec_v1_properties", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Returns an array of strings indicating the names of all the JSON-RPC functions supported by + /// the JSON-RPC server. + pub async fn rpc_methods(&self) -> Result, Error> { + self.client + .request( + "rpc_methods", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + }, + ) + .await + } + /// Attempt to submit a transaction, returning events about its progress. + pub async fn transaction_unstable_submit_and_watch( + &self, + tx: &[u8], + ) -> Result, Error> { + let sub = self + .client + .subscribe( + "transactionWatch_unstable_submitAndWatch", + { + #[allow(unused_mut)] + let mut params = crate::backend::rpc::RpcParams::new(); + params + .push(to_hex(tx)) + .expect( + "values passed to rpc_params! must be serializable to JSON", + ); + params + }, + "transactionWatch_unstable_unwatch", + ) + .await?; + Ok(TransactionSubscription { + sub, + done: false, + }) + } + } + /// This represents events generated by the `follow` method. + /// + /// The block events are generated in the following order: + /// 1. Initialized - generated only once to signal the latest finalized block + /// 2. NewBlock - a new block was added. + /// 3. BestBlockChanged - indicate that the best block is now the one from this event. The block was + /// announced priorly with the `NewBlock` event. + /// 4. Finalized - State the finalized and pruned blocks. + /// + /// The following events are related to operations: + /// - OperationBodyDone: The response of the `chainHead_body` + /// - OperationCallDone: The response of the `chainHead_call` + /// - OperationStorageItems: Items produced by the `chianHead_storage` + /// - OperationWaitingForContinue: Generated after OperationStorageItems and requires the user to + /// call `chainHead_continue` + /// - OperationStorageDone: The `chainHead_storage` method has produced all the results + /// - OperationInaccessible: The server was unable to provide the result, retries might succeed in + /// the future + /// - OperationError: The server encountered an error, retries will not succeed + /// + /// The stop event indicates that the JSON-RPC server was unable to provide a consistent list of + /// the blocks at the head of the chain. + #[serde(rename_all = "camelCase")] + #[serde(tag = "event")] + pub enum FollowEvent { + /// The latest finalized block. + /// + /// This event is generated only once. + Initialized(Initialized), + /// A new non-finalized block was added. + NewBlock(NewBlock), + /// The best block of the chain. + BestBlockChanged(BestBlockChanged), + /// A list of finalized and pruned blocks. + Finalized(Finalized), + /// The response of the `chainHead_body` method. + OperationBodyDone(OperationBodyDone), + /// The response of the `chainHead_call` method. + OperationCallDone(OperationCallDone), + /// Yield one or more items found in the storage. + OperationStorageItems(OperationStorageItems), + /// Ask the user to call `chainHead_continue` to produce more events + /// regarding the operation id. + OperationWaitingForContinue(OperationId), + /// The responses of the `chainHead_storage` method have been produced. + OperationStorageDone(OperationId), + /// The RPC server was unable to provide the response of the following operation id. + /// + /// Repeating the same operation in the future might succeed. + OperationInaccessible(OperationId), + /// The RPC server encountered an error while processing an operation id. + /// + /// Repeating the same operation in the future will not succeed. + OperationError(OperationError), + /// The subscription is dropped and no further events + /// will be generated. + Stop, + } + #[automatically_derived] + impl ::core::fmt::Debug for FollowEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + FollowEvent::Initialized(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Initialized", + &__self_0, + ) + } + FollowEvent::NewBlock(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "NewBlock", + &__self_0, + ) + } + FollowEvent::BestBlockChanged(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "BestBlockChanged", + &__self_0, + ) + } + FollowEvent::Finalized(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Finalized", + &__self_0, + ) + } + FollowEvent::OperationBodyDone(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationBodyDone", + &__self_0, + ) + } + FollowEvent::OperationCallDone(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationCallDone", + &__self_0, + ) + } + FollowEvent::OperationStorageItems(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationStorageItems", + &__self_0, + ) + } + FollowEvent::OperationWaitingForContinue(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationWaitingForContinue", + &__self_0, + ) + } + FollowEvent::OperationStorageDone(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationStorageDone", + &__self_0, + ) + } + FollowEvent::OperationInaccessible(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationInaccessible", + &__self_0, + ) + } + FollowEvent::OperationError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "OperationError", + &__self_0, + ) + } + FollowEvent::Stop => ::core::fmt::Formatter::write_str(f, "Stop"), + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for FollowEvent { + #[inline] + fn clone(&self) -> FollowEvent { + match self { + FollowEvent::Initialized(__self_0) => { + FollowEvent::Initialized( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::NewBlock(__self_0) => { + FollowEvent::NewBlock(::core::clone::Clone::clone(__self_0)) + } + FollowEvent::BestBlockChanged(__self_0) => { + FollowEvent::BestBlockChanged( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::Finalized(__self_0) => { + FollowEvent::Finalized(::core::clone::Clone::clone(__self_0)) + } + FollowEvent::OperationBodyDone(__self_0) => { + FollowEvent::OperationBodyDone( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationCallDone(__self_0) => { + FollowEvent::OperationCallDone( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationStorageItems(__self_0) => { + FollowEvent::OperationStorageItems( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationWaitingForContinue(__self_0) => { + FollowEvent::OperationWaitingForContinue( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationStorageDone(__self_0) => { + FollowEvent::OperationStorageDone( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationInaccessible(__self_0) => { + FollowEvent::OperationInaccessible( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::OperationError(__self_0) => { + FollowEvent::OperationError( + ::core::clone::Clone::clone(__self_0), + ) + } + FollowEvent::Stop => FollowEvent::Stop, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for FollowEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for FollowEvent { + #[inline] + fn eq(&self, other: &FollowEvent) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + FollowEvent::Initialized(__self_0), + FollowEvent::Initialized(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::NewBlock(__self_0), + FollowEvent::NewBlock(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::BestBlockChanged(__self_0), + FollowEvent::BestBlockChanged(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::Finalized(__self_0), + FollowEvent::Finalized(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationBodyDone(__self_0), + FollowEvent::OperationBodyDone(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationCallDone(__self_0), + FollowEvent::OperationCallDone(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationStorageItems(__self_0), + FollowEvent::OperationStorageItems(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationWaitingForContinue(__self_0), + FollowEvent::OperationWaitingForContinue(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationStorageDone(__self_0), + FollowEvent::OperationStorageDone(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationInaccessible(__self_0), + FollowEvent::OperationInaccessible(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + FollowEvent::OperationError(__self_0), + FollowEvent::OperationError(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for FollowEvent { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for FollowEvent + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __field6, + __field7, + __field8, + __field9, + __field10, + __field11, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + 5u64 => _serde::__private::Ok(__Field::__field5), + 6u64 => _serde::__private::Ok(__Field::__field6), + 7u64 => _serde::__private::Ok(__Field::__field7), + 8u64 => _serde::__private::Ok(__Field::__field8), + 9u64 => _serde::__private::Ok(__Field::__field9), + 10u64 => _serde::__private::Ok(__Field::__field10), + 11u64 => _serde::__private::Ok(__Field::__field11), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 12", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "initialized" => _serde::__private::Ok(__Field::__field0), + "newBlock" => _serde::__private::Ok(__Field::__field1), + "bestBlockChanged" => { + _serde::__private::Ok(__Field::__field2) + } + "finalized" => _serde::__private::Ok(__Field::__field3), + "operationBodyDone" => { + _serde::__private::Ok(__Field::__field4) + } + "operationCallDone" => { + _serde::__private::Ok(__Field::__field5) + } + "operationStorageItems" => { + _serde::__private::Ok(__Field::__field6) + } + "operationWaitingForContinue" => { + _serde::__private::Ok(__Field::__field7) + } + "operationStorageDone" => { + _serde::__private::Ok(__Field::__field8) + } + "operationInaccessible" => { + _serde::__private::Ok(__Field::__field9) + } + "operationError" => { + _serde::__private::Ok(__Field::__field10) + } + "stop" => _serde::__private::Ok(__Field::__field11), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"initialized" => _serde::__private::Ok(__Field::__field0), + b"newBlock" => _serde::__private::Ok(__Field::__field1), + b"bestBlockChanged" => { + _serde::__private::Ok(__Field::__field2) + } + b"finalized" => _serde::__private::Ok(__Field::__field3), + b"operationBodyDone" => { + _serde::__private::Ok(__Field::__field4) + } + b"operationCallDone" => { + _serde::__private::Ok(__Field::__field5) + } + b"operationStorageItems" => { + _serde::__private::Ok(__Field::__field6) + } + b"operationWaitingForContinue" => { + _serde::__private::Ok(__Field::__field7) + } + b"operationStorageDone" => { + _serde::__private::Ok(__Field::__field8) + } + b"operationInaccessible" => { + _serde::__private::Ok(__Field::__field9) + } + b"operationError" => { + _serde::__private::Ok(__Field::__field10) + } + b"stop" => _serde::__private::Ok(__Field::__field11), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "initialized", + "newBlock", + "bestBlockChanged", + "finalized", + "operationBodyDone", + "operationCallDone", + "operationStorageItems", + "operationWaitingForContinue", + "operationStorageDone", + "operationInaccessible", + "operationError", + "stop", + ]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::< + __Field, + >::new("event", "internally tagged enum FollowEvent"), + )?; + let __deserializer = _serde::__private::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::__private::Result::map( + as _serde::Deserialize>::deserialize(__deserializer), + FollowEvent::Initialized, + ) + } + __Field::__field1 => { + _serde::__private::Result::map( + as _serde::Deserialize>::deserialize(__deserializer), + FollowEvent::NewBlock, + ) + } + __Field::__field2 => { + _serde::__private::Result::map( + as _serde::Deserialize>::deserialize(__deserializer), + FollowEvent::BestBlockChanged, + ) + } + __Field::__field3 => { + _serde::__private::Result::map( + as _serde::Deserialize>::deserialize(__deserializer), + FollowEvent::Finalized, + ) + } + __Field::__field4 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationBodyDone, + ) + } + __Field::__field5 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationCallDone, + ) + } + __Field::__field6 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationStorageItems, + ) + } + __Field::__field7 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationWaitingForContinue, + ) + } + __Field::__field8 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationStorageDone, + ) + } + __Field::__field9 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationInaccessible, + ) + } + __Field::__field10 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + FollowEvent::OperationError, + ) + } + __Field::__field11 => { + _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::InternallyTaggedUnitVisitor::new( + "FollowEvent", + "Stop", + ), + )?; + _serde::__private::Ok(FollowEvent::Stop) + } + } + } + } + }; + /// Contain information about the latest finalized block. + /// + /// # Note + /// + /// This is the first event generated by the `follow` subscription + /// and is submitted only once. + #[serde(rename_all = "camelCase")] + pub struct Initialized { + /// The hash of the latest finalized block. + pub finalized_block_hash: Hash, + /// The runtime version of the finalized block. + /// + /// # Note + /// + /// This is present only if the `with_runtime` flag is set for + /// the `follow` subscription. + pub finalized_block_runtime: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug for Initialized { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Initialized", + "finalized_block_hash", + &self.finalized_block_hash, + "finalized_block_runtime", + &&self.finalized_block_runtime, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for Initialized { + #[inline] + fn clone(&self) -> Initialized { + Initialized { + finalized_block_hash: ::core::clone::Clone::clone( + &self.finalized_block_hash, + ), + finalized_block_runtime: ::core::clone::Clone::clone( + &self.finalized_block_runtime, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Initialized {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for Initialized { + #[inline] + fn eq(&self, other: &Initialized) -> bool { + self.finalized_block_hash == other.finalized_block_hash + && self.finalized_block_runtime == other.finalized_block_runtime + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Initialized { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for Initialized + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "finalizedBlockHash" => { + _serde::__private::Ok(__Field::__field0) + } + "finalizedBlockRuntime" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"finalizedBlockHash" => { + _serde::__private::Ok(__Field::__field0) + } + b"finalizedBlockRuntime" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = Initialized; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct Initialized", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Initialized with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Initialized with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(Initialized { + finalized_block_hash: __field0, + finalized_block_runtime: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + Option, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "finalizedBlockHash", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "finalizedBlockRuntime", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("finalizedBlockHash")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field( + "finalizedBlockRuntime", + )? + } + }; + _serde::__private::Ok(Initialized { + finalized_block_hash: __field0, + finalized_block_runtime: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "finalizedBlockHash", + "finalizedBlockRuntime", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Initialized", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The runtime event generated if the `follow` subscription + /// has set the `with_runtime` flag. + #[serde(rename_all = "camelCase")] + #[serde(tag = "type")] + pub enum RuntimeEvent { + /// The runtime version of this block. + Valid(RuntimeVersionEvent), + /// The runtime could not be obtained due to an error. + Invalid(ErrorEvent), + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + RuntimeEvent::Valid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Valid", + &__self_0, + ) + } + RuntimeEvent::Invalid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Invalid", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeEvent { + #[inline] + fn clone(&self) -> RuntimeEvent { + match self { + RuntimeEvent::Valid(__self_0) => { + RuntimeEvent::Valid(::core::clone::Clone::clone(__self_0)) + } + RuntimeEvent::Invalid(__self_0) => { + RuntimeEvent::Invalid(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeEvent { + #[inline] + fn eq(&self, other: &RuntimeEvent) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + RuntimeEvent::Valid(__self_0), + RuntimeEvent::Valid(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + RuntimeEvent::Invalid(__self_0), + RuntimeEvent::Invalid(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeEvent { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RuntimeEvent { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "valid" => _serde::__private::Ok(__Field::__field0), + "invalid" => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"valid" => _serde::__private::Ok(__Field::__field0), + b"invalid" => _serde::__private::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &["valid", "invalid"]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::< + __Field, + >::new("type", "internally tagged enum RuntimeEvent"), + )?; + let __deserializer = _serde::__private::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + RuntimeEvent::Valid, + ) + } + __Field::__field1 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + RuntimeEvent::Invalid, + ) + } + } + } + } + }; + /// The runtime specification of the current block. + /// + /// This event is generated for: + /// - the first announced block by the follow subscription + /// - blocks that suffered a change in runtime compared with their parents + #[serde(rename_all = "camelCase")] + pub struct RuntimeVersionEvent { + /// Details about this runtime. + pub spec: RuntimeSpec, + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeVersionEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "RuntimeVersionEvent", + "spec", + &&self.spec, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeVersionEvent { + #[inline] + fn clone(&self) -> RuntimeVersionEvent { + RuntimeVersionEvent { + spec: ::core::clone::Clone::clone(&self.spec), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeVersionEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeVersionEvent { + #[inline] + fn eq(&self, other: &RuntimeVersionEvent) -> bool { + self.spec == other.spec + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeVersionEvent { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RuntimeVersionEvent { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "spec" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"spec" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = RuntimeVersionEvent; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct RuntimeVersionEvent", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + RuntimeSpec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct RuntimeVersionEvent with 1 element", + ), + ); + } + }; + _serde::__private::Ok(RuntimeVersionEvent { + spec: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("spec"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + RuntimeSpec, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("spec")? + } + }; + _serde::__private::Ok(RuntimeVersionEvent { + spec: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["spec"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "RuntimeVersionEvent", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + RuntimeVersionEvent, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// This contains the runtime version information necessary to make transactions, and is obtained from + /// the "initialized" event of `chainHead_follow` if the `withRuntime` flag is set. + #[serde(rename_all = "camelCase")] + pub struct RuntimeSpec { + /// Opaque string indicating the name of the chain. + pub spec_name: String, + /// Opaque string indicating the name of the implementation of the chain. + pub impl_name: String, + /// Opaque integer. The JSON-RPC client can assume that the Runtime API call to `Metadata_metadata` + /// will always produce the same output as long as the specVersion is the same. + pub spec_version: u32, + /// Opaque integer. Whenever the runtime code changes in a backwards-compatible way, the implVersion + /// is modified while the specVersion is left untouched. + pub impl_version: u32, + /// Opaque integer. Necessary when building the bytes of a transaction. Transactions that have been + /// generated with a different `transaction_version` are incompatible. + pub transaction_version: u32, + /// Object containing a list of "entry point APIs" supported by the runtime. Each key is an opaque string + /// indicating the API, and each value is an integer version number. Before making a runtime call (using + /// chainHead_call), you should make sure that this list contains the entry point API corresponding to the + /// call and with a known version number. + /// + /// **Note:** In Substrate, the keys in the apis field consists of the hexadecimal-encoded 8-bytes blake2 + /// hash of the name of the API. For example, the `TaggedTransactionQueue` API is 0xd2bc9897eed08f15. + #[serde(with = "hashmap_as_tuple_list")] + pub apis: HashMap, + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeSpec { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "spec_name", + "impl_name", + "spec_version", + "impl_version", + "transaction_version", + "apis", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.spec_name, + &self.impl_name, + &self.spec_version, + &self.impl_version, + &self.transaction_version, + &&self.apis, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "RuntimeSpec", + names, + values, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeSpec { + #[inline] + fn clone(&self) -> RuntimeSpec { + RuntimeSpec { + spec_name: ::core::clone::Clone::clone(&self.spec_name), + impl_name: ::core::clone::Clone::clone(&self.impl_name), + spec_version: ::core::clone::Clone::clone(&self.spec_version), + impl_version: ::core::clone::Clone::clone(&self.impl_version), + transaction_version: ::core::clone::Clone::clone( + &self.transaction_version, + ), + apis: ::core::clone::Clone::clone(&self.apis), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeSpec {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeSpec { + #[inline] + fn eq(&self, other: &RuntimeSpec) -> bool { + self.spec_name == other.spec_name + && self.impl_name == other.impl_name + && self.spec_version == other.spec_version + && self.impl_version == other.impl_version + && self.transaction_version == other.transaction_version + && self.apis == other.apis + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeSpec { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for RuntimeSpec { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + 5u64 => _serde::__private::Ok(__Field::__field5), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "specName" => _serde::__private::Ok(__Field::__field0), + "implName" => _serde::__private::Ok(__Field::__field1), + "specVersion" => _serde::__private::Ok(__Field::__field2), + "implVersion" => _serde::__private::Ok(__Field::__field3), + "transactionVersion" => { + _serde::__private::Ok(__Field::__field4) + } + "apis" => _serde::__private::Ok(__Field::__field5), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"specName" => _serde::__private::Ok(__Field::__field0), + b"implName" => _serde::__private::Ok(__Field::__field1), + b"specVersion" => _serde::__private::Ok(__Field::__field2), + b"implVersion" => _serde::__private::Ok(__Field::__field3), + b"transactionVersion" => { + _serde::__private::Ok(__Field::__field4) + } + b"apis" => _serde::__private::Ok(__Field::__field5), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = RuntimeSpec; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct RuntimeSpec", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + let __field5 = match { + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: HashMap, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: hashmap_as_tuple_list::deserialize(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 5usize, + &"struct RuntimeSpec with 6 elements", + ), + ); + } + }; + _serde::__private::Ok(RuntimeSpec { + spec_name: __field0, + impl_name: __field1, + spec_version: __field2, + impl_version: __field3, + transaction_version: __field4, + apis: __field5, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option = _serde::__private::None; + let mut __field3: _serde::__private::Option = _serde::__private::None; + let mut __field4: _serde::__private::Option = _serde::__private::None; + let mut __field5: _serde::__private::Option< + HashMap, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "specName", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "implName", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "specVersion", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private::Option::is_some(&__field3) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "implVersion", + ), + ); + } + __field3 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private::Option::is_some(&__field4) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "transactionVersion", + ), + ); + } + __field4 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field5 => { + if _serde::__private::Option::is_some(&__field5) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("apis"), + ); + } + __field5 = _serde::__private::Some({ + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: HashMap, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: hashmap_as_tuple_list::deserialize(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + match _serde::de::MapAccess::next_value::< + __DeserializeWith<'de>, + >(&mut __map) { + _serde::__private::Ok(__wrapper) => __wrapper.value, + _serde::__private::Err(__err) => { + return _serde::__private::Err(__err); + } + } + }); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("specName")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("implName")? + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("specVersion")? + } + }; + let __field3 = match __field3 { + _serde::__private::Some(__field3) => __field3, + _serde::__private::None => { + _serde::__private::de::missing_field("implVersion")? + } + }; + let __field4 = match __field4 { + _serde::__private::Some(__field4) => __field4, + _serde::__private::None => { + _serde::__private::de::missing_field("transactionVersion")? + } + }; + let __field5 = match __field5 { + _serde::__private::Some(__field5) => __field5, + _serde::__private::None => { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::missing_field("apis"), + ); + } + }; + _serde::__private::Ok(RuntimeSpec { + spec_name: __field0, + impl_name: __field1, + spec_version: __field2, + impl_version: __field3, + transaction_version: __field4, + apis: __field5, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "specName", + "implName", + "specVersion", + "implVersion", + "transactionVersion", + "apis", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "RuntimeSpec", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The operation could not be processed due to an error. + #[serde(rename_all = "camelCase")] + pub struct ErrorEvent { + /// Reason of the error. + pub error: String, + } + #[automatically_derived] + impl ::core::fmt::Debug for ErrorEvent { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "ErrorEvent", + "error", + &&self.error, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for ErrorEvent { + #[inline] + fn clone(&self) -> ErrorEvent { + ErrorEvent { + error: ::core::clone::Clone::clone(&self.error), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ErrorEvent {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ErrorEvent { + #[inline] + fn eq(&self, other: &ErrorEvent) -> bool { + self.error == other.error + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ErrorEvent { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for ErrorEvent { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = ErrorEvent; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct ErrorEvent", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct ErrorEvent with 1 element", + ), + ); + } + }; + _serde::__private::Ok(ErrorEvent { error: __field0 }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(ErrorEvent { error: __field0 }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["error"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "ErrorEvent", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate a new non-finalized block. + #[serde(rename_all = "camelCase")] + pub struct NewBlock { + /// The hash of the new block. + pub block_hash: Hash, + /// The parent hash of the new block. + pub parent_block_hash: Hash, + /// The runtime version of the new block. + /// + /// # Note + /// + /// This is present only if the `with_runtime` flag is set for + /// the `follow` subscription. + pub new_runtime: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug for NewBlock { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "NewBlock", + "block_hash", + &self.block_hash, + "parent_block_hash", + &self.parent_block_hash, + "new_runtime", + &&self.new_runtime, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for NewBlock { + #[inline] + fn clone(&self) -> NewBlock { + NewBlock { + block_hash: ::core::clone::Clone::clone(&self.block_hash), + parent_block_hash: ::core::clone::Clone::clone( + &self.parent_block_hash, + ), + new_runtime: ::core::clone::Clone::clone(&self.new_runtime), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for NewBlock {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for NewBlock { + #[inline] + fn eq(&self, other: &NewBlock) -> bool { + self.block_hash == other.block_hash + && self.parent_block_hash == other.parent_block_hash + && self.new_runtime == other.new_runtime + } + } + #[automatically_derived] + impl ::core::cmp::Eq for NewBlock { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for NewBlock + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "blockHash" => _serde::__private::Ok(__Field::__field0), + "parentBlockHash" => { + _serde::__private::Ok(__Field::__field1) + } + "newRuntime" => _serde::__private::Ok(__Field::__field2), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"blockHash" => _serde::__private::Ok(__Field::__field0), + b"parentBlockHash" => { + _serde::__private::Ok(__Field::__field1) + } + b"newRuntime" => _serde::__private::Ok(__Field::__field2), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = NewBlock; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct NewBlock", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct NewBlock with 3 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct NewBlock with 3 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct NewBlock with 3 elements", + ), + ); + } + }; + _serde::__private::Ok(NewBlock { + block_hash: __field0, + parent_block_hash: __field1, + new_runtime: __field2, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option< + Option, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "blockHash", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "parentBlockHash", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "newRuntime", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("blockHash")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("parentBlockHash")? + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("newRuntime")? + } + }; + _serde::__private::Ok(NewBlock { + block_hash: __field0, + parent_block_hash: __field1, + new_runtime: __field2, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "blockHash", + "parentBlockHash", + "newRuntime", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "NewBlock", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate the block hash of the new best block. + #[serde(rename_all = "camelCase")] + pub struct BestBlockChanged { + /// The block hash of the new best block. + pub best_block_hash: Hash, + } + #[automatically_derived] + impl ::core::fmt::Debug + for BestBlockChanged { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "BestBlockChanged", + "best_block_hash", + &&self.best_block_hash, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for BestBlockChanged { + #[inline] + fn clone(&self) -> BestBlockChanged { + BestBlockChanged { + best_block_hash: ::core::clone::Clone::clone( + &self.best_block_hash, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BestBlockChanged {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for BestBlockChanged { + #[inline] + fn eq(&self, other: &BestBlockChanged) -> bool { + self.best_block_hash == other.best_block_hash + } + } + #[automatically_derived] + impl ::core::cmp::Eq for BestBlockChanged { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for BestBlockChanged + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "bestBlockHash" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"bestBlockHash" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + BestBlockChanged, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = BestBlockChanged; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct BestBlockChanged", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct BestBlockChanged with 1 element", + ), + ); + } + }; + _serde::__private::Ok(BestBlockChanged { + best_block_hash: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "bestBlockHash", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("bestBlockHash")? + } + }; + _serde::__private::Ok(BestBlockChanged { + best_block_hash: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["bestBlockHash"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "BestBlockChanged", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + BestBlockChanged, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate the finalized and pruned block hashes. + #[serde(rename_all = "camelCase")] + pub struct Finalized { + /// Block hashes that are finalized. + pub finalized_block_hashes: Vec, + /// Block hashes that are pruned (removed). + pub pruned_block_hashes: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for Finalized { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Finalized", + "finalized_block_hashes", + &self.finalized_block_hashes, + "pruned_block_hashes", + &&self.pruned_block_hashes, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for Finalized { + #[inline] + fn clone(&self) -> Finalized { + Finalized { + finalized_block_hashes: ::core::clone::Clone::clone( + &self.finalized_block_hashes, + ), + pruned_block_hashes: ::core::clone::Clone::clone( + &self.pruned_block_hashes, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Finalized {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for Finalized { + #[inline] + fn eq(&self, other: &Finalized) -> bool { + self.finalized_block_hashes == other.finalized_block_hashes + && self.pruned_block_hashes == other.pruned_block_hashes + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Finalized { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for Finalized + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "finalizedBlockHashes" => { + _serde::__private::Ok(__Field::__field0) + } + "prunedBlockHashes" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"finalizedBlockHashes" => { + _serde::__private::Ok(__Field::__field0) + } + b"prunedBlockHashes" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = Finalized; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct Finalized", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Finalized with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct Finalized with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(Finalized { + finalized_block_hashes: __field0, + pruned_block_hashes: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option> = _serde::__private::None; + let mut __field1: _serde::__private::Option> = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "finalizedBlockHashes", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "prunedBlockHashes", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field( + "finalizedBlockHashes", + )? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("prunedBlockHashes")? + } + }; + _serde::__private::Ok(Finalized { + finalized_block_hashes: __field0, + pruned_block_hashes: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "finalizedBlockHashes", + "prunedBlockHashes", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Finalized", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate the operation id of the event. + #[serde(rename_all = "camelCase")] + pub struct OperationId { + /// The operation id of the event. + pub operation_id: String, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationId { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "OperationId", + "operation_id", + &&self.operation_id, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationId { + #[inline] + fn clone(&self) -> OperationId { + OperationId { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationId {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationId { + #[inline] + fn eq(&self, other: &OperationId) -> bool { + self.operation_id == other.operation_id + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationId { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationId { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationId; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationId", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationId with 1 element", + ), + ); + } + }; + _serde::__private::Ok(OperationId { + operation_id: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + _serde::__private::Ok(OperationId { + operation_id: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["operationId"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationId", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The response of the `chainHead_body` method. + #[serde(rename_all = "camelCase")] + pub struct OperationBodyDone { + /// The operation id of the event. + pub operation_id: String, + /// Array of hexadecimal-encoded scale-encoded extrinsics found in the block. + pub value: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationBodyDone { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "OperationBodyDone", + "operation_id", + &self.operation_id, + "value", + &&self.value, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationBodyDone { + #[inline] + fn clone(&self) -> OperationBodyDone { + OperationBodyDone { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + value: ::core::clone::Clone::clone(&self.value), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationBodyDone {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationBodyDone { + #[inline] + fn eq(&self, other: &OperationBodyDone) -> bool { + self.operation_id == other.operation_id && self.value == other.value + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationBodyDone { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationBodyDone { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "value" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"value" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationBodyDone; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationBodyDone", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationBodyDone with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct OperationBodyDone with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(OperationBodyDone { + operation_id: __field0, + value: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option> = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("value"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::>(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("value")? + } + }; + _serde::__private::Ok(OperationBodyDone { + operation_id: __field0, + value: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "value", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationBodyDone", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The response of the `chainHead_call` method. + #[serde(rename_all = "camelCase")] + pub struct OperationCallDone { + /// The operation id of the event. + pub operation_id: String, + /// Hexadecimal-encoded output of the runtime function call. + pub output: Bytes, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationCallDone { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "OperationCallDone", + "operation_id", + &self.operation_id, + "output", + &&self.output, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationCallDone { + #[inline] + fn clone(&self) -> OperationCallDone { + OperationCallDone { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + output: ::core::clone::Clone::clone(&self.output), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationCallDone {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationCallDone { + #[inline] + fn eq(&self, other: &OperationCallDone) -> bool { + self.operation_id == other.operation_id + && self.output == other.output + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationCallDone { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationCallDone { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "output" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"output" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationCallDone; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationCallDone", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationCallDone with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Bytes, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct OperationCallDone with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(OperationCallDone { + operation_id: __field0, + output: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("output"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("output")? + } + }; + _serde::__private::Ok(OperationCallDone { + operation_id: __field0, + output: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "output", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationCallDone", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The response of the `chainHead_call` method. + #[serde(rename_all = "camelCase")] + pub struct OperationStorageItems { + /// The operation id of the event. + pub operation_id: String, + /// The resulting items. + pub items: VecDeque, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationStorageItems { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "OperationStorageItems", + "operation_id", + &self.operation_id, + "items", + &&self.items, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationStorageItems { + #[inline] + fn clone(&self) -> OperationStorageItems { + OperationStorageItems { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + items: ::core::clone::Clone::clone(&self.items), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationStorageItems {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationStorageItems { + #[inline] + fn eq(&self, other: &OperationStorageItems) -> bool { + self.operation_id == other.operation_id && self.items == other.items + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationStorageItems { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationStorageItems { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "items" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"items" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData< + OperationStorageItems, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationStorageItems; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationStorageItems", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationStorageItems with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + VecDeque, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct OperationStorageItems with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(OperationStorageItems { + operation_id: __field0, + items: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + VecDeque, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("items"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + VecDeque, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("items")? + } + }; + _serde::__private::Ok(OperationStorageItems { + operation_id: __field0, + items: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "items", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationStorageItems", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + OperationStorageItems, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Indicate a problem during the operation. + #[serde(rename_all = "camelCase")] + pub struct OperationError { + /// The operation id of the event. + pub operation_id: String, + /// The reason of the error. + pub error: String, + } + #[automatically_derived] + impl ::core::fmt::Debug for OperationError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "OperationError", + "operation_id", + &self.operation_id, + "error", + &&self.error, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for OperationError { + #[inline] + fn clone(&self) -> OperationError { + OperationError { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + error: ::core::clone::Clone::clone(&self.error), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for OperationError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for OperationError { + #[inline] + fn eq(&self, other: &OperationError) -> bool { + self.operation_id == other.operation_id && self.error == other.error + } + } + #[automatically_derived] + impl ::core::cmp::Eq for OperationError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for OperationError { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "error" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"error" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = OperationError; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct OperationError", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct OperationError with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct OperationError with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(OperationError { + operation_id: __field0, + error: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(OperationError { + operation_id: __field0, + error: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "error", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "OperationError", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The storage result. + #[serde(rename_all = "camelCase")] + pub struct StorageResult { + /// The hex-encoded key of the result. + pub key: Bytes, + /// The result of the query. + #[serde(flatten)] + pub result: StorageResultType, + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "StorageResult", + "key", + &self.key, + "result", + &&self.result, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageResult { + #[inline] + fn clone(&self) -> StorageResult { + StorageResult { + key: ::core::clone::Clone::clone(&self.key), + result: ::core::clone::Clone::clone(&self.result), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageResult {} + #[automatically_derived] + impl ::core::cmp::PartialEq for StorageResult { + #[inline] + fn eq(&self, other: &StorageResult) -> bool { + self.key == other.key && self.result == other.result + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageResult { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for StorageResult { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field<'de> { + __field0, + __other(_serde::__private::de::Content<'de>), + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field<'de>; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_bool<__E>( + self, + __value: bool, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::Bool(__value), + ), + ) + } + fn visit_i8<__E>( + self, + __value: i8, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I8(__value), + ), + ) + } + fn visit_i16<__E>( + self, + __value: i16, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I16(__value), + ), + ) + } + fn visit_i32<__E>( + self, + __value: i32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I32(__value), + ), + ) + } + fn visit_i64<__E>( + self, + __value: i64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::I64(__value), + ), + ) + } + fn visit_u8<__E>( + self, + __value: u8, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U8(__value), + ), + ) + } + fn visit_u16<__E>( + self, + __value: u16, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U16(__value), + ), + ) + } + fn visit_u32<__E>( + self, + __value: u32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U32(__value), + ), + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::U64(__value), + ), + ) + } + fn visit_f32<__E>( + self, + __value: f32, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::F32(__value), + ), + ) + } + fn visit_f64<__E>( + self, + __value: f64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::F64(__value), + ), + ) + } + fn visit_char<__E>( + self, + __value: char, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other( + _serde::__private::de::Content::Char(__value), + ), + ) + } + fn visit_unit<__E>( + self, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok( + __Field::__other(_serde::__private::de::Content::Unit), + ) + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "key" => _serde::__private::Ok(__Field::__field0), + _ => { + let __value = _serde::__private::de::Content::String( + _serde::__private::ToString::to_string(__value), + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"key" => _serde::__private::Ok(__Field::__field0), + _ => { + let __value = _serde::__private::de::Content::ByteBuf( + __value.to_vec(), + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_borrowed_str<__E>( + self, + __value: &'de str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "key" => _serde::__private::Ok(__Field::__field0), + _ => { + let __value = _serde::__private::de::Content::Str(__value); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + fn visit_borrowed_bytes<__E>( + self, + __value: &'de [u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"key" => _serde::__private::Ok(__Field::__field0), + _ => { + let __value = _serde::__private::de::Content::Bytes( + __value, + ); + _serde::__private::Ok(__Field::__other(__value)) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field<'de> { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = StorageResult; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct StorageResult", + ) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __collect = _serde::__private::Vec::< + _serde::__private::Option< + ( + _serde::__private::de::Content, + _serde::__private::de::Content, + ), + >, + >::new(); + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("key"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__other(__name) => { + __collect + .push( + _serde::__private::Some(( + __name, + _serde::de::MapAccess::next_value(&mut __map)?, + )), + ); + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("key")? + } + }; + let __field1: StorageResultType = _serde::de::Deserialize::deserialize( + _serde::__private::de::FlatMapDeserializer( + &mut __collect, + _serde::__private::PhantomData, + ), + )?; + _serde::__private::Ok(StorageResult { + key: __field0, + result: __field1, + }) + } + } + _serde::Deserializer::deserialize_map( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The type of the storage query. + #[serde(rename_all = "camelCase")] + pub enum StorageResultType { + /// Fetch the value of the provided key. + Value(Bytes), + /// Fetch the hash of the value of the provided key. + Hash(Bytes), + /// Fetch the closest descendant merkle value. + ClosestDescendantMerkleValue(Bytes), + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageResultType { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + StorageResultType::Value(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Value", + &__self_0, + ) + } + StorageResultType::Hash(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Hash", + &__self_0, + ) + } + StorageResultType::ClosestDescendantMerkleValue(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ClosestDescendantMerkleValue", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageResultType { + #[inline] + fn clone(&self) -> StorageResultType { + match self { + StorageResultType::Value(__self_0) => { + StorageResultType::Value( + ::core::clone::Clone::clone(__self_0), + ) + } + StorageResultType::Hash(__self_0) => { + StorageResultType::Hash( + ::core::clone::Clone::clone(__self_0), + ) + } + StorageResultType::ClosestDescendantMerkleValue(__self_0) => { + StorageResultType::ClosestDescendantMerkleValue( + ::core::clone::Clone::clone(__self_0), + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageResultType {} + #[automatically_derived] + impl ::core::cmp::PartialEq for StorageResultType { + #[inline] + fn eq(&self, other: &StorageResultType) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + StorageResultType::Value(__self_0), + StorageResultType::Value(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + StorageResultType::Hash(__self_0), + StorageResultType::Hash(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + StorageResultType::ClosestDescendantMerkleValue(__self_0), + StorageResultType::ClosestDescendantMerkleValue(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageResultType { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for StorageResultType { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 3", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "value" => _serde::__private::Ok(__Field::__field0), + "hash" => _serde::__private::Ok(__Field::__field1), + "closestDescendantMerkleValue" => { + _serde::__private::Ok(__Field::__field2) + } + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"value" => _serde::__private::Ok(__Field::__field0), + b"hash" => _serde::__private::Ok(__Field::__field1), + b"closestDescendantMerkleValue" => { + _serde::__private::Ok(__Field::__field2) + } + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = StorageResultType; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "enum StorageResultType", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Bytes, + >(__variant), + StorageResultType::Value, + ) + } + (__Field::__field1, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Bytes, + >(__variant), + StorageResultType::Hash, + ) + } + (__Field::__field2, __variant) => { + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::< + Bytes, + >(__variant), + StorageResultType::ClosestDescendantMerkleValue, + ) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "value", + "hash", + "closestDescendantMerkleValue", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "StorageResultType", + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The method response of `chainHead_body`, `chainHead_call` and `chainHead_storage`. + #[serde(rename_all = "camelCase")] + #[serde(tag = "result")] + pub enum MethodResponse { + /// The method has started. + Started(MethodResponseStarted), + /// The RPC server cannot handle the request at the moment. + LimitReached, + } + #[automatically_derived] + impl ::core::fmt::Debug for MethodResponse { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + MethodResponse::Started(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Started", + &__self_0, + ) + } + MethodResponse::LimitReached => { + ::core::fmt::Formatter::write_str(f, "LimitReached") + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for MethodResponse { + #[inline] + fn clone(&self) -> MethodResponse { + match self { + MethodResponse::Started(__self_0) => { + MethodResponse::Started( + ::core::clone::Clone::clone(__self_0), + ) + } + MethodResponse::LimitReached => MethodResponse::LimitReached, + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for MethodResponse {} + #[automatically_derived] + impl ::core::cmp::PartialEq for MethodResponse { + #[inline] + fn eq(&self, other: &MethodResponse) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + MethodResponse::Started(__self_0), + MethodResponse::Started(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for MethodResponse { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for MethodResponse { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "started" => _serde::__private::Ok(__Field::__field0), + "limitReached" => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"started" => _serde::__private::Ok(__Field::__field0), + b"limitReached" => _serde::__private::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "started", + "limitReached", + ]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::< + __Field, + >::new("result", "internally tagged enum MethodResponse"), + )?; + let __deserializer = _serde::__private::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::__private::Result::map( + ::deserialize( + __deserializer, + ), + MethodResponse::Started, + ) + } + __Field::__field1 => { + _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::InternallyTaggedUnitVisitor::new( + "MethodResponse", + "LimitReached", + ), + )?; + _serde::__private::Ok(MethodResponse::LimitReached) + } + } + } + } + }; + /// The `started` result of a method. + #[serde(rename_all = "camelCase")] + pub struct MethodResponseStarted { + /// The operation id of the response. + pub operation_id: String, + /// The number of items from the back of the `chainHead_storage` that have been discarded. + pub discarded_items: Option, + } + #[automatically_derived] + impl ::core::fmt::Debug for MethodResponseStarted { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "MethodResponseStarted", + "operation_id", + &self.operation_id, + "discarded_items", + &&self.discarded_items, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for MethodResponseStarted { + #[inline] + fn clone(&self) -> MethodResponseStarted { + MethodResponseStarted { + operation_id: ::core::clone::Clone::clone(&self.operation_id), + discarded_items: ::core::clone::Clone::clone( + &self.discarded_items, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for MethodResponseStarted {} + #[automatically_derived] + impl ::core::cmp::PartialEq for MethodResponseStarted { + #[inline] + fn eq(&self, other: &MethodResponseStarted) -> bool { + self.operation_id == other.operation_id + && self.discarded_items == other.discarded_items + } + } + #[automatically_derived] + impl ::core::cmp::Eq for MethodResponseStarted { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for MethodResponseStarted { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "operationId" => _serde::__private::Ok(__Field::__field0), + "discardedItems" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"operationId" => _serde::__private::Ok(__Field::__field0), + b"discardedItems" => { + _serde::__private::Ok(__Field::__field1) + } + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData< + MethodResponseStarted, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = MethodResponseStarted; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct MethodResponseStarted", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct MethodResponseStarted with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + Option, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct MethodResponseStarted with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(MethodResponseStarted { + operation_id: __field0, + discarded_items: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + Option, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "operationId", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "discardedItems", + ), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("operationId")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("discardedItems")? + } + }; + _serde::__private::Ok(MethodResponseStarted { + operation_id: __field0, + discarded_items: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "operationId", + "discardedItems", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "MethodResponseStarted", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + MethodResponseStarted, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The storage item received as parameter. + #[serde(rename_all = "camelCase")] + pub struct StorageQuery { + /// The provided key. + pub key: Key, + /// The type of the storage query. + #[serde(rename = "type")] + pub query_type: StorageQueryType, + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageQuery { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "StorageQuery", + "key", + &self.key, + "query_type", + &&self.query_type, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageQuery { + #[inline] + fn clone(&self) -> StorageQuery { + StorageQuery { + key: ::core::clone::Clone::clone(&self.key), + query_type: ::core::clone::Clone::clone(&self.query_type), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageQuery {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for StorageQuery { + #[inline] + fn eq(&self, other: &StorageQuery) -> bool { + self.key == other.key && self.query_type == other.query_type + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageQuery { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for StorageQuery + where + Key: _serde::Serialize, + { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "StorageQuery", + false as usize + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "key", + &self.key, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "type", + &self.query_type, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Key> _serde::Deserialize<'de> for StorageQuery + where + Key: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "key" => _serde::__private::Ok(__Field::__field0), + "type" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"key" => _serde::__private::Ok(__Field::__field0), + b"type" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Key> + where + Key: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Key> _serde::de::Visitor<'de> for __Visitor<'de, Key> + where + Key: _serde::Deserialize<'de>, + { + type Value = StorageQuery; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct StorageQuery", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Key, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct StorageQuery with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + StorageQueryType, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct StorageQuery with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(StorageQuery { + key: __field0, + query_type: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option< + StorageQueryType, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("key"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("type"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + StorageQueryType, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("key")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("type")? + } + }; + _serde::__private::Ok(StorageQuery { + key: __field0, + query_type: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["key", "type"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "StorageQuery", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::>, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// The type of the storage query. + #[serde(rename_all = "camelCase")] + pub enum StorageQueryType { + /// Fetch the value of the provided key. + Value, + /// Fetch the hash of the value of the provided key. + Hash, + /// Fetch the closest descendant merkle value. + ClosestDescendantMerkleValue, + /// Fetch the values of all descendants of they provided key. + DescendantsValues, + /// Fetch the hashes of the values of all descendants of they provided key. + DescendantsHashes, + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageQueryType { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + StorageQueryType::Value => "Value", + StorageQueryType::Hash => "Hash", + StorageQueryType::ClosestDescendantMerkleValue => { + "ClosestDescendantMerkleValue" + } + StorageQueryType::DescendantsValues => "DescendantsValues", + StorageQueryType::DescendantsHashes => "DescendantsHashes", + }, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for StorageQueryType { + #[inline] + fn clone(&self) -> StorageQueryType { + match self { + StorageQueryType::Value => StorageQueryType::Value, + StorageQueryType::Hash => StorageQueryType::Hash, + StorageQueryType::ClosestDescendantMerkleValue => { + StorageQueryType::ClosestDescendantMerkleValue + } + StorageQueryType::DescendantsValues => { + StorageQueryType::DescendantsValues + } + StorageQueryType::DescendantsHashes => { + StorageQueryType::DescendantsHashes + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for StorageQueryType {} + #[automatically_derived] + impl ::core::cmp::PartialEq for StorageQueryType { + #[inline] + fn eq(&self, other: &StorageQueryType) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + impl ::core::cmp::Eq for StorageQueryType { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for StorageQueryType { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + StorageQueryType::Value => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 0u32, + "value", + ) + } + StorageQueryType::Hash => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 1u32, + "hash", + ) + } + StorageQueryType::ClosestDescendantMerkleValue => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 2u32, + "closestDescendantMerkleValue", + ) + } + StorageQueryType::DescendantsValues => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 3u32, + "descendantsValues", + ) + } + StorageQueryType::DescendantsHashes => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "StorageQueryType", + 4u32, + "descendantsHashes", + ) + } + } + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for StorageQueryType { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 5", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "value" => _serde::__private::Ok(__Field::__field0), + "hash" => _serde::__private::Ok(__Field::__field1), + "closestDescendantMerkleValue" => { + _serde::__private::Ok(__Field::__field2) + } + "descendantsValues" => { + _serde::__private::Ok(__Field::__field3) + } + "descendantsHashes" => { + _serde::__private::Ok(__Field::__field4) + } + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"value" => _serde::__private::Ok(__Field::__field0), + b"hash" => _serde::__private::Ok(__Field::__field1), + b"closestDescendantMerkleValue" => { + _serde::__private::Ok(__Field::__field2) + } + b"descendantsValues" => { + _serde::__private::Ok(__Field::__field3) + } + b"descendantsHashes" => { + _serde::__private::Ok(__Field::__field4) + } + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = StorageQueryType; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "enum StorageQueryType", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(StorageQueryType::Value) + } + (__Field::__field1, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(StorageQueryType::Hash) + } + (__Field::__field2, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok( + StorageQueryType::ClosestDescendantMerkleValue, + ) + } + (__Field::__field3, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(StorageQueryType::DescendantsValues) + } + (__Field::__field4, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(StorageQueryType::DescendantsHashes) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "value", + "hash", + "closestDescendantMerkleValue", + "descendantsValues", + "descendantsHashes", + ]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "StorageQueryType", + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// A subscription which returns follow events, and ends when a Stop event occurs. + pub struct FollowSubscription { + sub: RpcSubscription>, + done: bool, + } + impl FollowSubscription { + /// Fetch the next item in the stream. + pub async fn next(&mut self) -> Option<::Item> { + ::next(self).await + } + /// Fetch the subscription ID for the stream. + pub fn subscription_id(&self) -> Option<&str> { + self.sub.subscription_id() + } + } + impl Stream for FollowSubscription { + type Item = > as Stream>::Item; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + if self.done { + return Poll::Ready(None); + } + let res = self.sub.poll_next_unpin(cx); + if let Poll::Ready(Some(Ok(FollowEvent::Stop))) = &res { + self.done = true; + } + res + } + } + /// A subscription which returns transaction status events, stopping + /// when no more events will be sent. + pub struct TransactionSubscription { + sub: RpcSubscription>, + done: bool, + } + impl TransactionSubscription { + /// Fetch the next item in the stream. + pub async fn next(&mut self) -> Option<::Item> { + ::next(self).await + } + } + impl Stream for TransactionSubscription { + type Item = > as Stream>::Item; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + if self.done { + return Poll::Ready(None); + } + let res = self.sub.poll_next_unpin(cx); + if let Poll::Ready(Some(Ok(res))) = &res { + if match res { + TransactionStatus::Dropped { .. } + | TransactionStatus::Error { .. } + | TransactionStatus::Invalid { .. } + | TransactionStatus::Finalized { .. } => true, + _ => false, + } { + self.done = true; + } + } + res + } + } + /// Transaction progress events + #[serde(rename_all = "camelCase")] + #[serde(tag = "event")] + pub enum TransactionStatus { + /// Transaction is part of the future queue. + Validated, + /// The transaction has been broadcast to other nodes. + Broadcasted { + /// Number of peers it's been broadcast to. + num_peers: u32, + }, + /// Transaction has been included in block with given details. + /// Null is returned if the transaction is no longer in any block + /// of the best chain. + BestChainBlockIncluded { + /// Details of the block it's been seen in. + block: Option>, + }, + /// The transaction is in a block that's been finalized. + Finalized { + /// Details of the block it's been seen in. + block: TransactionBlockDetails, + }, + /// Something went wrong in the node. + Error { + /// Human readable message; what went wrong. + error: String, + }, + /// Transaction is invalid (bad nonce, signature etc). + Invalid { + /// Human readable message; why was it invalid. + error: String, + }, + /// The transaction was dropped. + Dropped { + /// Was the transaction broadcasted to other nodes before being dropped? + broadcasted: bool, + /// Human readable message; why was it dropped. + error: String, + }, + } + #[automatically_derived] + impl ::core::fmt::Debug + for TransactionStatus { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionStatus::Validated => { + ::core::fmt::Formatter::write_str(f, "Validated") + } + TransactionStatus::Broadcasted { num_peers: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Broadcasted", + "num_peers", + &__self_0, + ) + } + TransactionStatus::BestChainBlockIncluded { block: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "BestChainBlockIncluded", + "block", + &__self_0, + ) + } + TransactionStatus::Finalized { block: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Finalized", + "block", + &__self_0, + ) + } + TransactionStatus::Error { error: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Error", + "error", + &__self_0, + ) + } + TransactionStatus::Invalid { error: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Invalid", + "error", + &__self_0, + ) + } + TransactionStatus::Dropped { + broadcasted: __self_0, + error: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Dropped", + "broadcasted", + __self_0, + "error", + &__self_1, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone + for TransactionStatus { + #[inline] + fn clone(&self) -> TransactionStatus { + match self { + TransactionStatus::Validated => TransactionStatus::Validated, + TransactionStatus::Broadcasted { num_peers: __self_0 } => { + TransactionStatus::Broadcasted { + num_peers: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::BestChainBlockIncluded { block: __self_0 } => { + TransactionStatus::BestChainBlockIncluded { + block: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Finalized { block: __self_0 } => { + TransactionStatus::Finalized { + block: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Error { error: __self_0 } => { + TransactionStatus::Error { + error: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Invalid { error: __self_0 } => { + TransactionStatus::Invalid { + error: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Dropped { + broadcasted: __self_0, + error: __self_1, + } => { + TransactionStatus::Dropped { + broadcasted: ::core::clone::Clone::clone(__self_0), + error: ::core::clone::Clone::clone(__self_1), + } + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionStatus {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for TransactionStatus { + #[inline] + fn eq(&self, other: &TransactionStatus) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionStatus::Broadcasted { num_peers: __self_0 }, + TransactionStatus::Broadcasted { num_peers: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::BestChainBlockIncluded { + block: __self_0, + }, + TransactionStatus::BestChainBlockIncluded { + block: __arg1_0, + }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Finalized { block: __self_0 }, + TransactionStatus::Finalized { block: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Error { error: __self_0 }, + TransactionStatus::Error { error: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Invalid { error: __self_0 }, + TransactionStatus::Invalid { error: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Dropped { + broadcasted: __self_0, + error: __self_1, + }, + TransactionStatus::Dropped { + broadcasted: __arg1_0, + error: __arg1_1, + }, + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TransactionStatus { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq< + Option>, + >; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> for TransactionStatus + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __field5, + __field6, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + 5u64 => _serde::__private::Ok(__Field::__field5), + 6u64 => _serde::__private::Ok(__Field::__field6), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 7", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "validated" => _serde::__private::Ok(__Field::__field0), + "broadcasted" => _serde::__private::Ok(__Field::__field1), + "bestChainBlockIncluded" => { + _serde::__private::Ok(__Field::__field2) + } + "finalized" => _serde::__private::Ok(__Field::__field3), + "error" => _serde::__private::Ok(__Field::__field4), + "invalid" => _serde::__private::Ok(__Field::__field5), + "dropped" => _serde::__private::Ok(__Field::__field6), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"validated" => _serde::__private::Ok(__Field::__field0), + b"broadcasted" => _serde::__private::Ok(__Field::__field1), + b"bestChainBlockIncluded" => { + _serde::__private::Ok(__Field::__field2) + } + b"finalized" => _serde::__private::Ok(__Field::__field3), + b"error" => _serde::__private::Ok(__Field::__field4), + b"invalid" => _serde::__private::Ok(__Field::__field5), + b"dropped" => _serde::__private::Ok(__Field::__field6), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ + "validated", + "broadcasted", + "bestChainBlockIncluded", + "finalized", + "error", + "invalid", + "dropped", + ]; + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::< + __Field, + >::new("event", "internally tagged enum TransactionStatus"), + )?; + let __deserializer = _serde::__private::de::ContentDeserializer::< + __D::Error, + >::new(__content); + match __tag { + __Field::__field0 => { + _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::InternallyTaggedUnitVisitor::new( + "TransactionStatus", + "Validated", + ), + )?; + _serde::__private::Ok(TransactionStatus::Validated) + } + __Field::__field1 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "num_peers" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"num_peers" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Broadcasted", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u32, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Broadcasted with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Broadcasted { + num_peers: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "num_peers", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("num_peers")? + } + }; + _serde::__private::Ok(TransactionStatus::Broadcasted { + num_peers: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["num_peers"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field2 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "block" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"block" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::BestChainBlockIncluded", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Option>, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::BestChainBlockIncluded with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::BestChainBlockIncluded { + block: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option< + Option>, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("block"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Option>, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("block")? + } + }; + _serde::__private::Ok(TransactionStatus::BestChainBlockIncluded { + block: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["block"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field3 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "block" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"block" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Finalized", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + TransactionBlockDetails, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Finalized with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Finalized { + block: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option< + TransactionBlockDetails, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("block"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + TransactionBlockDetails, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("block")? + } + }; + _serde::__private::Ok(TransactionStatus::Finalized { + block: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["block"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field4 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Error", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Error with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Error { + error: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(TransactionStatus::Error { + error: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["error"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field5 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"error" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Invalid", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Invalid with 1 element", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Invalid { + error: __field0, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(TransactionStatus::Invalid { + error: __field0, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["error"]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + __Field::__field6 => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "broadcasted" => _serde::__private::Ok(__Field::__field0), + "error" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"broadcasted" => _serde::__private::Ok(__Field::__field0), + b"error" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> + for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionStatus; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant TransactionStatus::Dropped", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + bool, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant TransactionStatus::Dropped with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + String, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct variant TransactionStatus::Dropped with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(TransactionStatus::Dropped { + broadcasted: __field0, + error: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "broadcasted", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("error"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("broadcasted")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("error")? + } + }; + _serde::__private::Ok(TransactionStatus::Dropped { + broadcasted: __field0, + error: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "broadcasted", + "error", + ]; + _serde::Deserializer::deserialize_any( + __deserializer, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionStatus, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + } + } + }; + /// Details of a block that a transaction is seen in. + pub struct TransactionBlockDetails { + /// The block hash. + pub hash: Hash, + /// The index of the transaction in the block. + #[serde(with = "unsigned_number_as_string")] + pub index: u64, + } + #[automatically_derived] + impl ::core::fmt::Debug + for TransactionBlockDetails { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "TransactionBlockDetails", + "hash", + &self.hash, + "index", + &&self.index, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for TransactionBlockDetails { + #[inline] + fn clone(&self) -> TransactionBlockDetails { + TransactionBlockDetails { + hash: ::core::clone::Clone::clone(&self.hash), + index: ::core::clone::Clone::clone(&self.index), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for TransactionBlockDetails {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for TransactionBlockDetails { + #[inline] + fn eq(&self, other: &TransactionBlockDetails) -> bool { + self.hash == other.hash && self.index == other.index + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for TransactionBlockDetails { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de, Hash> _serde::Deserialize<'de> + for TransactionBlockDetails + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "hash" => _serde::__private::Ok(__Field::__field0), + "index" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"hash" => _serde::__private::Ok(__Field::__field0), + b"index" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData< + TransactionBlockDetails, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + type Value = TransactionBlockDetails; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct TransactionBlockDetails", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Hash, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct TransactionBlockDetails with 2 elements", + ), + ); + } + }; + let __field1 = match { + #[doc(hidden)] + struct __DeserializeWith<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + value: u64, + phantom: _serde::__private::PhantomData< + TransactionBlockDetails, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::Deserialize<'de> + for __DeserializeWith<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: unsigned_number_as_string::deserialize( + __deserializer, + )?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de, Hash>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct TransactionBlockDetails with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(TransactionBlockDetails { + hash: __field0, + index: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("hash"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("index"), + ); + } + __field1 = _serde::__private::Some({ + #[doc(hidden)] + struct __DeserializeWith<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + value: u64, + phantom: _serde::__private::PhantomData< + TransactionBlockDetails, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de, Hash> _serde::Deserialize<'de> + for __DeserializeWith<'de, Hash> + where + Hash: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: unsigned_number_as_string::deserialize( + __deserializer, + )?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + match _serde::de::MapAccess::next_value::< + __DeserializeWith<'de, Hash>, + >(&mut __map) { + _serde::__private::Ok(__wrapper) => __wrapper.value, + _serde::__private::Err(__err) => { + return _serde::__private::Err(__err); + } + } + }); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("hash")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::missing_field("index"), + ); + } + }; + _serde::__private::Ok(TransactionBlockDetails { + hash: __field0, + index: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["hash", "index"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "TransactionBlockDetails", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + TransactionBlockDetails, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + /// Hex-serialized shim for `Vec`. + pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec); + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Bytes {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Bytes { + #[inline] + fn eq(&self, other: &Bytes) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Bytes { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Bytes { + #[inline] + fn clone(&self) -> Bytes { + Bytes(::core::clone::Clone::clone(&self.0)) + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Bytes { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + _serde::Serializer::serialize_newtype_struct( + __serializer, + "Bytes", + { + #[doc(hidden)] + struct __SerializeWith<'__a> { + values: (&'__a Vec,), + phantom: _serde::__private::PhantomData, + } + impl<'__a> _serde::Serialize for __SerializeWith<'__a> { + fn serialize<__S>( + &self, + __s: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + impl_serde::serialize::serialize(self.values.0, __s) + } + } + &__SerializeWith { + values: (&self.0,), + phantom: _serde::__private::PhantomData::, + } + }, + ) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Bytes { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Bytes; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "tuple struct Bytes", + ) + } + #[inline] + fn visit_newtype_struct<__E>( + self, + __e: __E, + ) -> _serde::__private::Result + where + __E: _serde::Deserializer<'de>, + { + let __field0: Vec = impl_serde::serialize::deserialize( + __e, + )?; + _serde::__private::Ok(Bytes(__field0)) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match { + #[doc(hidden)] + struct __DeserializeWith<'de> { + value: Vec, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::Deserialize<'de> + for __DeserializeWith<'de> { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: impl_serde::serialize::deserialize(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"tuple struct Bytes with 1 element", + ), + ); + } + }; + _serde::__private::Ok(Bytes(__field0)) + } + } + _serde::Deserializer::deserialize_newtype_struct( + __deserializer, + "Bytes", + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::hash::Hash for Bytes { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Bytes { + #[inline] + fn partial_cmp( + &self, + other: &Bytes, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Bytes { + #[inline] + fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Bytes { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Bytes", + &&self.0, + ) + } + } + impl std::ops::Deref for Bytes { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.0[..] + } + } + impl From> for Bytes { + fn from(s: Vec) -> Self { + Bytes(s) + } + } + fn to_hex(bytes: impl AsRef<[u8]>) -> String { + { + let res = ::alloc::fmt::format( + format_args!("0x{0}", hex::encode(bytes.as_ref())), + ); + res + } + } + /// Attempt to deserialize either a string or integer into an integer. + /// See + pub(crate) mod unsigned_number_as_string { + use serde::de::{Deserializer, Visitor}; + use std::fmt; + /// Deserialize a number from a string or number. + pub fn deserialize<'de, N: From, D>( + deserializer: D, + ) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(NumberVisitor(std::marker::PhantomData)) + } + struct NumberVisitor(std::marker::PhantomData); + impl<'de, N: From> Visitor<'de> for NumberVisitor { + type Value = N; + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .write_str("an unsigned integer or a string containing one") + } + fn visit_str( + self, + v: &str, + ) -> Result { + let n: u64 = v.parse().map_err(serde::de::Error::custom)?; + Ok(n.into()) + } + fn visit_u64( + self, + v: u64, + ) -> Result { + Ok(v.into()) + } + } + } + /// A temporary shim to decode "spec.apis" if it comes back as an array like: + /// + /// ```text + /// [["0xABC", 1], ["0xCDE", 2]] + /// ``` + /// + /// The expected format (which this also supports deserializing from) is: + /// + /// ```text + /// { "0xABC": 1, "0xCDE": 2 } + /// ``` + /// + /// We can delete this when the correct format is being returned. + /// + /// Adapted from + pub(crate) mod hashmap_as_tuple_list { + use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; + use std::collections::HashMap; + use std::fmt; + use std::hash::{BuildHasher, Hash}; + use std::marker::PhantomData; + /// Deserialize a [`HashMap`] from a list of tuples or object + pub fn deserialize<'de, K, V, BH, D>( + deserializer: D, + ) -> Result, D::Error> + where + D: Deserializer<'de>, + K: Eq + Hash + Deserialize<'de>, + V: Deserialize<'de>, + BH: BuildHasher + Default, + { + deserializer.deserialize_any(HashMapVisitor(PhantomData)) + } + #[allow(clippy::type_complexity)] + struct HashMapVisitor(PhantomData HashMap>); + impl<'de, K, V, BH> Visitor<'de> for HashMapVisitor + where + K: Deserialize<'de> + Eq + Hash, + V: Deserialize<'de>, + BH: BuildHasher + Default, + { + type Value = HashMap; + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a list of key-value pairs") + } + fn visit_map(self, mut m: A) -> Result + where + A: serde::de::MapAccess<'de>, + { + let mut map = HashMap::with_capacity_and_hasher( + m.size_hint().unwrap_or(0), + BH::default(), + ); + while let Some((key, value)) = m.next_entry()? { + map.insert(key, value); + } + Ok(map) + } + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let mut map = HashMap::with_capacity_and_hasher( + seq.size_hint().unwrap_or(0), + BH::default(), + ); + while let Some((key, value)) = seq.next_element()? { + map.insert(key, value); + } + Ok(map) + } + } + } + } + use self::rpc_methods::{ + FollowEvent, MethodResponse, RuntimeEvent, StorageQuery, StorageQueryType, + StorageResultType, + }; + use crate::backend::{ + rpc::RpcClient, Backend, BlockRef, BlockRefT, RuntimeVersion, + StorageResponse, StreamOf, StreamOfResults, TransactionStatus, + }; + use crate::config::BlockHash; + use crate::error::{Error, RpcError}; + use crate::Config; + use async_trait::async_trait; + use follow_stream_driver::{FollowStreamDriver, FollowStreamDriverHandle}; + use futures::{Stream, StreamExt}; + use std::collections::HashMap; + use std::sync::Arc; + use std::task::Poll; + use storage_items::StorageItems; + pub use rpc_methods::UnstableRpcMethods; + /// Configure and build an [`UnstableBackend`]. + pub struct UnstableBackendBuilder { + max_block_life: usize, + _marker: std::marker::PhantomData, + } + impl Default for UnstableBackendBuilder { + fn default() -> Self { + Self::new() + } + } + impl UnstableBackendBuilder { + /// Create a new [`UnstableBackendBuilder`]. + pub fn new() -> Self { + Self { + max_block_life: usize::MAX, + _marker: std::marker::PhantomData, + } + } + /// The age of a block is defined here as the difference between the current finalized block number + /// and the block number of a given block. Once the difference equals or exceeds the number given + /// here, the block is unpinned. + /// + /// By default, we will never automatically unpin blocks, but if the number of pinned blocks that we + /// keep hold of exceeds the number that the server can tolerate, then a `stop` event is generated and + /// we are forced to resubscribe, losing any pinned blocks. + pub fn max_block_life(mut self, max_block_life: usize) -> Self { + self.max_block_life = max_block_life; + self + } + /// Given an [`RpcClient`] to use to make requests, this returns a tuple of an [`UnstableBackend`], + /// which implements the [`Backend`] trait, and an [`UnstableBackendDriver`] which must be polled in + /// order for the backend to make progress. + pub fn build( + self, + client: RpcClient, + ) -> (UnstableBackend, UnstableBackendDriver) { + let rpc_methods = UnstableRpcMethods::new(client); + let follow_stream = follow_stream::FollowStream::< + T::Hash, + >::from_methods(rpc_methods.clone()); + let follow_stream_unpin = follow_stream_unpin::FollowStreamUnpin::< + T::Hash, + >::from_methods(follow_stream, rpc_methods.clone(), self.max_block_life); + let follow_stream_driver = FollowStreamDriver::new(follow_stream_unpin); + let backend = UnstableBackend { + methods: rpc_methods, + follow_handle: follow_stream_driver.handle(), + }; + let driver = UnstableBackendDriver { + driver: follow_stream_driver, + }; + (backend, driver) + } + } + /// Driver for the [`UnstableBackend`]. This must be polled in order for the + /// backend to make progress. + pub struct UnstableBackendDriver { + driver: FollowStreamDriver, + } + #[automatically_derived] + impl ::core::fmt::Debug + for UnstableBackendDriver + where + T::Hash: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "UnstableBackendDriver", + "driver", + &&self.driver, + ) + } + } + impl Stream for UnstableBackendDriver { + type Item = as Stream>::Item; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.driver.poll_next_unpin(cx) + } + } + /// The unstable backend. + pub struct UnstableBackend { + methods: UnstableRpcMethods, + follow_handle: FollowStreamDriverHandle, + } + #[automatically_derived] + impl ::core::fmt::Debug for UnstableBackend + where + T::Hash: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "UnstableBackend", + "methods", + &self.methods, + "follow_handle", + &&self.follow_handle, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone + for UnstableBackend + where + T::Hash: ::core::clone::Clone, + { + #[inline] + fn clone(&self) -> UnstableBackend { + UnstableBackend { + methods: ::core::clone::Clone::clone(&self.methods), + follow_handle: ::core::clone::Clone::clone(&self.follow_handle), + } + } + } + impl UnstableBackend { + /// Configure and construct an [`UnstableBackend`] and the associated [`UnstableBackendDriver`]. + pub fn builder() -> UnstableBackendBuilder { + UnstableBackendBuilder::new() + } + /// Stream block headers based on the provided filter fn + async fn stream_headers( + &self, + f: F, + ) -> Result)>, Error> + where + F: Fn(FollowEvent>) -> I + Copy + + Send + 'static, + I: IntoIterator> + Send + + 'static, + ::IntoIter: Send, + { + let sub_id = get_subscription_id(&self.follow_handle).await?; + let sub_id = Arc::new(sub_id); + let methods = self.methods.clone(); + let headers = self + .follow_handle + .subscribe() + .events() + .flat_map(move |ev| { + let sub_id = sub_id.clone(); + let methods = methods.clone(); + let block_refs = f(ev).into_iter(); + futures::stream::iter(block_refs) + .filter_map(move |block_ref| { + let sub_id = sub_id.clone(); + let methods = methods.clone(); + async move { + let res = methods + .chainhead_unstable_header(&sub_id, block_ref.hash()) + .await + .transpose()?; + let header = match res { + Ok(header) => header, + Err(e) => return Some(Err(e)), + }; + Some(Ok((header, block_ref.into()))) + } + }) + }); + Ok(StreamOf(Box::pin(headers))) + } + } + impl BlockRefT + for follow_stream_unpin::BlockRef {} + impl From> + for BlockRef { + fn from(b: follow_stream_unpin::BlockRef) -> Self { + BlockRef::new(b.hash(), b) + } + } + impl super::sealed::Sealed for UnstableBackend {} + impl Backend for UnstableBackend { + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_values<'life0, 'async_trait>( + &'life0 self, + keys: Vec>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let keys = keys; + let at = at; + let __ret: Result, Error> = { + let queries = keys + .iter() + .map(|key| StorageQuery { + key: &**key, + query_type: StorageQueryType::Value, + }); + let storage_items = StorageItems::from_methods( + queries, + at, + &__self.follow_handle, + __self.methods.clone(), + ) + .await?; + let storage_result_stream = storage_items + .filter_map(|val| async move { + let val = match val { + Ok(val) => val, + Err(e) => return Some(Err(e)), + }; + let StorageResultType::Value(result) = val.result else { + return None; + }; + Some( + Ok(StorageResponse { + key: val.key.0, + value: result.0, + }), + ) + }); + Ok(StreamOf(Box::pin(storage_result_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_descendant_keys<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>, Error>, + > { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result>, Error> = { + let query = StorageQuery { + key: &*key, + query_type: StorageQueryType::DescendantsHashes, + }; + let storage_items = StorageItems::from_methods( + std::iter::once(query), + at, + &__self.follow_handle, + __self.methods.clone(), + ) + .await?; + let storage_result_stream = storage_items + .map(|val| val.map(|v| v.key.0)); + Ok(StreamOf(Box::pin(storage_result_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_descendant_values<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result, Error> = { + let query = StorageQuery { + key: &*key, + query_type: StorageQueryType::DescendantsValues, + }; + let storage_items = StorageItems::from_methods( + std::iter::once(query), + at, + &__self.follow_handle, + __self.methods.clone(), + ) + .await?; + let storage_result_stream = storage_items + .filter_map(|val| async move { + let val = match val { + Ok(val) => val, + Err(e) => return Some(Err(e)), + }; + let StorageResultType::Value(result) = val.result else { + return None; + }; + Some( + Ok(StorageResponse { + key: val.key.0, + value: result.0, + }), + ) + }); + Ok(StreamOf(Box::pin(storage_result_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn genesis_hash<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let __ret: Result = { + __self.methods.chainspec_v1_genesis_hash().await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn block_header<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result, Error> = { + let sub_id = get_subscription_id(&__self.follow_handle).await?; + __self.methods.chainhead_unstable_header(&sub_id, at).await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn block_body<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>>, Error>, + > { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result>>, Error> = { + let sub_id = get_subscription_id(&__self.follow_handle).await?; + let follow_events = __self.follow_handle.subscribe().events(); + let status = __self + .methods + .chainhead_unstable_body(&sub_id, at) + .await?; + let operation_id = match status { + MethodResponse::LimitReached => { + return Err( + RpcError::request_rejected("limit reached").into(), + ); + } + MethodResponse::Started(s) => s.operation_id, + }; + let mut exts_stream = follow_events + .filter_map(|ev| { + let FollowEvent::OperationBodyDone(body) = ev else { + return std::future::ready(None); + }; + if body.operation_id != operation_id { + return std::future::ready(None); + } + let exts: Vec<_> = body + .value + .into_iter() + .map(|ext| ext.0) + .collect(); + std::future::ready(Some(exts)) + }); + Ok(exts_stream.next().await) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn latest_finalized_block_ref<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result, Error> = { + let next_ref: Option> = __self + .follow_handle + .subscribe() + .events() + .filter_map(|ev| { + let out = match ev { + FollowEvent::Initialized(init) => { + Some(init.finalized_block_hash.into()) + } + _ => None, + }; + std::future::ready(out) + }) + .next() + .await; + next_ref.ok_or_else(|| RpcError::SubscriptionDropped.into()) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn current_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let __ret: Result = { + let runtime_version = __self + .stream_runtime_version() + .await? + .next() + .await; + match runtime_version { + None => Err(Error::Rpc(RpcError::SubscriptionDropped)), + Some(Err(e)) => Err(e), + Some(Ok(version)) => Ok(version), + } + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result, Error> = { + let mut runtimes = HashMap::new(); + let runtime_stream = __self + .follow_handle + .subscribe() + .events() + .filter_map(move |ev| { + let output = match ev { + FollowEvent::Initialized(ev) => { + runtimes.remove(&ev.finalized_block_hash.hash()); + ev.finalized_block_runtime + } + FollowEvent::NewBlock(ev) => { + if let Some(runtime) = ev.new_runtime { + runtimes.insert(ev.block_hash.hash(), runtime); + } + None + } + FollowEvent::Finalized(ev) => { + let next_runtime = { + let mut it = ev + .finalized_block_hashes + .iter() + .rev() + .filter_map(|h| runtimes.get(&h.hash()).cloned()) + .peekable(); + let next = it.next(); + if it.peek().is_some() { + { + use ::tracing::__macro_support::Callsite as _; + static __CALLSITE: ::tracing::callsite::DefaultCallsite = { + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "event subxt/src/backend/unstable/mod.rs:377", + "subxt", + ::tracing::Level::WARN, + ::core::option::Option::Some( + "subxt/src/backend/unstable/mod.rs", + ), + ::core::option::Option::Some(377u32), + ::core::option::Option::Some("subxt::backend::unstable"), + ::tracing_core::field::FieldSet::new( + &["message"], + ::tracing_core::callsite::Identifier(&__CALLSITE), + ), + ::tracing::metadata::Kind::EVENT, + ) + }; + ::tracing::callsite::DefaultCallsite::new(&META) + }; + let enabled = ::tracing::Level::WARN + <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::WARN + <= ::tracing::level_filters::LevelFilter::current() + && { + let interest = __CALLSITE.interest(); + !interest.is_never() + && ::tracing::__macro_support::__is_enabled( + __CALLSITE.metadata(), + interest, + ) + }; + if enabled { + (|value_set: ::tracing::field::ValueSet| { + let meta = __CALLSITE.metadata(); + ::tracing::Event::dispatch(meta, &value_set); + })({ + #[allow(unused_imports)] + use ::tracing::field::{debug, display, Value}; + let mut iter = __CALLSITE.metadata().fields().iter(); + __CALLSITE + .metadata() + .fields() + .value_set( + &[ + ( + &::core::iter::Iterator::next(&mut iter) + .expect("FieldSet corrupted (this is a bug)"), + ::core::option::Option::Some( + &format_args!( + "Several runtime upgrades in the finalized blocks but only the latest runtime upgrade is returned" + ) as &dyn Value, + ), + ), + ], + ) + }); + } else { + } + }; + } + next + }; + for block in ev + .finalized_block_hashes + .iter() + .chain(ev.pruned_block_hashes.iter()) + { + runtimes.remove(&block.hash()); + } + next_runtime + } + _ => None, + }; + let runtime_event = match output { + None => return std::future::ready(None), + Some(ev) => ev, + }; + let runtime_details = match runtime_event { + RuntimeEvent::Invalid(err) => { + return std::future::ready( + Some(Err(Error::Other(err.error))), + ); + } + RuntimeEvent::Valid(ev) => ev, + }; + std::future::ready( + Some( + Ok(RuntimeVersion { + spec_version: runtime_details.spec.spec_version, + transaction_version: runtime_details + .spec + .transaction_version, + }), + ), + ) + }); + Ok(StreamOf(Box::pin(runtime_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_all_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + __self + .stream_headers(|ev| match ev { + FollowEvent::Initialized(ev) => { + Some(ev.finalized_block_hash) + } + FollowEvent::NewBlock(ev) => Some(ev.block_hash), + _ => None, + }) + .await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_best_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + __self + .stream_headers(|ev| match ev { + FollowEvent::Initialized(ev) => { + Some(ev.finalized_block_hash) + } + FollowEvent::BestBlockChanged(ev) => { + Some(ev.best_block_hash) + } + _ => None, + }) + .await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn stream_finalized_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + > = { + __self + .stream_headers(|ev| match ev { + FollowEvent::Initialized(ev) => { + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ev.finalized_block_hash]), + ) + } + FollowEvent::Finalized(ev) => ev.finalized_block_hashes, + _ => ::alloc::vec::Vec::new(), + }) + .await + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn submit_transaction<'life0, 'life1, 'async_trait>( + &'life0 self, + extrinsic: &'life1 [u8], + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::< + Result>, Error>, + > { + return __ret; + } + let __self = self; + let __ret: Result< + StreamOfResults>, + Error, + > = { + enum SeenBlockMarker { + New, + Finalized, + } + let mut seen_blocks_sub = __self + .follow_handle + .subscribe() + .events(); + let mut tx_progress = __self + .methods + .transaction_unstable_submit_and_watch(extrinsic) + .await?; + let mut seen_blocks = HashMap::new(); + let mut done = false; + let mut finalized_hash: Option = None; + let start_instant = instant::Instant::now(); + let err_other = |s: &str| Some(Err(Error::Other(s.into()))); + let tx_stream = futures::stream::poll_fn(move |cx| { + loop { + if done { + return Poll::Ready(None); + } + if start_instant.elapsed().as_secs() > 240 { + return Poll::Ready( + err_other( + "Timeout waiting for the transaction to be finalized", + ), + ); + } + let follow_ev_poll = match seen_blocks_sub + .poll_next_unpin(cx) + { + Poll::Ready(None) => { + return Poll::Ready( + err_other("chainHead_follow stream ended unexpectedly"), + ); + } + Poll::Ready(Some(follow_ev)) => Poll::Ready(follow_ev), + Poll::Pending => Poll::Pending, + }; + let follow_ev_is_pending = follow_ev_poll.is_pending(); + if let Poll::Ready(follow_ev) = follow_ev_poll { + match follow_ev { + FollowEvent::NewBlock(ev) => { + if finalized_hash.is_none() { + seen_blocks + .insert( + ev.block_hash.hash(), + (SeenBlockMarker::New, ev.block_hash), + ); + } + } + FollowEvent::Finalized(ev) => { + for block_ref in ev.finalized_block_hashes { + seen_blocks + .insert( + block_ref.hash(), + (SeenBlockMarker::Finalized, block_ref), + ); + } + } + FollowEvent::Stop => { + return Poll::Ready( + err_other( + "chainHead_follow emitted 'stop' event during transaction submission", + ), + ); + } + _ => {} + } + continue; + } + if let Some(hash) = &finalized_hash { + if let Some((SeenBlockMarker::Finalized, block_ref)) + = seen_blocks.remove(hash) + { + done = true; + let ev = TransactionStatus::InFinalizedBlock { + hash: block_ref.into(), + }; + return Poll::Ready(Some(Ok(ev))); + } else { + seen_blocks.clear(); + if follow_ev_is_pending { + return Poll::Pending; + } else { + continue; + } + } + } + let tx_progress_ev = match tx_progress.poll_next_unpin(cx) { + Poll::Pending => return Poll::Pending, + Poll::Ready(None) => { + return Poll::Ready( + err_other( + "No more transaction progress events, but we haven't seen a Finalized one yet", + ), + ); + } + Poll::Ready(Some(Err(e))) => { + return Poll::Ready(Some(Err(e))); + } + Poll::Ready(Some(Ok(ev))) => ev, + }; + let tx_progress_ev = match tx_progress_ev { + rpc_methods::TransactionStatus::Finalized { block } => { + finalized_hash = Some(block.hash); + continue; + } + rpc_methods::TransactionStatus::BestChainBlockIncluded { + block: Some(block), + } => { + let block_ref = match seen_blocks.get(&block.hash) { + Some((_, block_ref)) => block_ref.clone().into(), + None => BlockRef::from_hash(block.hash), + }; + TransactionStatus::InBestBlock { + hash: block_ref, + } + } + rpc_methods::TransactionStatus::BestChainBlockIncluded { + block: None, + } => TransactionStatus::NoLongerInBestBlock, + rpc_methods::TransactionStatus::Broadcasted { + num_peers, + } => { + TransactionStatus::Broadcasted { + num_peers, + } + } + rpc_methods::TransactionStatus::Dropped { error, .. } => { + TransactionStatus::Dropped { + message: error, + } + } + rpc_methods::TransactionStatus::Error { error } => { + TransactionStatus::Dropped { + message: error, + } + } + rpc_methods::TransactionStatus::Invalid { error } => { + TransactionStatus::Invalid { + message: error, + } + } + rpc_methods::TransactionStatus::Validated => { + TransactionStatus::Validated + } + }; + return Poll::Ready(Some(Ok(tx_progress_ev))); + } + }); + Ok(StreamOf(Box::pin(tx_stream))) + }; + #[allow(unreachable_code)] __ret + }) + } + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn call<'life0, 'life1, 'life2, 'async_trait>( + &'life0 self, + method: &'life1 str, + call_parameters: Option<&'life2 [u8]>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + 'life2: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::, Error>> { + return __ret; + } + let __self = self; + let call_parameters = call_parameters; + let at = at; + let __ret: Result, Error> = { + let sub_id = get_subscription_id(&__self.follow_handle).await?; + let follow_events = __self.follow_handle.subscribe().events(); + let call_parameters = call_parameters.unwrap_or(&[]); + let status = __self + .methods + .chainhead_unstable_call( + &sub_id, + at, + method, + call_parameters, + ) + .await?; + let operation_id = match status { + MethodResponse::LimitReached => { + return Err( + RpcError::request_rejected("limit reached").into(), + ); + } + MethodResponse::Started(s) => s.operation_id, + }; + let mut call_data_stream = follow_events + .filter_map(|ev| { + let FollowEvent::OperationCallDone(body) = ev else { + return std::future::ready(None); + }; + if body.operation_id != operation_id { + return std::future::ready(None); + } + std::future::ready(Some(body.output.0)) + }); + call_data_stream + .next() + .await + .ok_or_else(|| RpcError::SubscriptionDropped.into()) + }; + #[allow(unreachable_code)] __ret + }) + } + } + /// A helper to obtain a subscription ID. + async fn get_subscription_id( + follow_handle: &FollowStreamDriverHandle, + ) -> Result { + let Some(sub_id) = follow_handle.subscribe().subscription_id().await else { + return Err(RpcError::SubscriptionDropped.into()); + }; + Ok(sub_id) + } + } + use crate::error::Error; + use crate::metadata::Metadata; + use crate::Config; + use async_trait::async_trait; + use codec::{Decode, Encode}; + use futures::{Stream, StreamExt}; + use std::pin::Pin; + use std::sync::Arc; + /// Prevent the backend trait being implemented externally. + #[doc(hidden)] + pub(crate) mod sealed { + pub trait Sealed {} + } + /// This trait exposes the interface that Subxt will use to communicate with + /// a backend. Its goal is to be as minimal as possible. + pub trait Backend: sealed::Sealed + Send + Sync + 'static { + /// Fetch values from storage. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn storage_fetch_values<'life0, 'async_trait>( + &'life0 self, + keys: Vec>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Fetch keys underneath the given key from storage. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn storage_fetch_descendant_keys<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Fetch values underneath the given key from storage. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn storage_fetch_descendant_values<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Fetch the genesis hash + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn genesis_hash<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Get a block header + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn block_header<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Return the extrinsics found in the block. Each extrinsic is represented + /// by a vector of bytes which has _not_ been SCALE decoded (in other words, the + /// first bytes in the vector will decode to the compact encoded length of the extrinsic) + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn block_body<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Get the most recent finalized block hash. + /// Note: needed only in blocks client for finalized block stream; can prolly be removed. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn latest_finalized_block_ref<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Get information about the current runtime. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn current_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// A stream of all new runtime versions as they occur. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn stream_runtime_version<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// A stream of all new block headers as they arrive. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn stream_all_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// A stream of best block headers. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn stream_best_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// A stream of finalized block headers. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn stream_finalized_block_headers<'life0, 'async_trait>( + &'life0 self, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result< + StreamOfResults<(T::Header, BlockRef)>, + Error, + >, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: 'async_trait; + /// Submit a transaction. This will return a stream of events about it. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn submit_transaction<'life0, 'life1, 'async_trait>( + &'life0 self, + bytes: &'life1 [u8], + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + Self: 'async_trait; + /// Make a call to some runtime API. + #[must_use] + #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] + fn call<'life0, 'life1, 'life2, 'async_trait>( + &'life0 self, + method: &'life1 str, + call_parameters: Option<&'life2 [u8]>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + 'life1: 'async_trait, + 'life2: 'async_trait, + Self: 'async_trait; + } + /// helpeful utility methods derived from those provided on [`Backend`] + pub trait BackendExt: Backend { + /// Fetch a single value from storage. + #[must_use] + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn storage_fetch_value<'life0, 'async_trait>( + &'life0 self, + key: Vec, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result>, Error>, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: ::core::marker::Sync + 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::>, Error>> { + return __ret; + } + let __self = self; + let key = key; + let at = at; + let __ret: Result>, Error> = { + __self + .storage_fetch_values( + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([key]), + ), + at, + ) + .await? + .next() + .await + .transpose() + .map(|o| o.map(|s| s.value)) + }; + #[allow(unreachable_code)] __ret + }) + } + /// The same as a [`Backend::call()`], but it will also attempt to decode the + /// result into the given type, which is a fairly common operation. + #[must_use] + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn call_decoding<'life0, 'life1, 'life2, 'async_trait, D>( + &'life0 self, + method: &'life1 str, + call_parameters: Option<&'life2 [u8]>, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + D: 'async_trait + codec::Decode, + 'life0: 'async_trait, + 'life1: 'async_trait, + 'life2: 'async_trait, + Self: ::core::marker::Sync + 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let call_parameters = call_parameters; + let at = at; + let __ret: Result = { + let bytes = __self.call(method, call_parameters, at).await?; + let res = D::decode(&mut &*bytes)?; + Ok(res) + }; + #[allow(unreachable_code)] __ret + }) + } + /// Return the metadata at some version. + #[must_use] + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn metadata_at_version<'life0, 'async_trait>( + &'life0 self, + version: u32, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: ::core::marker::Sync + 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let version = version; + let at = at; + let __ret: Result = { + let param = version.encode(); + let opaque: Option = __self + .call_decoding("Metadata_metadata_at_version", Some(¶m), at) + .await?; + let Some(opaque) = opaque else { + return Err(Error::Other("Metadata version not found".into())); + }; + let metadata: Metadata = Decode::decode(&mut &opaque.0[..])?; + Ok(metadata) + }; + #[allow(unreachable_code)] __ret + }) + } + /// Return V14 metadata from the legacy `Metadata_metadata` call. + #[must_use] + #[allow( + clippy::async_yields_async, + clippy::diverging_sub_expression, + clippy::let_unit_value, + clippy::no_effect_underscore_binding, + clippy::shadow_same, + clippy::type_complexity, + clippy::type_repetition_in_bounds, + clippy::used_underscore_binding + )] + fn legacy_metadata<'life0, 'async_trait>( + &'life0 self, + at: T::Hash, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future< + Output = Result, + > + ::core::marker::Send + 'async_trait, + >, + > + where + 'life0: 'async_trait, + Self: ::core::marker::Sync + 'async_trait, + { + Box::pin(async move { + if let ::core::option::Option::Some(__ret) + = ::core::option::Option::None::> { + return __ret; + } + let __self = self; + let at = at; + let __ret: Result = { + let opaque: frame_metadata::OpaqueMetadata = __self + .call_decoding("Metadata_metadata", None, at) + .await?; + let metadata: Metadata = Decode::decode(&mut &opaque.0[..])?; + Ok(metadata) + }; + #[allow(unreachable_code)] __ret + }) + } + } + impl + ?Sized, T: Config> BackendExt for B {} + /// An opaque struct which, while alive, indicates that some references to a block + /// still exist. This gives the backend the opportunity to keep the corresponding block + /// details around for a while if it likes and is able to. No guarantees can be made about + /// how long the corresponding details might be available for, but if no references to a block + /// exist, then the backend is free to discard any details for it. + pub struct BlockRef { + hash: H, + _pointer: Option>, + } + #[automatically_derived] + impl ::core::clone::Clone for BlockRef { + #[inline] + fn clone(&self) -> BlockRef { + BlockRef { + hash: ::core::clone::Clone::clone(&self.hash), + _pointer: ::core::clone::Clone::clone(&self._pointer), + } + } + } + impl From for BlockRef { + fn from(value: H) -> Self { + BlockRef::from_hash(value) + } + } + impl PartialEq for BlockRef { + fn eq(&self, other: &Self) -> bool { + self.hash == other.hash + } + } + impl Eq for BlockRef {} + impl PartialOrd for BlockRef { + fn partial_cmp(&self, other: &Self) -> Option { + self.hash.partial_cmp(&other.hash) + } + } + impl Ord for BlockRef { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.hash.cmp(&other.hash) + } + } + impl std::fmt::Debug for BlockRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("BlockRef").field(&self.hash).finish() + } + } + impl std::hash::Hash for BlockRef { + fn hash(&self, state: &mut Hasher) { + self.hash.hash(state); + } + } + impl BlockRef { + /// A [`BlockRef`] that doesn't reference a given block, but does have an associated hash. + /// This is used in the legacy backend, which has no notion of pinning blocks. + pub fn from_hash(hash: H) -> Self { + Self { hash, _pointer: None } + } + /// Construct a [`BlockRef`] from an instance of the underlying trait. It's expected + /// that the [`Backend`] implementation will call this if it wants to track which blocks + /// are potentially in use. + pub fn new(hash: H, inner: P) -> Self { + Self { + hash, + _pointer: Some(Arc::new(inner)), + } + } + /// Return the hash of the referenced block. + pub fn hash(&self) -> H + where + H: Copy, + { + self.hash + } + } + /// A trait that a [`Backend`] can implement to know when some block + /// can be unpinned: when this is dropped, there are no remaining references + /// to the block that it's associated with. + pub trait BlockRefT: Send + Sync + 'static {} + /// A stream of some item. + pub struct StreamOf(Pin + Send + 'static>>); + impl Stream for StreamOf { + type Item = T; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.0.poll_next_unpin(cx) + } + } + impl std::fmt::Debug for StreamOf { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("StreamOf").field(&"").finish() + } + } + impl StreamOf { + /// Construct a new stream. + pub fn new(inner: Pin + Send + 'static>>) -> Self { + StreamOf(inner) + } + /// Returns the next item in the stream. This is just a wrapper around + /// [`StreamExt::next()`] so that you can avoid the extra import. + pub async fn next(&mut self) -> Option { + StreamExt::next(self).await + } + } + /// A stream of [`Result`]. + pub type StreamOfResults = StreamOf>; + /// Runtime version information needed to submit transactions. + pub struct RuntimeVersion { + /// Version of the runtime specification. A full-node will not attempt to use its native + /// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, + /// `spec_version` and `authoring_version` are the same between Wasm and native. + pub spec_version: u32, + /// All existing dispatches are fully compatible when this number doesn't change. If this + /// number changes, then `spec_version` must change, also. + /// + /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, + /// either through an alteration in its user-level semantics, a parameter + /// added/removed/changed, a dispatchable being removed, a module being removed, or a + /// dispatchable/module changing its index. + /// + /// It need *not* change when a new module is added or when a dispatchable is added. + pub transaction_version: u32, + } + #[automatically_derived] + impl ::core::fmt::Debug for RuntimeVersion { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "RuntimeVersion", + "spec_version", + &self.spec_version, + "transaction_version", + &&self.transaction_version, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for RuntimeVersion { + #[inline] + fn clone(&self) -> RuntimeVersion { + RuntimeVersion { + spec_version: ::core::clone::Clone::clone(&self.spec_version), + transaction_version: ::core::clone::Clone::clone( + &self.transaction_version, + ), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for RuntimeVersion {} + #[automatically_derived] + impl ::core::cmp::PartialEq for RuntimeVersion { + #[inline] + fn eq(&self, other: &RuntimeVersion) -> bool { + self.spec_version == other.spec_version + && self.transaction_version == other.transaction_version + } + } + #[automatically_derived] + impl ::core::cmp::Eq for RuntimeVersion { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + /// The status of the transaction. + /// + /// If the status is [`TransactionStatus::InFinalizedBlock`], [`TransactionStatus::Error`], + /// [`TransactionStatus::Invalid`] or [`TransactionStatus::Dropped`], then no future + /// events will be emitted. + pub enum TransactionStatus { + /// Transaction is part of the future queue. + Validated, + /// The transaction has been broadcast to other nodes. + Broadcasted { + /// Number of peers it's been broadcast to. + num_peers: u32, + }, + /// Transaction is no longer in a best block. + NoLongerInBestBlock, + /// Transaction has been included in block with given hash. + InBestBlock { + /// Block hash the transaction is in. + hash: BlockRef, + }, + /// Transaction has been finalized by a finality-gadget, e.g GRANDPA + InFinalizedBlock { + /// Block hash the transaction is in. + hash: BlockRef, + }, + /// Something went wrong in the node. + Error { + /// Human readable message; what went wrong. + message: String, + }, + /// Transaction is invalid (bad nonce, signature etc). + Invalid { + /// Human readable message; why was it invalid. + message: String, + }, + /// The transaction was dropped. + Dropped { + /// Human readable message; why was it dropped. + message: String, + }, + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionStatus { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionStatus::Validated => { + ::core::fmt::Formatter::write_str(f, "Validated") + } + TransactionStatus::Broadcasted { num_peers: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Broadcasted", + "num_peers", + &__self_0, + ) + } + TransactionStatus::NoLongerInBestBlock => { + ::core::fmt::Formatter::write_str(f, "NoLongerInBestBlock") + } + TransactionStatus::InBestBlock { hash: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "InBestBlock", + "hash", + &__self_0, + ) + } + TransactionStatus::InFinalizedBlock { hash: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "InFinalizedBlock", + "hash", + &__self_0, + ) + } + TransactionStatus::Error { message: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Error", + "message", + &__self_0, + ) + } + TransactionStatus::Invalid { message: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Invalid", + "message", + &__self_0, + ) + } + TransactionStatus::Dropped { message: __self_0 } => { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Dropped", + "message", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::clone::Clone for TransactionStatus { + #[inline] + fn clone(&self) -> TransactionStatus { + match self { + TransactionStatus::Validated => TransactionStatus::Validated, + TransactionStatus::Broadcasted { num_peers: __self_0 } => { + TransactionStatus::Broadcasted { + num_peers: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::NoLongerInBestBlock => { + TransactionStatus::NoLongerInBestBlock + } + TransactionStatus::InBestBlock { hash: __self_0 } => { + TransactionStatus::InBestBlock { + hash: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::InFinalizedBlock { hash: __self_0 } => { + TransactionStatus::InFinalizedBlock { + hash: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Error { message: __self_0 } => { + TransactionStatus::Error { + message: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Invalid { message: __self_0 } => { + TransactionStatus::Invalid { + message: ::core::clone::Clone::clone(__self_0), + } + } + TransactionStatus::Dropped { message: __self_0 } => { + TransactionStatus::Dropped { + message: ::core::clone::Clone::clone(__self_0), + } + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionStatus {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for TransactionStatus { + #[inline] + fn eq(&self, other: &TransactionStatus) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionStatus::Broadcasted { num_peers: __self_0 }, + TransactionStatus::Broadcasted { num_peers: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::InBestBlock { hash: __self_0 }, + TransactionStatus::InBestBlock { hash: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::InFinalizedBlock { hash: __self_0 }, + TransactionStatus::InFinalizedBlock { hash: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Error { message: __self_0 }, + TransactionStatus::Error { message: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Invalid { message: __self_0 }, + TransactionStatus::Invalid { message: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + ( + TransactionStatus::Dropped { message: __self_0 }, + TransactionStatus::Dropped { message: __arg1_0 }, + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TransactionStatus { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + } + } + /// A response from calls like [`Backend::storage_fetch_values`] or + /// [`Backend::storage_fetch_descendant_values`]. + pub struct StorageResponse { + /// The key. + pub key: Vec, + /// The associated value. + pub value: Vec, + } +} +pub mod blocks { + //! This module exposes the necessary functionality for working with events. + mod block_types { + use crate::{ + backend::BlockRef, + blocks::{extrinsic_types::ExtrinsicPartTypeIds, Extrinsics}, + client::{OfflineClientT, OnlineClientT}, + config::{Config, Header}, + error::{BlockError, DecodeError, Error}, + events, runtime_api::RuntimeApi, storage::Storage, + }; + use codec::{Decode, Encode}; + use futures::lock::Mutex as AsyncMutex; + use std::sync::Arc; + /// A representation of a block. + pub struct Block { + header: T::Header, + block_ref: BlockRef, + client: C, + cached_events: CachedEvents, + } + pub(crate) type CachedEvents = Arc>>>; + impl Block + where + T: Config, + C: OfflineClientT, + { + pub(crate) fn new( + header: T::Header, + block_ref: BlockRef, + client: C, + ) -> Self { + Block { + header, + block_ref, + client, + cached_events: Default::default(), + } + } + /// Return a reference to the given block. While this reference is kept alive, + /// the backend will (if possible) endeavour to keep hold of the block. + pub fn reference(&self) -> BlockRef { + self.block_ref.clone() + } + /// Return the block hash. + pub fn hash(&self) -> T::Hash { + self.block_ref.hash() + } + /// Return the block number. + pub fn number(&self) -> ::Number { + self.header().number() + } + /// Return the entire block header. + pub fn header(&self) -> &T::Header { + &self.header + } + } + impl Block + where + T: Config, + C: OnlineClientT, + { + /// Return the events associated with the block, fetching them from the node if necessary. + pub async fn events(&self) -> Result, Error> { + get_events(&self.client, self.header.hash(), &self.cached_events).await + } + /// Fetch and return the extrinsics in the block body. + pub async fn extrinsics(&self) -> Result, Error> { + let ids = ExtrinsicPartTypeIds::new(&self.client.metadata())?; + let block_hash = self.header.hash(); + let Some(extrinsics) = self + .client + .backend() + .block_body(block_hash) + .await? else { return Err(BlockError::not_found(block_hash).into()); + }; + Ok( + Extrinsics::new( + self.client.clone(), + extrinsics, + self.cached_events.clone(), + ids, + block_hash, + ), + ) + } + /// Work with storage. + pub fn storage(&self) -> Storage { + Storage::new(self.client.clone(), self.block_ref.clone()) + } + /// Execute a runtime API call at this block. + pub async fn runtime_api(&self) -> Result, Error> { + Ok(RuntimeApi::new(self.client.clone(), self.block_ref.clone())) + } + /// Get the account nonce for a given account ID at this block. + pub async fn account_nonce( + &self, + account_id: &T::AccountId, + ) -> Result { + get_account_nonce(&self.client, account_id, self.hash()).await + } + } + pub(crate) async fn get_events( + client: &C, + block_hash: T::Hash, + cached_events: &AsyncMutex>>, + ) -> Result, Error> + where + T: Config, + C: OnlineClientT, + { + let mut lock = cached_events.lock().await; + let events = match &*lock { + Some(events) => events.clone(), + None => { + let events = events::EventsClient::new(client.clone()) + .at(block_hash) + .await?; + lock.replace(events.clone()); + events + } + }; + Ok(events) + } + pub(crate) async fn get_account_nonce( + client: &C, + account_id: &T::AccountId, + block_hash: T::Hash, + ) -> Result + where + C: OnlineClientT, + T: Config, + { + let account_nonce_bytes = client + .backend() + .call( + "AccountNonceApi_account_nonce", + Some(&account_id.encode()), + block_hash, + ) + .await?; + let cursor = &mut &account_nonce_bytes[..]; + let account_nonce: u64 = match account_nonce_bytes.len() { + 2 => u16::decode(cursor)?.into(), + 4 => u32::decode(cursor)?.into(), + 8 => u64::decode(cursor)?, + _ => { + return Err( + Error::Decode( + DecodeError::custom_string({ + let res = ::alloc::fmt::format( + format_args!( + "state call AccountNonceApi_account_nonce returned an unexpected number of bytes: {0} (expected 2, 4 or 8)", + account_nonce_bytes.len() + ), + ); + res + }), + ), + ); + } + }; + Ok(account_nonce) + } + } + mod blocks_client { + use super::Block; + use crate::{ + backend::{BlockRef, StreamOfResults}, + client::OnlineClientT, config::Config, error::{BlockError, Error}, + utils::PhantomDataSendSync, + }; + use derivative::Derivative; + use futures::StreamExt; + use std::future::Future; + type BlockStream = StreamOfResults; + type BlockStreamRes = Result, Error>; + /// A client for working with blocks. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct BlocksClient { + client: Client, + _marker: PhantomDataSendSync, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for BlocksClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + BlocksClient { client: ref __arg_0, _marker: ref __arg_1 } => { + BlocksClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl BlocksClient { + /// Create a new [`BlocksClient`]. + pub fn new(client: Client) -> Self { + Self { + client, + _marker: PhantomDataSendSync::new(), + } + } + } + impl BlocksClient + where + T: Config, + Client: OnlineClientT, + { + /// Obtain block details given the provided block hash. + /// + /// # Warning + /// + /// This call only supports blocks produced since the most recent + /// runtime upgrade. You can attempt to retrieve older blocks, + /// but may run into errors attempting to work with them. + pub fn at( + &self, + block_ref: impl Into>, + ) -> impl Future, Error>> + Send + 'static { + self.at_or_latest(Some(block_ref.into())) + } + /// Obtain block details of the latest block hash. + pub fn at_latest( + &self, + ) -> impl Future, Error>> + Send + 'static { + self.at_or_latest(None) + } + /// Obtain block details given the provided block hash, or the latest block if `None` is + /// provided. + fn at_or_latest( + &self, + block_ref: Option>, + ) -> impl Future, Error>> + Send + 'static { + let client = self.client.clone(); + async move { + let block_ref = match block_ref { + Some(r) => r, + None => client.backend().latest_finalized_block_ref().await?, + }; + let block_header = match client + .backend() + .block_header(block_ref.hash()) + .await? + { + Some(header) => header, + None => { + return Err(BlockError::not_found(block_ref.hash()).into()); + } + }; + Ok(Block::new(block_header, block_ref, client)) + } + } + /// Subscribe to all new blocks imported by the node. + /// + /// **Note:** You probably want to use [`Self::subscribe_finalized()`] most of + /// the time. + pub fn subscribe_all( + &self, + ) -> impl Future< + Output = Result>, Error>, + > + Send + 'static + where + Client: Send + Sync + 'static, + { + let client = self.client.clone(); + header_sub_fut_to_block_sub( + self.clone(), + async move { + let sub = client.backend().stream_all_block_headers().await?; + BlockStreamRes::Ok(sub) + }, + ) + } + /// Subscribe to all new blocks imported by the node onto the current best fork. + /// + /// **Note:** You probably want to use [`Self::subscribe_finalized()`] most of + /// the time. + pub fn subscribe_best( + &self, + ) -> impl Future< + Output = Result>, Error>, + > + Send + 'static + where + Client: Send + Sync + 'static, + { + let client = self.client.clone(); + header_sub_fut_to_block_sub( + self.clone(), + async move { + let sub = client.backend().stream_best_block_headers().await?; + BlockStreamRes::Ok(sub) + }, + ) + } + /// Subscribe to finalized blocks. + pub fn subscribe_finalized( + &self, + ) -> impl Future< + Output = Result>, Error>, + > + Send + 'static + where + Client: Send + Sync + 'static, + { + let client = self.client.clone(); + header_sub_fut_to_block_sub( + self.clone(), + async move { + let sub = client + .backend() + .stream_finalized_block_headers() + .await?; + BlockStreamRes::Ok(sub) + }, + ) + } + } + /// Take a promise that will return a subscription to some block headers, + /// and return a subscription to some blocks based on this. + async fn header_sub_fut_to_block_sub( + blocks_client: BlocksClient, + sub: S, + ) -> Result>, Error> + where + T: Config, + S: Future< + Output = Result)>, Error>, + > + Send + 'static, + Client: OnlineClientT + Send + Sync + 'static, + { + let sub = sub + .await? + .then(move |header_and_ref| { + let client = blocks_client.client.clone(); + async move { + let (header, block_ref) = match header_and_ref { + Ok(header_and_ref) => header_and_ref, + Err(e) => return Err(e), + }; + Ok(Block::new(header, block_ref, client)) + } + }); + BlockStreamRes::Ok(StreamOfResults::new(Box::pin(sub))) + } + } + mod extrinsic_types { + use crate::{ + blocks::block_types::{get_events, CachedEvents}, + client::{OfflineClientT, OnlineClientT}, + config::{Config, Hasher}, + error::{BlockError, Error, MetadataError}, + events, metadata::types::PalletMetadata, Metadata, + }; + use crate::config::signed_extensions::{ + ChargeAssetTxPayment, ChargeTransactionPayment, CheckNonce, + }; + use crate::config::SignedExtension; + use crate::dynamic::DecodedValue; + use crate::utils::strip_compact_prefix; + use codec::Decode; + use derivative::Derivative; + use scale_decode::{DecodeAsFields, DecodeAsType}; + use std::sync::Arc; + /// Trait to uniquely identify the extrinsic's identity from the runtime metadata. + /// + /// Generated API structures that represent an extrinsic implement this trait. + /// + /// The trait is utilized to decode emitted extrinsics from a block, via obtaining the + /// form of the `Extrinsic` from the metadata. + pub trait StaticExtrinsic: DecodeAsFields { + /// Pallet name. + const PALLET: &'static str; + /// Call name. + const CALL: &'static str; + /// Returns true if the given pallet and call names match this extrinsic. + fn is_extrinsic(pallet: &str, call: &str) -> bool { + Self::PALLET == pallet && Self::CALL == call + } + } + /// The body of a block. + pub struct Extrinsics { + client: C, + extrinsics: Vec>, + cached_events: CachedEvents, + ids: ExtrinsicPartTypeIds, + hash: T::Hash, + } + impl Extrinsics + where + T: Config, + C: OfflineClientT, + { + pub(crate) fn new( + client: C, + extrinsics: Vec>, + cached_events: CachedEvents, + ids: ExtrinsicPartTypeIds, + hash: T::Hash, + ) -> Self { + Self { + client, + extrinsics, + cached_events, + ids, + hash, + } + } + /// The number of extrinsics. + pub fn len(&self) -> usize { + self.extrinsics.len() + } + /// Are there no extrinsics in this block? + pub fn is_empty(&self) -> bool { + self.extrinsics.is_empty() + } + /// Return the block hash that these extrinsics are from. + pub fn block_hash(&self) -> T::Hash { + self.hash + } + /// Returns an iterator over the extrinsics in the block body. + pub fn iter( + &self, + ) -> impl Iterator< + Item = Result, Error>, + > + Send + Sync + 'static { + let extrinsics = self.extrinsics.clone(); + let num_extrinsics = self.extrinsics.len(); + let client = self.client.clone(); + let hash = self.hash; + let cached_events = self.cached_events.clone(); + let ids = self.ids; + let mut index = 0; + std::iter::from_fn(move || { + if index == num_extrinsics { + None + } else { + match ExtrinsicDetails::decode_from( + index as u32, + &extrinsics[index], + client.clone(), + hash, + cached_events.clone(), + ids, + ) { + Ok(extrinsic_details) => { + index += 1; + Some(Ok(extrinsic_details)) + } + Err(e) => { + index = num_extrinsics; + Some(Err(e)) + } + } + } + }) + } + /// Iterate through the extrinsics using metadata to dynamically decode and skip + /// them, and return only those which should decode to the provided `E` type. + /// If an error occurs, all subsequent iterations return `None`. + pub fn find( + &self, + ) -> impl Iterator, Error>> + '_ { + self.iter() + .filter_map(|res| match res { + Err(err) => Some(Err(err)), + Ok(details) => { + match details.as_extrinsic::() { + Err(err) => Some(Err(err)), + Ok(None) => None, + Ok(Some(value)) => { + Some(Ok(FoundExtrinsic { details, value })) + } + } + } + }) + } + /// Iterate through the extrinsics using metadata to dynamically decode and skip + /// them, and return the first extrinsic found which decodes to the provided `E` type. + pub fn find_first( + &self, + ) -> Result>, Error> { + self.find::().next().transpose() + } + /// Iterate through the extrinsics using metadata to dynamically decode and skip + /// them, and return the last extrinsic found which decodes to the provided `Ev` type. + pub fn find_last( + &self, + ) -> Result>, Error> { + self.find::().last().transpose() + } + /// Find an extrinsics that decodes to the type provided. Returns true if it was found. + pub fn has(&self) -> Result { + Ok(self.find::().next().transpose()?.is_some()) + } + } + /// A single extrinsic in a block. + pub struct ExtrinsicDetails { + /// The index of the extrinsic in the block. + index: u32, + /// Extrinsic bytes. + bytes: Arc<[u8]>, + /// Some if the extrinsic payload is signed. + signed_details: Option, + /// The start index in the `bytes` from which the call is encoded. + call_start_idx: usize, + /// The pallet index. + pallet_index: u8, + /// The variant index. + variant_index: u8, + /// The block hash of this extrinsic (needed to fetch events). + block_hash: T::Hash, + /// Subxt client. + client: C, + /// Cached events. + cached_events: CachedEvents, + /// Subxt metadata to fetch the extrinsic metadata. + metadata: Metadata, + _marker: std::marker::PhantomData, + } + /// Details only available in signed extrinsics. + pub struct SignedExtrinsicDetails { + /// start index of the range in `bytes` of `ExtrinsicDetails` that encodes the address. + address_start_idx: usize, + /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the address. Equivalent to signature_start_idx. + address_end_idx: usize, + /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the signature. Equivalent to extra_start_idx. + signature_end_idx: usize, + /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the signature. + extra_end_idx: usize, + } + impl ExtrinsicDetails + where + T: Config, + C: OfflineClientT, + { + pub(crate) fn decode_from( + index: u32, + extrinsic_bytes: &[u8], + client: C, + block_hash: T::Hash, + cached_events: CachedEvents, + ids: ExtrinsicPartTypeIds, + ) -> Result, Error> { + const SIGNATURE_MASK: u8 = 0b1000_0000; + const VERSION_MASK: u8 = 0b0111_1111; + const LATEST_EXTRINSIC_VERSION: u8 = 4; + let metadata = client.metadata(); + let bytes: Arc<[u8]> = strip_compact_prefix(extrinsic_bytes)?.1.into(); + let first_byte: u8 = Decode::decode(&mut &bytes[..])?; + let version = first_byte & VERSION_MASK; + if version != LATEST_EXTRINSIC_VERSION { + return Err(BlockError::UnsupportedVersion(version).into()); + } + let is_signed = first_byte & SIGNATURE_MASK != 0; + let cursor = &mut &bytes[1..]; + let signed_details = is_signed + .then(|| -> Result { + let address_start_idx = bytes.len() - cursor.len(); + scale_decode::visitor::decode_with_visitor( + cursor, + ids.address, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(scale_decode::Error::from)?; + let address_end_idx = bytes.len() - cursor.len(); + scale_decode::visitor::decode_with_visitor( + cursor, + ids.signature, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(scale_decode::Error::from)?; + let signature_end_idx = bytes.len() - cursor.len(); + scale_decode::visitor::decode_with_visitor( + cursor, + ids.extra, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(scale_decode::Error::from)?; + let extra_end_idx = bytes.len() - cursor.len(); + Ok(SignedExtrinsicDetails { + address_start_idx, + address_end_idx, + signature_end_idx, + extra_end_idx, + }) + }) + .transpose()?; + let call_start_idx = bytes.len() - cursor.len(); + let cursor = &mut &bytes[call_start_idx..]; + let pallet_index: u8 = Decode::decode(cursor)?; + let variant_index: u8 = Decode::decode(cursor)?; + Ok(ExtrinsicDetails { + index, + bytes, + signed_details, + call_start_idx, + pallet_index, + variant_index, + block_hash, + client, + cached_events, + metadata, + _marker: std::marker::PhantomData, + }) + } + /// Is the extrinsic signed? + pub fn is_signed(&self) -> bool { + self.signed_details.is_some() + } + /// The index of the extrinsic in the block. + pub fn index(&self) -> u32 { + self.index + } + /// Return _all_ of the bytes representing this extrinsic, which include, in order: + /// - First byte: abbbbbbb (a = 0 for unsigned, 1 for signed, b = version) + /// - SignatureType (if the payload is signed) + /// - Address + /// - Signature + /// - Extra fields + /// - Extrinsic call bytes + pub fn bytes(&self) -> &[u8] { + &self.bytes + } + /// Return only the bytes representing this extrinsic call: + /// - First byte is the pallet index + /// - Second byte is the variant (call) index + /// - Followed by field bytes. + /// + /// # Note + /// + /// Please use [`Self::bytes`] if you want to get all extrinsic bytes. + pub fn call_bytes(&self) -> &[u8] { + &self.bytes[self.call_start_idx..] + } + /// Return the bytes representing the fields stored in this extrinsic. + /// + /// # Note + /// + /// This is a subset of [`Self::call_bytes`] that does not include the + /// first two bytes that denote the pallet index and the variant index. + pub fn field_bytes(&self) -> &[u8] { + &self.call_bytes()[2..] + } + /// Return only the bytes of the address that signed this extrinsic. + /// + /// # Note + /// + /// Returns `None` if the extrinsic is not signed. + pub fn address_bytes(&self) -> Option<&[u8]> { + self.signed_details + .as_ref() + .map(|e| &self.bytes[e.address_start_idx..e.address_end_idx]) + } + /// Returns Some(signature_bytes) if the extrinsic was signed otherwise None is returned. + pub fn signature_bytes(&self) -> Option<&[u8]> { + self.signed_details + .as_ref() + .map(|e| &self.bytes[e.address_end_idx..e.signature_end_idx]) + } + /// Returns the signed extension `extra` bytes of the extrinsic. + /// Each signed extension has an `extra` type (May be zero-sized). + /// These bytes are the scale encoded `extra` fields of each signed extension in order of the signed extensions. + /// They do *not* include the `additional` signed bytes that are used as part of the payload that is signed. + /// + /// Note: Returns `None` if the extrinsic is not signed. + pub fn signed_extensions_bytes(&self) -> Option<&[u8]> { + self.signed_details + .as_ref() + .map(|e| &self.bytes[e.signature_end_idx..e.extra_end_idx]) + } + /// Returns `None` if the extrinsic is not signed. + pub fn signed_extensions(&self) -> Option> { + let signed = self.signed_details.as_ref()?; + let extra_bytes = &self + .bytes[signed.signature_end_idx..signed.extra_end_idx]; + Some(ExtrinsicSignedExtensions { + bytes: extra_bytes, + metadata: &self.metadata, + _marker: std::marker::PhantomData, + }) + } + /// The index of the pallet that the extrinsic originated from. + pub fn pallet_index(&self) -> u8 { + self.pallet_index + } + /// The index of the extrinsic variant that the extrinsic originated from. + pub fn variant_index(&self) -> u8 { + self.variant_index + } + /// The name of the pallet from whence the extrinsic originated. + pub fn pallet_name(&self) -> Result<&str, Error> { + Ok(self.extrinsic_metadata()?.pallet.name()) + } + /// The name of the call (ie the name of the variant that it corresponds to). + pub fn variant_name(&self) -> Result<&str, Error> { + Ok(&self.extrinsic_metadata()?.variant.name) + } + /// Fetch the metadata for this extrinsic. + pub fn extrinsic_metadata(&self) -> Result { + let pallet = self.metadata.pallet_by_index_err(self.pallet_index())?; + let variant = pallet + .call_variant_by_index(self.variant_index()) + .ok_or_else(|| MetadataError::VariantIndexNotFound( + self.variant_index(), + ))?; + Ok(ExtrinsicMetadataDetails { + pallet, + variant, + }) + } + /// Decode and provide the extrinsic fields back in the form of a [`scale_value::Composite`] + /// type which represents the named or unnamed fields that were present in the extrinsic. + pub fn field_values( + &self, + ) -> Result, Error> { + let bytes = &mut self.field_bytes(); + let extrinsic_metadata = self.extrinsic_metadata()?; + let mut fields = extrinsic_metadata + .variant + .fields + .iter() + .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); + let decoded = >::decode_as_fields(bytes, &mut fields, self.metadata.types())?; + Ok(decoded) + } + /// Attempt to decode these [`ExtrinsicDetails`] into a type representing the extrinsic fields. + /// Such types are exposed in the codegen as `pallet_name::calls::types::CallName` types. + pub fn as_extrinsic(&self) -> Result, Error> { + let extrinsic_metadata = self.extrinsic_metadata()?; + if extrinsic_metadata.pallet.name() == E::PALLET + && extrinsic_metadata.variant.name == E::CALL + { + let mut fields = extrinsic_metadata + .variant + .fields + .iter() + .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); + let decoded = E::decode_as_fields( + &mut self.field_bytes(), + &mut fields, + self.metadata.types(), + )?; + Ok(Some(decoded)) + } else { + Ok(None) + } + } + /// Attempt to decode these [`ExtrinsicDetails`] into an outer call enum type (which includes + /// the pallet and extrinsic enum variants as well as the extrinsic fields). A compatible + /// type for this is exposed via static codegen as a root level `Call` type. + pub fn as_root_extrinsic(&self) -> Result { + let decoded = E::decode_as_type( + &mut &self.call_bytes()[..], + self.metadata.outer_enums().call_enum_ty(), + self.metadata.types(), + )?; + Ok(decoded) + } + } + impl ExtrinsicDetails + where + T: Config, + C: OnlineClientT, + { + /// The events associated with the extrinsic. + pub async fn events(&self) -> Result, Error> { + let events = get_events( + &self.client, + self.block_hash, + &self.cached_events, + ) + .await?; + let ext_hash = T::Hasher::hash_of(&self.bytes); + Ok(ExtrinsicEvents::new(ext_hash, self.index, events)) + } + } + /// A Static Extrinsic found in a block coupled with it's details. + pub struct FoundExtrinsic { + pub details: ExtrinsicDetails, + pub value: E, + } + /// Details for the given extrinsic plucked from the metadata. + pub struct ExtrinsicMetadataDetails<'a> { + pub pallet: PalletMetadata<'a>, + pub variant: &'a scale_info::Variant, + } + /// The type IDs extracted from the metadata that represent the + /// generic type parameters passed to the `UncheckedExtrinsic` from + /// the substrate-based chain. + pub(crate) struct ExtrinsicPartTypeIds { + /// The address (source) of the extrinsic. + address: u32, + /// The extrinsic call type. + _call: u32, + /// The signature of the extrinsic. + signature: u32, + /// The extra parameters of the extrinsic. + extra: u32, + } + #[automatically_derived] + impl ::core::fmt::Debug for ExtrinsicPartTypeIds { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field4_finish( + f, + "ExtrinsicPartTypeIds", + "address", + &self.address, + "_call", + &self._call, + "signature", + &self.signature, + "extra", + &&self.extra, + ) + } + } + #[automatically_derived] + impl ::core::marker::Copy for ExtrinsicPartTypeIds {} + #[automatically_derived] + impl ::core::clone::Clone for ExtrinsicPartTypeIds { + #[inline] + fn clone(&self) -> ExtrinsicPartTypeIds { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + impl ExtrinsicPartTypeIds { + /// Extract the generic type parameters IDs from the extrinsic type. + pub(crate) fn new(metadata: &Metadata) -> Result { + Ok(ExtrinsicPartTypeIds { + address: metadata.extrinsic().address_ty(), + _call: metadata.extrinsic().call_ty(), + signature: metadata.extrinsic().signature_ty(), + extra: metadata.extrinsic().extra_ty(), + }) + } + } + /// The events associated with a given extrinsic. + #[derivative(Debug(bound = ""))] + pub struct ExtrinsicEvents { + ext_hash: T::Hash, + idx: u32, + events: events::Events, + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for ExtrinsicEvents { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + ExtrinsicEvents { + ext_hash: ref __arg_0, + idx: ref __arg_1, + events: ref __arg_2, + } => { + let mut __debug_trait_builder = __f + .debug_struct("ExtrinsicEvents"); + let _ = __debug_trait_builder.field("ext_hash", &&(*__arg_0)); + let _ = __debug_trait_builder.field("idx", &&(*__arg_1)); + let _ = __debug_trait_builder.field("events", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + impl ExtrinsicEvents { + pub(crate) fn new( + ext_hash: T::Hash, + idx: u32, + events: events::Events, + ) -> Self { + Self { ext_hash, idx, events } + } + /// Return the hash of the block that the extrinsic is in. + pub fn block_hash(&self) -> T::Hash { + self.events.block_hash() + } + /// The index of the extrinsic that these events are produced from. + pub fn extrinsic_index(&self) -> u32 { + self.idx + } + /// Return the hash of the extrinsic. + pub fn extrinsic_hash(&self) -> T::Hash { + self.ext_hash + } + /// Return all of the events in the block that the extrinsic is in. + pub fn all_events_in_block(&self) -> &events::Events { + &self.events + } + /// Iterate over all of the raw events associated with this transaction. + /// + /// This works in the same way that [`events::Events::iter()`] does, with the + /// exception that it filters out events not related to the submitted extrinsic. + pub fn iter( + &self, + ) -> impl Iterator, Error>> + '_ { + self.events + .iter() + .filter(|ev| { + ev.as_ref() + .map(|ev| { + ev.phase() == events::Phase::ApplyExtrinsic(self.idx) + }) + .unwrap_or(true) + }) + } + /// Find all of the transaction events matching the event type provided as a generic parameter. + /// + /// This works in the same way that [`events::Events::find()`] does, with the + /// exception that it filters out events not related to the submitted extrinsic. + pub fn find( + &self, + ) -> impl Iterator> + '_ { + self.iter() + .filter_map(|ev| { + ev.and_then(|ev| ev.as_event::().map_err(Into::into)) + .transpose() + }) + } + /// Iterate through the transaction events using metadata to dynamically decode and skip + /// them, and return the first event found which decodes to the provided `Ev` type. + /// + /// This works in the same way that [`events::Events::find_first()`] does, with the + /// exception that it ignores events not related to the submitted extrinsic. + pub fn find_first( + &self, + ) -> Result, Error> { + self.find::().next().transpose() + } + /// Iterate through the transaction events using metadata to dynamically decode and skip + /// them, and return the last event found which decodes to the provided `Ev` type. + /// + /// This works in the same way that [`events::Events::find_last()`] does, with the + /// exception that it ignores events not related to the submitted extrinsic. + pub fn find_last( + &self, + ) -> Result, Error> { + self.find::().last().transpose() + } + /// Find an event in those associated with this transaction. Returns true if it was found. + /// + /// This works in the same way that [`events::Events::has()`] does, with the + /// exception that it ignores events not related to the submitted extrinsic. + pub fn has(&self) -> Result { + Ok(self.find::().next().transpose()?.is_some()) + } + } + /// The signed extensions of an extrinsic. + pub struct ExtrinsicSignedExtensions<'a, T: Config> { + bytes: &'a [u8], + metadata: &'a Metadata, + _marker: std::marker::PhantomData, + } + #[automatically_derived] + impl<'a, T: ::core::fmt::Debug + Config> ::core::fmt::Debug + for ExtrinsicSignedExtensions<'a, T> { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "ExtrinsicSignedExtensions", + "bytes", + &self.bytes, + "metadata", + &self.metadata, + "_marker", + &&self._marker, + ) + } + } + #[automatically_derived] + impl<'a, T: ::core::clone::Clone + Config> ::core::clone::Clone + for ExtrinsicSignedExtensions<'a, T> { + #[inline] + fn clone(&self) -> ExtrinsicSignedExtensions<'a, T> { + ExtrinsicSignedExtensions { + bytes: ::core::clone::Clone::clone(&self.bytes), + metadata: ::core::clone::Clone::clone(&self.metadata), + _marker: ::core::clone::Clone::clone(&self._marker), + } + } + } + impl<'a, T: Config> ExtrinsicSignedExtensions<'a, T> { + /// Returns an iterator over each of the signed extension details of the extrinsic. + /// If the decoding of any signed extension fails, an error item is yielded and the iterator stops. + pub fn iter( + &self, + ) -> impl Iterator, Error>> { + let signed_extension_types = self + .metadata + .extrinsic() + .signed_extensions(); + let num_signed_extensions = signed_extension_types.len(); + let bytes = self.bytes; + let mut index = 0; + let mut byte_start_idx = 0; + let metadata = &self.metadata; + std::iter::from_fn(move || { + if index == num_signed_extensions { + return None; + } + let extension = &signed_extension_types[index]; + let ty_id = extension.extra_ty(); + let cursor = &mut &bytes[byte_start_idx..]; + if let Err(err) + = scale_decode::visitor::decode_with_visitor( + cursor, + ty_id, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(|e| Error::Decode(e.into())) + { + index = num_signed_extensions; + return Some(Err(err)); + } + let byte_end_idx = bytes.len() - cursor.len(); + let bytes = &bytes[byte_start_idx..byte_end_idx]; + byte_start_idx = byte_end_idx; + index += 1; + Some( + Ok(ExtrinsicSignedExtension { + bytes, + ty_id, + identifier: extension.identifier(), + metadata, + _marker: std::marker::PhantomData, + }), + ) + }) + } + /// Searches through all signed extensions to find a specific one. + /// If the Signed Extension is not found `Ok(None)` is returned. + /// If the Signed Extension is found but decoding failed `Err(_)` is returned. + pub fn find>( + &self, + ) -> Result, Error> { + for ext in self.iter() { + let ext = ext?; + match ext.as_signed_extension::() { + Ok(Some(e)) => return Ok(Some(e)), + Ok(None) => continue, + Err(e) => return Err(e), + } + } + Ok(None) + } + /// The tip of an extrinsic, extracted from the ChargeTransactionPayment or ChargeAssetTxPayment + /// signed extension, depending on which is present. + /// + /// Returns `None` if `tip` was not found or decoding failed. + pub fn tip(&self) -> Option { + self.find::() + .ok() + .flatten() + .map(|e| e.tip()) + .or_else(|| { + self.find::>() + .ok() + .flatten() + .map(|e| e.tip()) + }) + } + /// The nonce of the account that submitted the extrinsic, extracted from the CheckNonce signed extension. + /// + /// Returns `None` if `nonce` was not found or decoding failed. + pub fn nonce(&self) -> Option { + self.find::().ok()? + } + } + /// A single signed extension + pub struct ExtrinsicSignedExtension<'a, T: Config> { + bytes: &'a [u8], + ty_id: u32, + identifier: &'a str, + metadata: &'a Metadata, + _marker: std::marker::PhantomData, + } + #[automatically_derived] + impl<'a, T: ::core::fmt::Debug + Config> ::core::fmt::Debug + for ExtrinsicSignedExtension<'a, T> { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "ExtrinsicSignedExtension", + "bytes", + &self.bytes, + "ty_id", + &self.ty_id, + "identifier", + &self.identifier, + "metadata", + &self.metadata, + "_marker", + &&self._marker, + ) + } + } + #[automatically_derived] + impl<'a, T: ::core::clone::Clone + Config> ::core::clone::Clone + for ExtrinsicSignedExtension<'a, T> { + #[inline] + fn clone(&self) -> ExtrinsicSignedExtension<'a, T> { + ExtrinsicSignedExtension { + bytes: ::core::clone::Clone::clone(&self.bytes), + ty_id: ::core::clone::Clone::clone(&self.ty_id), + identifier: ::core::clone::Clone::clone(&self.identifier), + metadata: ::core::clone::Clone::clone(&self.metadata), + _marker: ::core::clone::Clone::clone(&self._marker), + } + } + } + impl<'a, T: Config> ExtrinsicSignedExtension<'a, T> { + /// The bytes representing this signed extension. + pub fn bytes(&self) -> &'a [u8] { + self.bytes + } + /// The name of the signed extension. + pub fn name(&self) -> &'a str { + self.identifier + } + /// The type id of the signed extension. + pub fn type_id(&self) -> u32 { + self.ty_id + } + /// Signed Extension as a [`scale_value::Value`] + pub fn value(&self) -> Result { + self.as_type() + } + /// Decodes the bytes of this Signed Extension into its associated `Decoded` type. + /// Returns `Ok(None)` if the data we have doesn't match the Signed Extension we're asking to + /// decode with. + pub fn as_signed_extension>( + &self, + ) -> Result, Error> { + if !S::matches(self.identifier, self.ty_id, self.metadata.types()) { + return Ok(None); + } + self.as_type::().map(Some) + } + fn as_type(&self) -> Result { + let value = E::decode_as_type( + &mut &self.bytes[..], + self.ty_id, + self.metadata.types(), + )?; + Ok(value) + } + } + } + /// A reference to a block. + pub use crate::backend::BlockRef; + pub use block_types::Block; + pub use blocks_client::BlocksClient; + pub use extrinsic_types::{ + ExtrinsicDetails, ExtrinsicEvents, ExtrinsicSignedExtension, + ExtrinsicSignedExtensions, Extrinsics, StaticExtrinsic, + }; + pub(crate) use block_types::get_account_nonce; +} +pub mod client { + //! This module provides two clients that can be used to work with + //! transactions, storage and events. The [`OfflineClient`] works + //! entirely offline and can be passed to any function that doesn't + //! require network access. The [`OnlineClient`] requires network + //! access. + mod offline_client { + use crate::custom_values::CustomValuesClient; + use crate::{ + backend::RuntimeVersion, blocks::BlocksClient, constants::ConstantsClient, + events::EventsClient, runtime_api::RuntimeApiClient, storage::StorageClient, + tx::TxClient, Config, Metadata, + }; + use derivative::Derivative; + use std::sync::Arc; + /// A trait representing a client that can perform + /// offline-only actions. + pub trait OfflineClientT: Clone + Send + Sync + 'static { + /// Return the provided [`Metadata`]. + fn metadata(&self) -> Metadata; + /// Return the provided genesis hash. + fn genesis_hash(&self) -> T::Hash; + /// Return the provided [`RuntimeVersion`]. + fn runtime_version(&self) -> RuntimeVersion; + /// Work with transactions. + fn tx(&self) -> TxClient { + TxClient::new(self.clone()) + } + /// Work with events. + fn events(&self) -> EventsClient { + EventsClient::new(self.clone()) + } + /// Work with storage. + fn storage(&self) -> StorageClient { + StorageClient::new(self.clone()) + } + /// Access constants. + fn constants(&self) -> ConstantsClient { + ConstantsClient::new(self.clone()) + } + /// Work with blocks. + fn blocks(&self) -> BlocksClient { + BlocksClient::new(self.clone()) + } + /// Work with runtime API. + fn runtime_api(&self) -> RuntimeApiClient { + RuntimeApiClient::new(self.clone()) + } + /// Work this custom types. + fn custom_values(&self) -> CustomValuesClient { + CustomValuesClient::new(self.clone()) + } + } + /// A client that is capable of performing offline-only operations. + /// Can be constructed as long as you can populate the required fields. + #[derivative(Debug(bound = ""), Clone(bound = ""))] + pub struct OfflineClient { + inner: Arc>, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for OfflineClient { + fn clone(&self) -> Self { + match *self { + OfflineClient { inner: ref __arg_0 } => { + OfflineClient { + inner: (*__arg_0).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for OfflineClient { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + OfflineClient { inner: ref __arg_0 } => { + let mut __debug_trait_builder = __f + .debug_struct("OfflineClient"); + let _ = __debug_trait_builder.field("inner", &&(*__arg_0)); + __debug_trait_builder.finish() + } + } + } + } + #[derivative(Debug(bound = ""), Clone(bound = ""))] + struct Inner { + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: Metadata, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Inner { + fn clone(&self) -> Self { + match *self { + Inner { + genesis_hash: ref __arg_0, + runtime_version: ref __arg_1, + metadata: ref __arg_2, + } => { + Inner { + genesis_hash: (*__arg_0).clone(), + runtime_version: (*__arg_1).clone(), + metadata: (*__arg_2).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Inner { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Inner { + genesis_hash: ref __arg_0, + runtime_version: ref __arg_1, + metadata: ref __arg_2, + } => { + let mut __debug_trait_builder = __f.debug_struct("Inner"); + let _ = __debug_trait_builder + .field("genesis_hash", &&(*__arg_0)); + let _ = __debug_trait_builder + .field("runtime_version", &&(*__arg_1)); + let _ = __debug_trait_builder.field("metadata", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + impl OfflineClient { + /// Construct a new [`OfflineClient`], providing + /// the necessary runtime and compile-time arguments. + pub fn new( + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: impl Into, + ) -> OfflineClient { + OfflineClient { + inner: Arc::new(Inner { + genesis_hash, + runtime_version, + metadata: metadata.into(), + }), + } + } + /// Return the genesis hash. + pub fn genesis_hash(&self) -> T::Hash { + self.inner.genesis_hash + } + /// Return the runtime version. + pub fn runtime_version(&self) -> RuntimeVersion { + self.inner.runtime_version.clone() + } + /// Return the [`Metadata`] used in this client. + pub fn metadata(&self) -> Metadata { + self.inner.metadata.clone() + } + /// Work with transactions. + pub fn tx(&self) -> TxClient { + >::tx(self) + } + /// Work with events. + pub fn events(&self) -> EventsClient { + >::events(self) + } + /// Work with storage. + pub fn storage(&self) -> StorageClient { + >::storage(self) + } + /// Access constants. + pub fn constants(&self) -> ConstantsClient { + >::constants(self) + } + /// Access custom types + pub fn custom_values(&self) -> CustomValuesClient { + >::custom_values(self) + } + } + impl OfflineClientT for OfflineClient { + fn genesis_hash(&self) -> T::Hash { + self.genesis_hash() + } + fn runtime_version(&self) -> RuntimeVersion { + self.runtime_version() + } + fn metadata(&self) -> Metadata { + self.metadata() + } + } + impl<'a, T: Config> From<&'a OfflineClient> for OfflineClient { + fn from(c: &'a OfflineClient) -> Self { + c.clone() + } + } + } + mod online_client { + use super::{OfflineClient, OfflineClientT}; + use crate::custom_values::CustomValuesClient; + use crate::{ + backend::{ + legacy::LegacyBackend, rpc::RpcClient, Backend, BackendExt, + RuntimeVersion, StreamOfResults, + }, + blocks::{BlockRef, BlocksClient}, + constants::ConstantsClient, error::Error, events::EventsClient, + runtime_api::RuntimeApiClient, storage::StorageClient, tx::TxClient, Config, + Metadata, + }; + use derivative::Derivative; + use futures::future; + use std::sync::{Arc, RwLock}; + /// A trait representing a client that can perform + /// online actions. + pub trait OnlineClientT: OfflineClientT { + /// Return a backend that can be used to communicate with a node. + fn backend(&self) -> &dyn Backend; + } + /// A client that can be used to perform API calls (that is, either those + /// requiring an [`OfflineClientT`] or those requiring an [`OnlineClientT`]). + #[derivative(Clone(bound = ""))] + pub struct OnlineClient { + inner: Arc>>, + backend: Arc>, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for OnlineClient { + fn clone(&self) -> Self { + match *self { + OnlineClient { inner: ref __arg_0, backend: ref __arg_1 } => { + OnlineClient { + inner: (*__arg_0).clone(), + backend: (*__arg_1).clone(), + } + } + } + } + } + #[derivative(Debug(bound = ""))] + struct Inner { + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: Metadata, + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Inner { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Inner { + genesis_hash: ref __arg_0, + runtime_version: ref __arg_1, + metadata: ref __arg_2, + } => { + let mut __debug_trait_builder = __f.debug_struct("Inner"); + let _ = __debug_trait_builder + .field("genesis_hash", &&(*__arg_0)); + let _ = __debug_trait_builder + .field("runtime_version", &&(*__arg_1)); + let _ = __debug_trait_builder.field("metadata", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + impl std::fmt::Debug for OnlineClient { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Client") + .field("rpc", &"RpcClient") + .field("inner", &self.inner) + .finish() + } + } + #[cfg(feature = "jsonrpsee")] + impl OnlineClient { + /// Construct a new [`OnlineClient`] using default settings which + /// point to a locally running node on `ws://127.0.0.1:9944`. + pub async fn new() -> Result, Error> { + let url = "ws://127.0.0.1:9944"; + OnlineClient::from_url(url).await + } + /// Construct a new [`OnlineClient`], providing a URL to connect to. + pub async fn from_url( + url: impl AsRef, + ) -> Result, Error> { + crate::utils::validate_url_is_secure(url.as_ref())?; + OnlineClient::from_insecure_url(url).await + } + /// Construct a new [`OnlineClient`], providing a URL to connect to. + /// + /// Allows insecure URLs without SSL encryption, e.g. (http:// and ws:// URLs). + pub async fn from_insecure_url( + url: impl AsRef, + ) -> Result, Error> { + let client = RpcClient::from_insecure_url(url).await?; + let backend = LegacyBackend::new(client); + OnlineClient::from_backend(Arc::new(backend)).await + } + } + impl OnlineClient { + /// Construct a new [`OnlineClient`] by providing an [`RpcClient`] to drive the connection. + /// This will use the current default [`Backend`], which may change in future releases. + pub async fn from_rpc_client( + rpc_client: RpcClient, + ) -> Result, Error> { + let backend = Arc::new(LegacyBackend::new(rpc_client)); + OnlineClient::from_backend(backend).await + } + /// Construct a new [`OnlineClient`] by providing an RPC client along with the other + /// necessary details. This will use the current default [`Backend`], which may change + /// in future releases. + /// + /// # Warning + /// + /// This is considered the most primitive and also error prone way to + /// instantiate a client; the genesis hash, metadata and runtime version provided will + /// entirely determine which node and blocks this client will be able to interact with, + /// and whether it will be able to successfully do things like submit transactions. + /// + /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate + /// a client. + pub fn from_rpc_client_with( + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: impl Into, + rpc_client: RpcClient, + ) -> Result, Error> { + let backend = Arc::new(LegacyBackend::new(rpc_client)); + OnlineClient::from_backend_with( + genesis_hash, + runtime_version, + metadata, + backend, + ) + } + /// Construct a new [`OnlineClient`] by providing an underlying [`Backend`] + /// implementation to power it. Other details will be obtained from the chain. + pub async fn from_backend>( + backend: Arc, + ) -> Result, Error> { + let latest_block = backend.latest_finalized_block_ref().await?; + let (genesis_hash, runtime_version, metadata) = future::join3( + backend.genesis_hash(), + backend.current_runtime_version(), + OnlineClient::fetch_metadata(&*backend, latest_block.hash()), + ) + .await; + OnlineClient::from_backend_with( + genesis_hash?, + runtime_version?, + metadata?, + backend, + ) + } + /// Construct a new [`OnlineClient`] by providing all of the underlying details needed + /// to make it work. + /// + /// # Warning + /// + /// This is considered the most primitive and also error prone way to + /// instantiate a client; the genesis hash, metadata and runtime version provided will + /// entirely determine which node and blocks this client will be able to interact with, + /// and whether it will be able to successfully do things like submit transactions. + /// + /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate + /// a client. + pub fn from_backend_with>( + genesis_hash: T::Hash, + runtime_version: RuntimeVersion, + metadata: impl Into, + backend: Arc, + ) -> Result, Error> { + Ok(OnlineClient { + inner: Arc::new( + RwLock::new(Inner { + genesis_hash, + runtime_version, + metadata: metadata.into(), + }), + ), + backend, + }) + } + /// Fetch the metadata from substrate using the runtime API. + async fn fetch_metadata( + backend: &dyn Backend, + block_hash: T::Hash, + ) -> Result { + #[cfg(not(feature = "unstable-metadata"))] + OnlineClient::fetch_latest_stable_metadata(backend, block_hash).await + } + /// Fetch the latest stable metadata from the node. + async fn fetch_latest_stable_metadata( + backend: &dyn Backend, + block_hash: T::Hash, + ) -> Result { + const V15_METADATA_VERSION: u32 = 15; + if let Ok(bytes) + = backend.metadata_at_version(V15_METADATA_VERSION, block_hash).await + { + return Ok(bytes); + } + backend.legacy_metadata(block_hash).await + } + /// Create an object which can be used to keep the runtime up to date + /// in a separate thread. + /// + /// # Example + /// + /// ```no_run + /// # #[tokio::main] + /// # async fn main() { + /// use subxt::{ OnlineClient, PolkadotConfig }; + /// + /// let client = OnlineClient::::new().await.unwrap(); + /// + /// // high level API. + /// + /// let update_task = client.updater(); + /// tokio::spawn(async move { + /// update_task.perform_runtime_updates().await; + /// }); + /// + /// + /// // low level API. + /// + /// let updater = client.updater(); + /// tokio::spawn(async move { + /// let mut update_stream = updater.runtime_updates().await.unwrap(); + /// + /// while let Some(Ok(update)) = update_stream.next().await { + /// let version = update.runtime_version().spec_version; + /// + /// match updater.apply_update(update) { + /// Ok(()) => { + /// println!("Upgrade to version: {} successful", version) + /// } + /// Err(e) => { + /// println!("Upgrade to version {} failed {:?}", version, e); + /// } + /// }; + /// } + /// }); + /// # } + /// ``` + pub fn updater(&self) -> ClientRuntimeUpdater { + ClientRuntimeUpdater(self.clone()) + } + /// Return the [`Metadata`] used in this client. + pub fn metadata(&self) -> Metadata { + let inner = self.inner.read().expect("shouldn't be poisoned"); + inner.metadata.clone() + } + /// Change the [`Metadata`] used in this client. + /// + /// # Warning + /// + /// Setting custom metadata may leave Subxt unable to work with certain blocks, + /// subscribe to latest blocks or submit valid transactions. + pub fn set_metadata(&self, metadata: impl Into) { + let mut inner = self.inner.write().expect("shouldn't be poisoned"); + inner.metadata = metadata.into(); + } + /// Return the genesis hash. + pub fn genesis_hash(&self) -> T::Hash { + let inner = self.inner.read().expect("shouldn't be poisoned"); + inner.genesis_hash + } + /// Change the genesis hash used in this client. + /// + /// # Warning + /// + /// Setting a custom genesis hash may leave Subxt unable to + /// submit valid transactions. + pub fn set_genesis_hash(&self, genesis_hash: T::Hash) { + let mut inner = self.inner.write().expect("shouldn't be poisoned"); + inner.genesis_hash = genesis_hash; + } + /// Return the runtime version. + pub fn runtime_version(&self) -> RuntimeVersion { + let inner = self.inner.read().expect("shouldn't be poisoned"); + inner.runtime_version.clone() + } + /// Change the [`RuntimeVersion`] used in this client. + /// + /// # Warning + /// + /// Setting a custom runtime version may leave Subxt unable to + /// submit valid transactions. + pub fn set_runtime_version(&self, runtime_version: RuntimeVersion) { + let mut inner = self.inner.write().expect("shouldn't be poisoned"); + inner.runtime_version = runtime_version; + } + /// Return an RPC client to make raw requests with. + pub fn backend(&self) -> &dyn Backend { + &*self.backend + } + /// Return an offline client with the same configuration as this. + pub fn offline(&self) -> OfflineClient { + let inner = self.inner.read().expect("shouldn't be poisoned"); + OfflineClient::new( + inner.genesis_hash, + inner.runtime_version.clone(), + inner.metadata.clone(), + ) + } + /// Work with transactions. + pub fn tx(&self) -> TxClient { + >::tx(self) + } + /// Work with events. + pub fn events(&self) -> EventsClient { + >::events(self) + } + /// Work with storage. + pub fn storage(&self) -> StorageClient { + >::storage(self) + } + /// Access constants. + pub fn constants(&self) -> ConstantsClient { + >::constants(self) + } + /// Access custom types. + pub fn custom_values(&self) -> CustomValuesClient { + >::custom_values(self) + } + /// Work with blocks. + pub fn blocks(&self) -> BlocksClient { + >::blocks(self) + } + /// Work with runtime API. + pub fn runtime_api(&self) -> RuntimeApiClient { + >::runtime_api(self) + } + } + impl OfflineClientT for OnlineClient { + fn metadata(&self) -> Metadata { + self.metadata() + } + fn genesis_hash(&self) -> T::Hash { + self.genesis_hash() + } + fn runtime_version(&self) -> RuntimeVersion { + self.runtime_version() + } + } + impl OnlineClientT for OnlineClient { + fn backend(&self) -> &dyn Backend { + &*self.backend + } + } + /// Client wrapper for performing runtime updates. See [`OnlineClient::updater()`] + /// for example usage. + pub struct ClientRuntimeUpdater(OnlineClient); + impl ClientRuntimeUpdater { + fn is_runtime_version_different(&self, new: &RuntimeVersion) -> bool { + let curr = self.0.inner.read().expect("shouldn't be poisoned"); + &curr.runtime_version != new + } + fn do_update(&self, update: Update) { + let mut writable = self.0.inner.write().expect("shouldn't be poisoned"); + writable.metadata = update.metadata; + writable.runtime_version = update.runtime_version; + } + /// Tries to apply a new update. + pub fn apply_update(&self, update: Update) -> Result<(), UpgradeError> { + if !self.is_runtime_version_different(&update.runtime_version) { + return Err(UpgradeError::SameVersion); + } + self.do_update(update); + Ok(()) + } + /// Performs runtime updates indefinitely unless encountering an error. + /// + /// *Note:* This will run indefinitely until it errors, so the typical usage + /// would be to run it in a separate background task. + pub async fn perform_runtime_updates(&self) -> Result<(), Error> { + let mut runtime_version_stream = self.runtime_updates().await?; + while let Some(update) = runtime_version_stream.next().await { + let update = update?; + let _ = self.apply_update(update); + } + Ok(()) + } + /// Low-level API to get runtime updates as a stream but it's doesn't check if the + /// runtime version is newer or updates the runtime. + /// + /// Instead that's up to the user of this API to decide when to update and + /// to perform the actual updating. + pub async fn runtime_updates( + &self, + ) -> Result, Error> { + let stream = self.0.backend().stream_runtime_version().await?; + Ok(RuntimeUpdaterStream { + stream, + client: self.0.clone(), + }) + } + } + /// Stream to perform runtime upgrades. + pub struct RuntimeUpdaterStream { + stream: StreamOfResults, + client: OnlineClient, + } + impl RuntimeUpdaterStream { + /// Wait for the next runtime update. + pub async fn next(&mut self) -> Option> { + let runtime_version = match self.stream.next().await? { + Ok(runtime_version) => runtime_version, + Err(err) => return Some(Err(err)), + }; + let at = match wait_runtime_upgrade_in_finalized_block( + &self.client, + &runtime_version, + ) + .await? + { + Ok(at) => at, + Err(err) => return Some(Err(err)), + }; + let metadata = match OnlineClient::fetch_metadata( + self.client.backend(), + at.hash(), + ) + .await + { + Ok(metadata) => metadata, + Err(err) => return Some(Err(err)), + }; + Some( + Ok(Update { + metadata, + runtime_version, + }), + ) + } + } + /// Error that can occur during upgrade. + #[non_exhaustive] + pub enum UpgradeError { + /// The version is the same as the current version. + SameVersion, + } + #[automatically_derived] + impl ::core::fmt::Debug for UpgradeError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "SameVersion") + } + } + #[automatically_derived] + impl ::core::clone::Clone for UpgradeError { + #[inline] + fn clone(&self) -> UpgradeError { + UpgradeError::SameVersion + } + } + /// Represents the state when a runtime upgrade occurred. + pub struct Update { + runtime_version: RuntimeVersion, + metadata: Metadata, + } + impl Update { + /// Get the runtime version. + pub fn runtime_version(&self) -> &RuntimeVersion { + &self.runtime_version + } + /// Get the metadata. + pub fn metadata(&self) -> &Metadata { + &self.metadata + } + } + /// Helper to wait until the runtime upgrade is applied on at finalized block. + async fn wait_runtime_upgrade_in_finalized_block( + client: &OnlineClient, + runtime_version: &RuntimeVersion, + ) -> Option, Error>> { + use scale_value::At; + let mut block_sub = match client + .backend() + .stream_finalized_block_headers() + .await + { + Ok(s) => s, + Err(err) => return Some(Err(err)), + }; + let block_ref = loop { + let (_, block_ref) = match block_sub.next().await? { + Ok(n) => n, + Err(err) => return Some(Err(err)), + }; + let key: Vec = ::alloc::vec::Vec::new(); + let addr = crate::dynamic::storage("System", "LastRuntimeUpgrade", key); + let chunk = match client + .storage() + .at(block_ref.hash()) + .fetch(&addr) + .await + { + Ok(Some(v)) => v, + Ok(None) => { + ::core::panicking::panic_fmt( + format_args!( + "internal error: entered unreachable code: {0}", + format_args!("The storage item `system::lastRuntimeUpgrade` should always exist") + ), + ); + } + Err(e) => return Some(Err(e)), + }; + let scale_val = match chunk.to_value() { + Ok(v) => v, + Err(e) => return Some(Err(e)), + }; + let Some(Ok(spec_version)) = scale_val + .at("spec_version") + .and_then(|v| v.as_u128()) + .map(u32::try_from) else { + return Some( + Err( + Error::Other( + "Decoding `RuntimeVersion::spec_version` as u32 failed" + .to_string(), + ), + ), + ); + }; + if spec_version == runtime_version.spec_version { + break block_ref; + } + }; + Some(Ok(block_ref)) + } + } + pub use offline_client::{OfflineClient, OfflineClientT}; + pub use online_client::{ + ClientRuntimeUpdater, OnlineClient, OnlineClientT, RuntimeUpdaterStream, Update, + UpgradeError, + }; +} +pub mod config { + //! This module provides a [`Config`] type, which is used to define various + //! types that are important in order to speak to a particular chain. + //! [`SubstrateConfig`] provides a default set of these types suitable for the + //! default Substrate node implementation, and [`PolkadotConfig`] for a + //! Polkadot node. + mod default_extrinsic_params { + use super::{signed_extensions, ExtrinsicParams}; + use super::{Config, Header}; + /// The default [`super::ExtrinsicParams`] implementation understands common signed extensions + /// and how to apply them to a given chain. + pub type DefaultExtrinsicParams = signed_extensions::AnyOf< + T, + ( + signed_extensions::CheckSpecVersion, + signed_extensions::CheckTxVersion, + signed_extensions::CheckNonce, + signed_extensions::CheckGenesis, + signed_extensions::CheckMortality, + signed_extensions::ChargeAssetTxPayment, + signed_extensions::ChargeTransactionPayment, + ), + >; + /// A builder that outputs the set of [`super::ExtrinsicParams::OtherParams`] required for + /// [`DefaultExtrinsicParams`]. This may expose methods that aren't applicable to the current + /// chain; such values will simply be ignored if so. + pub struct DefaultExtrinsicParamsBuilder { + /// `None` means the tx will be immortal. + mortality: Option>, + /// `None` means we'll use the native token. + tip_of_asset_id: Option, + tip: u128, + tip_of: u128, + } + struct Mortality { + /// Block hash that mortality starts from + checkpoint_hash: Hash, + /// Block number that mortality starts from (must + checkpoint_number: u64, + /// How many blocks the tx is mortal for + period: u64, + } + impl Default for DefaultExtrinsicParamsBuilder { + fn default() -> Self { + Self { + mortality: None, + tip: 0, + tip_of: 0, + tip_of_asset_id: None, + } + } + } + impl DefaultExtrinsicParamsBuilder { + /// Configure new extrinsic params. We default to providing no tip + /// and using an immortal transaction unless otherwise configured + pub fn new() -> Self { + Default::default() + } + /// Make the transaction mortal, given a block header that it should be mortal from, + /// and the number of blocks (roughly; it'll be rounded to a power of two) that it will + /// be mortal for. + pub fn mortal(mut self, from_block: &T::Header, for_n_blocks: u64) -> Self { + self + .mortality = Some(Mortality { + checkpoint_hash: from_block.hash(), + checkpoint_number: from_block.number().into(), + period: for_n_blocks, + }); + self + } + /// Make the transaction mortal, given a block number and block hash (which must both point to + /// the same block) that it should be mortal from, and the number of blocks (roughly; it'll be + /// rounded to a power of two) that it will be mortal for. + /// + /// Prefer to use [`DefaultExtrinsicParamsBuilder::mortal()`], which ensures that the block hash + /// and number align. + pub fn mortal_unchecked( + mut self, + from_block_number: u64, + from_block_hash: T::Hash, + for_n_blocks: u64, + ) -> Self { + self + .mortality = Some(Mortality { + checkpoint_hash: from_block_hash, + checkpoint_number: from_block_number, + period: for_n_blocks, + }); + self + } + /// Provide a tip to the block author in the chain's native token. + pub fn tip(mut self, tip: u128) -> Self { + self.tip = tip; + self.tip_of = tip; + self.tip_of_asset_id = None; + self + } + /// Provide a tip to the block author using the token denominated by the `asset_id` provided. This + /// is not applicable on chains which don't use the `ChargeAssetTxPayment` signed extension; in this + /// case, no tip will be given. + pub fn tip_of(mut self, tip: u128, asset_id: T::AssetId) -> Self { + self.tip = 0; + self.tip_of = tip; + self.tip_of_asset_id = Some(asset_id); + self + } + /// Build the extrinsic parameters. + pub fn build( + self, + ) -> as ExtrinsicParams>::OtherParams { + let check_mortality_params = if let Some(mortality) = self.mortality { + signed_extensions::CheckMortalityParams::mortal( + mortality.period, + mortality.checkpoint_number, + mortality.checkpoint_hash, + ) + } else { + signed_extensions::CheckMortalityParams::immortal() + }; + let charge_asset_tx_params = if let Some(asset_id) = self.tip_of_asset_id + { + signed_extensions::ChargeAssetTxPaymentParams::tip_of( + self.tip, + asset_id, + ) + } else { + signed_extensions::ChargeAssetTxPaymentParams::tip(self.tip) + }; + let charge_transaction_params = signed_extensions::ChargeTransactionPaymentParams::tip( + self.tip, + ); + ( + (), + (), + (), + (), + check_mortality_params, + charge_asset_tx_params, + charge_transaction_params, + ) + } + } + } + mod extrinsic_params { + //! This module contains a trait which controls the parameters that must + //! be provided in order to successfully construct an extrinsic. + //! [`crate::config::DefaultExtrinsicParams`] provides a general-purpose + //! implementation of this that will work in many cases. + use crate::{client::OfflineClientT, Config}; + use core::fmt::Debug; + /// An error that can be emitted when trying to construct an instance of [`ExtrinsicParams`], + /// encode data from the instance, or match on signed extensions. + #[non_exhaustive] + pub enum ExtrinsicParamsError { + /// Cannot find a type id in the metadata. The context provides some additional + /// information about the source of the error (eg the signed extension name). + #[error( + "Cannot find type id '{type_id} in the metadata (context: {context})" + )] + MissingTypeId { + /// Type ID. + type_id: u32, + /// Some arbitrary context to help narrow the source of the error. + context: &'static str, + }, + /// A signed extension in use on some chain was not provided. + #[error( + "The chain expects a signed extension with the name {0}, but we did not provide one" + )] + UnknownSignedExtension(String), + /// Some custom error. + #[error("Error constructing extrinsic parameters: {0}")] + Custom(CustomExtrinsicParamsError), + } + #[allow(unused_qualifications)] + impl std::error::Error for ExtrinsicParamsError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for ExtrinsicParamsError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + ExtrinsicParamsError::MissingTypeId { type_id, context } => { + __formatter + .write_fmt( + format_args!( + "Cannot find type id \'{0} in the metadata (context: {1})", + type_id.as_display(), context.as_display() + ), + ) + } + ExtrinsicParamsError::UnknownSignedExtension(_0) => { + __formatter + .write_fmt( + format_args!( + "The chain expects a signed extension with the name {0}, but we did not provide one", + _0.as_display() + ), + ) + } + ExtrinsicParamsError::Custom(_0) => { + __formatter + .write_fmt( + format_args!( + "Error constructing extrinsic parameters: {0}", _0 + .as_display() + ), + ) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ExtrinsicParamsError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ExtrinsicParamsError::MissingTypeId { + type_id: __self_0, + context: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "MissingTypeId", + "type_id", + __self_0, + "context", + &__self_1, + ) + } + ExtrinsicParamsError::UnknownSignedExtension(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "UnknownSignedExtension", + &__self_0, + ) + } + ExtrinsicParamsError::Custom(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Custom", + &__self_0, + ) + } + } + } + } + /// A custom error. + pub type CustomExtrinsicParamsError = Box< + dyn std::error::Error + Send + Sync + 'static, + >; + impl From for ExtrinsicParamsError { + fn from(value: std::convert::Infallible) -> Self { + match value {} + } + } + impl From for ExtrinsicParamsError { + fn from(value: CustomExtrinsicParamsError) -> Self { + ExtrinsicParamsError::Custom(value) + } + } + /// This trait allows you to configure the "signed extra" and + /// "additional" parameters that are a part of the transaction payload + /// or the signer payload respectively. + pub trait ExtrinsicParams: ExtrinsicParamsEncoder + Sized + 'static { + /// These parameters can be provided to the constructor along with + /// some default parameters that `subxt` understands, in order to + /// help construct your [`ExtrinsicParams`] object. + type OtherParams; + /// Construct a new instance of our [`ExtrinsicParams`]. + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result; + } + /// This trait is expected to be implemented for any [`ExtrinsicParams`], and + /// defines how to encode the "additional" and "extra" params. Both functions + /// are optional and will encode nothing by default. + pub trait ExtrinsicParamsEncoder: 'static { + /// This is expected to SCALE encode the "signed extra" parameters + /// to some buffer that has been provided. These are the parameters + /// which are sent along with the transaction, as well as taken into + /// account when signing the transaction. + fn encode_extra_to(&self, _v: &mut Vec) {} + /// This is expected to SCALE encode the "additional" parameters + /// to some buffer that has been provided. These parameters are _not_ + /// sent along with the transaction, but are taken into account when + /// signing it, meaning the client and node must agree on their values. + fn encode_additional_to(&self, _v: &mut Vec) {} + } + } + pub mod polkadot { + //! Polkadot specific configuration + use super::{Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder}; + pub use crate::utils::{AccountId32, MultiAddress, MultiSignature}; + use crate::SubstrateConfig; + pub use primitive_types::{H256, U256}; + /// Default set of commonly used types by Polkadot nodes. + pub enum PolkadotConfig {} + impl Config for PolkadotConfig { + type Hash = ::Hash; + type AccountId = ::AccountId; + type Address = MultiAddress; + type Signature = ::Signature; + type Hasher = ::Hasher; + type Header = ::Header; + type ExtrinsicParams = PolkadotExtrinsicParams; + type AssetId = u32; + } + /// A struct representing the signed extra and additional parameters required + /// to construct a transaction for a polkadot node. + pub type PolkadotExtrinsicParams = DefaultExtrinsicParams; + /// A builder which leads to [`PolkadotExtrinsicParams`] being constructed. + /// This is what you provide to methods like `sign_and_submit()`. + pub type PolkadotExtrinsicParamsBuilder = DefaultExtrinsicParamsBuilder; + } + pub mod signed_extensions { + //! This module contains implementations for common signed extensions, each + //! of which implements [`SignedExtension`], and can be used in conjunction with + //! [`AnyOf`] to configure the set of signed extensions which are known about + //! when interacting with a chain. + use super::extrinsic_params::{ + ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, + }; + use crate::utils::Era; + use crate::{client::OfflineClientT, Config}; + use codec::{Compact, Encode}; + use core::fmt::Debug; + use derivative::Derivative; + use scale_decode::DecodeAsType; + use scale_info::PortableRegistry; + use std::collections::HashMap; + /// A single [`SignedExtension`] has a unique name, but is otherwise the + /// same as [`ExtrinsicParams`] in describing how to encode the extra and + /// additional data. + pub trait SignedExtension: ExtrinsicParams { + /// The type representing the `extra` bytes of a signed extension. + /// Decoding from this type should be symmetrical to the respective + /// `ExtrinsicParamsEncoder::encode_extra_to()` implementation of this signed extension. + type Decoded: DecodeAsType; + /// This should return true if the signed extension matches the details given. + /// Often, this will involve just checking that the identifier given matches that of the + /// extension in question. + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool; + } + /// The [`CheckSpecVersion`] signed extension. + pub struct CheckSpecVersion(u32); + impl ExtrinsicParams for CheckSpecVersion { + type OtherParams = (); + fn new>( + _nonce: u64, + client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CheckSpecVersion(client.runtime_version().spec_version)) + } + } + impl ExtrinsicParamsEncoder for CheckSpecVersion { + fn encode_additional_to(&self, v: &mut Vec) { + self.0.encode_to(v); + } + } + impl SignedExtension for CheckSpecVersion { + type Decoded = (); + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckSpecVersion" + } + } + /// The [`CheckNonce`] signed extension. + pub struct CheckNonce(Compact); + impl ExtrinsicParams for CheckNonce { + type OtherParams = (); + fn new>( + nonce: u64, + _client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CheckNonce(Compact(nonce))) + } + } + impl ExtrinsicParamsEncoder for CheckNonce { + fn encode_extra_to(&self, v: &mut Vec) { + self.0.encode_to(v); + } + } + impl SignedExtension for CheckNonce { + type Decoded = u64; + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckNonce" + } + } + /// The [`CheckTxVersion`] signed extension. + pub struct CheckTxVersion(u32); + impl ExtrinsicParams for CheckTxVersion { + type OtherParams = (); + fn new>( + _nonce: u64, + client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CheckTxVersion(client.runtime_version().transaction_version)) + } + } + impl ExtrinsicParamsEncoder for CheckTxVersion { + fn encode_additional_to(&self, v: &mut Vec) { + self.0.encode_to(v); + } + } + impl SignedExtension for CheckTxVersion { + type Decoded = (); + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckTxVersion" + } + } + /// The [`CheckGenesis`] signed extension. + pub struct CheckGenesis(T::Hash); + impl ExtrinsicParams for CheckGenesis { + type OtherParams = (); + fn new>( + _nonce: u64, + client: Client, + _other_params: Self::OtherParams, + ) -> Result { + Ok(CheckGenesis(client.genesis_hash())) + } + } + impl ExtrinsicParamsEncoder for CheckGenesis { + fn encode_additional_to(&self, v: &mut Vec) { + self.0.encode_to(v); + } + } + impl SignedExtension for CheckGenesis { + type Decoded = (); + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckGenesis" + } + } + /// The [`CheckMortality`] signed extension. + pub struct CheckMortality { + era: Era, + checkpoint: T::Hash, + } + /// Parameters to configure the [`CheckMortality`] signed extension. + pub struct CheckMortalityParams { + era: Era, + checkpoint: Option, + } + impl Default for CheckMortalityParams { + fn default() -> Self { + Self { + era: Default::default(), + checkpoint: Default::default(), + } + } + } + impl CheckMortalityParams { + /// Configure a mortal transaction. The `period` is (roughly) how many + /// blocks the transaction will be valid for. The `block_number` and + /// `block_hash` should both point to the same block, and are the block that + /// the transaction is mortal from. + pub fn mortal(period: u64, block_number: u64, block_hash: T::Hash) -> Self { + CheckMortalityParams { + era: Era::mortal(period, block_number), + checkpoint: Some(block_hash), + } + } + /// An immortal transaction. + pub fn immortal() -> Self { + CheckMortalityParams { + era: Era::Immortal, + checkpoint: None, + } + } + } + impl ExtrinsicParams for CheckMortality { + type OtherParams = CheckMortalityParams; + fn new>( + _nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + Ok(CheckMortality { + era: other_params.era, + checkpoint: other_params.checkpoint.unwrap_or(client.genesis_hash()), + }) + } + } + impl ExtrinsicParamsEncoder for CheckMortality { + fn encode_extra_to(&self, v: &mut Vec) { + self.era.encode_to(v); + } + fn encode_additional_to(&self, v: &mut Vec) { + self.checkpoint.encode_to(v); + } + } + impl SignedExtension for CheckMortality { + type Decoded = Era; + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "CheckMortality" + } + } + /// The [`ChargeAssetTxPayment`] signed extension. + #[derivative( + Clone(bound = "T::AssetId: Clone"), + Debug(bound = "T::AssetId: Debug") + )] + #[decode_as_type(trait_bounds = "T::AssetId: DecodeAsType")] + pub struct ChargeAssetTxPayment { + tip: Compact, + asset_id: Option, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for ChargeAssetTxPayment + where + T::AssetId: Clone, + { + fn clone(&self) -> Self { + match *self { + ChargeAssetTxPayment { tip: ref __arg_0, asset_id: ref __arg_1 } => { + ChargeAssetTxPayment { + tip: (*__arg_0).clone(), + asset_id: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for ChargeAssetTxPayment + where + T::AssetId: Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + ChargeAssetTxPayment { tip: ref __arg_0, asset_id: ref __arg_1 } => { + let mut __debug_trait_builder = __f + .debug_struct("ChargeAssetTxPayment"); + let _ = __debug_trait_builder.field("tip", &&(*__arg_0)); + let _ = __debug_trait_builder.field("asset_id", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<(T,)>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for ChargeAssetTxPayment + where + T::AssetId: DecodeAsType, + { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor + where + T::AssetId: DecodeAsType, + { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = ChargeAssetTxPayment; + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.has_unnamed_fields() { + return self.visit_tuple(&mut value.as_tuple(), type_id); + } + let vals: ::scale_decode::BTreeMap, _> = value + .map(|res| res.map(|item| (item.name(), item))) + .collect::>()?; + Ok(ChargeAssetTxPayment { + tip: { + let val = *vals + .get(&Some("tip")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "tip".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("tip"))? + }, + asset_id: { + let val = *vals + .get(&Some("asset_id")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "asset_id".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("asset_id"))? + }, + }) + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 2usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: value.remaining(), + expected_len: 2usize, + }), + ); + } + let vals = value; + Ok(ChargeAssetTxPayment { + tip: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("tip"))? + }, + asset_id: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("asset_id"))? + }, + }) + } + } + impl ::scale_decode::DecodeAsFields for ChargeAssetTxPayment + where + T::AssetId: DecodeAsType, + { + fn decode_as_fields<'info>( + input: &mut &[u8], + fields: &mut dyn ::scale_decode::FieldIter<'info>, + types: &'info ::scale_decode::PortableRegistry, + ) -> Result { + let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; + let mut composite = ::scale_decode::visitor::types::Composite::new( + input, + path, + fields, + types, + false, + ); + use ::scale_decode::{Visitor, IntoVisitor}; + let val = >::into_visitor() + .visit_composite( + &mut composite, + ::scale_decode::visitor::TypeId(0), + ); + composite.skip_decoding()?; + *input = composite.bytes_from_undecoded(); + val.map_err(From::from) + } + } + }; + impl ChargeAssetTxPayment { + /// Tip to the extrinsic author in the native chain token. + pub fn tip(&self) -> u128 { + self.tip.0 + } + /// Tip to the extrinsic author using the asset ID given. + pub fn asset_id(&self) -> Option<&T::AssetId> { + self.asset_id.as_ref() + } + } + /// Parameters to configure the [`ChargeAssetTxPayment`] signed extension. + pub struct ChargeAssetTxPaymentParams { + tip: u128, + asset_id: Option, + } + impl Default for ChargeAssetTxPaymentParams { + fn default() -> Self { + ChargeAssetTxPaymentParams { + tip: Default::default(), + asset_id: Default::default(), + } + } + } + impl ChargeAssetTxPaymentParams { + /// Don't provide a tip to the extrinsic author. + pub fn no_tip() -> Self { + ChargeAssetTxPaymentParams { + tip: 0, + asset_id: None, + } + } + /// Tip the extrinsic author in the native chain token. + pub fn tip(tip: u128) -> Self { + ChargeAssetTxPaymentParams { + tip, + asset_id: None, + } + } + /// Tip the extrinsic author using the asset ID given. + pub fn tip_of(tip: u128, asset_id: T::AssetId) -> Self { + ChargeAssetTxPaymentParams { + tip, + asset_id: Some(asset_id), + } + } + } + impl ExtrinsicParams for ChargeAssetTxPayment { + type OtherParams = ChargeAssetTxPaymentParams; + fn new>( + _nonce: u64, + _client: Client, + other_params: Self::OtherParams, + ) -> Result { + Ok(ChargeAssetTxPayment { + tip: Compact(other_params.tip), + asset_id: other_params.asset_id, + }) + } + } + impl ExtrinsicParamsEncoder for ChargeAssetTxPayment { + fn encode_extra_to(&self, v: &mut Vec) { + (self.tip, &self.asset_id).encode_to(v); + } + } + impl SignedExtension for ChargeAssetTxPayment { + type Decoded = Self; + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "ChargeAssetTxPayment" + } + } + /// The [`ChargeTransactionPayment`] signed extension. + pub struct ChargeTransactionPayment { + tip: Compact, + } + #[automatically_derived] + impl ::core::clone::Clone for ChargeTransactionPayment { + #[inline] + fn clone(&self) -> ChargeTransactionPayment { + ChargeTransactionPayment { + tip: ::core::clone::Clone::clone(&self.tip), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ChargeTransactionPayment { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "ChargeTransactionPayment", + "tip", + &&self.tip, + ) + } + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for ChargeTransactionPayment { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = ChargeTransactionPayment; + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.has_unnamed_fields() { + return self.visit_tuple(&mut value.as_tuple(), type_id); + } + let vals: ::scale_decode::BTreeMap, _> = value + .map(|res| res.map(|item| (item.name(), item))) + .collect::>()?; + Ok(ChargeTransactionPayment { + tip: { + let val = *vals + .get(&Some("tip")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "tip".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("tip"))? + }, + }) + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: value.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = value; + Ok(ChargeTransactionPayment { + tip: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("tip"))? + }, + }) + } + } + impl ::scale_decode::DecodeAsFields for ChargeTransactionPayment { + fn decode_as_fields<'info>( + input: &mut &[u8], + fields: &mut dyn ::scale_decode::FieldIter<'info>, + types: &'info ::scale_decode::PortableRegistry, + ) -> Result { + let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; + let mut composite = ::scale_decode::visitor::types::Composite::new( + input, + path, + fields, + types, + false, + ); + use ::scale_decode::{Visitor, IntoVisitor}; + let val = ::into_visitor() + .visit_composite( + &mut composite, + ::scale_decode::visitor::TypeId(0), + ); + composite.skip_decoding()?; + *input = composite.bytes_from_undecoded(); + val.map_err(From::from) + } + } + }; + impl ChargeTransactionPayment { + /// Tip to the extrinsic author in the native chain token. + pub fn tip(&self) -> u128 { + self.tip.0 + } + } + /// Parameters to configure the [`ChargeTransactionPayment`] signed extension. + pub struct ChargeTransactionPaymentParams { + tip: u128, + } + #[automatically_derived] + impl ::core::default::Default for ChargeTransactionPaymentParams { + #[inline] + fn default() -> ChargeTransactionPaymentParams { + ChargeTransactionPaymentParams { + tip: ::core::default::Default::default(), + } + } + } + impl ChargeTransactionPaymentParams { + /// Don't provide a tip to the extrinsic author. + pub fn no_tip() -> Self { + ChargeTransactionPaymentParams { + tip: 0, + } + } + /// Tip the extrinsic author in the native chain token. + pub fn tip(tip: u128) -> Self { + ChargeTransactionPaymentParams { + tip, + } + } + } + impl ExtrinsicParams for ChargeTransactionPayment { + type OtherParams = ChargeTransactionPaymentParams; + fn new>( + _nonce: u64, + _client: Client, + other_params: Self::OtherParams, + ) -> Result { + Ok(ChargeTransactionPayment { + tip: Compact(other_params.tip), + }) + } + } + impl ExtrinsicParamsEncoder for ChargeTransactionPayment { + fn encode_extra_to(&self, v: &mut Vec) { + self.tip.encode_to(v); + } + } + impl SignedExtension for ChargeTransactionPayment { + type Decoded = Self; + fn matches( + identifier: &str, + _type_id: u32, + _types: &PortableRegistry, + ) -> bool { + identifier == "ChargeTransactionPayment" + } + } + /// This accepts a tuple of [`SignedExtension`]s, and will dynamically make use of whichever + /// ones are actually required for the chain in the correct order, ignoring the rest. This + /// is a sensible default, and allows for a single configuration to work across multiple chains. + pub struct AnyOf { + params: Vec>, + _marker: std::marker::PhantomData<(T, Params)>, + } + #[rustfmt::skip] + const _: () = { + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + { + type OtherParams = (A::OtherParams,); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + { + type OtherParams = (A::OtherParams, B::OtherParams); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + { + type OtherParams = (A::OtherParams, B::OtherParams, C::OtherParams); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + > ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + R::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if R::matches(e.identifier(), e.extra_ty(), types) { + let ext = R::new(nonce, client.clone(), other_params.17)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + > ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + R::OtherParams, + S::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if R::matches(e.identifier(), e.extra_ty(), types) { + let ext = R::new(nonce, client.clone(), other_params.17)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if S::matches(e.identifier(), e.extra_ty(), types) { + let ext = S::new(nonce, client.clone(), other_params.18)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + U, + > ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + U: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + R::OtherParams, + S::OtherParams, + U::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if R::matches(e.identifier(), e.extra_ty(), types) { + let ext = R::new(nonce, client.clone(), other_params.17)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if S::matches(e.identifier(), e.extra_ty(), types) { + let ext = S::new(nonce, client.clone(), other_params.18)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if U::matches(e.identifier(), e.extra_ty(), types) { + let ext = U::new(nonce, client.clone(), other_params.19)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + U, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + U: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + U, + V, + > ExtrinsicParams + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + U: SignedExtension, + V: SignedExtension, + { + type OtherParams = ( + A::OtherParams, + B::OtherParams, + C::OtherParams, + D::OtherParams, + E::OtherParams, + F::OtherParams, + G::OtherParams, + H::OtherParams, + I::OtherParams, + J::OtherParams, + K::OtherParams, + L::OtherParams, + M::OtherParams, + N::OtherParams, + O::OtherParams, + P::OtherParams, + Q::OtherParams, + R::OtherParams, + S::OtherParams, + U::OtherParams, + V::OtherParams, + ); + fn new>( + nonce: u64, + client: Client, + other_params: Self::OtherParams, + ) -> Result { + let metadata = client.metadata(); + let types = metadata.types(); + let mut exts_by_index = HashMap::new(); + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if A::matches(e.identifier(), e.extra_ty(), types) { + let ext = A::new(nonce, client.clone(), other_params.0)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if B::matches(e.identifier(), e.extra_ty(), types) { + let ext = B::new(nonce, client.clone(), other_params.1)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if C::matches(e.identifier(), e.extra_ty(), types) { + let ext = C::new(nonce, client.clone(), other_params.2)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if D::matches(e.identifier(), e.extra_ty(), types) { + let ext = D::new(nonce, client.clone(), other_params.3)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if E::matches(e.identifier(), e.extra_ty(), types) { + let ext = E::new(nonce, client.clone(), other_params.4)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if F::matches(e.identifier(), e.extra_ty(), types) { + let ext = F::new(nonce, client.clone(), other_params.5)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if G::matches(e.identifier(), e.extra_ty(), types) { + let ext = G::new(nonce, client.clone(), other_params.6)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if H::matches(e.identifier(), e.extra_ty(), types) { + let ext = H::new(nonce, client.clone(), other_params.7)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if I::matches(e.identifier(), e.extra_ty(), types) { + let ext = I::new(nonce, client.clone(), other_params.8)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if J::matches(e.identifier(), e.extra_ty(), types) { + let ext = J::new(nonce, client.clone(), other_params.9)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if K::matches(e.identifier(), e.extra_ty(), types) { + let ext = K::new(nonce, client.clone(), other_params.10)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if L::matches(e.identifier(), e.extra_ty(), types) { + let ext = L::new(nonce, client.clone(), other_params.11)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if M::matches(e.identifier(), e.extra_ty(), types) { + let ext = M::new(nonce, client.clone(), other_params.12)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if N::matches(e.identifier(), e.extra_ty(), types) { + let ext = N::new(nonce, client.clone(), other_params.13)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if O::matches(e.identifier(), e.extra_ty(), types) { + let ext = O::new(nonce, client.clone(), other_params.14)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if P::matches(e.identifier(), e.extra_ty(), types) { + let ext = P::new(nonce, client.clone(), other_params.15)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if Q::matches(e.identifier(), e.extra_ty(), types) { + let ext = Q::new(nonce, client.clone(), other_params.16)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if R::matches(e.identifier(), e.extra_ty(), types) { + let ext = R::new(nonce, client.clone(), other_params.17)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if S::matches(e.identifier(), e.extra_ty(), types) { + let ext = S::new(nonce, client.clone(), other_params.18)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if U::matches(e.identifier(), e.extra_ty(), types) { + let ext = U::new(nonce, client.clone(), other_params.19)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + { + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + if exts_by_index.contains_key(&idx) { + continue; + } + if V::matches(e.identifier(), e.extra_ty(), types) { + let ext = V::new(nonce, client.clone(), other_params.20)?; + let boxed_ext: Box = Box::new( + ext, + ); + exts_by_index.insert(idx, boxed_ext); + break; + } + } + } + let mut params = Vec::new(); + for (idx, e) in metadata + .extrinsic() + .signed_extensions() + .iter() + .enumerate() + { + let Some(ext) = exts_by_index.remove(&idx) else { + if is_type_empty(e.extra_ty(), types) { + continue + } else { + return Err( + ExtrinsicParamsError::UnknownSignedExtension( + e.identifier().to_owned(), + ), + ); + } }; + params.push(ext); + } + Ok(AnyOf { + params, + _marker: std::marker::PhantomData, + }) + } + } + impl< + T, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + U, + V, + > ExtrinsicParamsEncoder + for AnyOf + where + T: Config, + A: SignedExtension, + B: SignedExtension, + C: SignedExtension, + D: SignedExtension, + E: SignedExtension, + F: SignedExtension, + G: SignedExtension, + H: SignedExtension, + I: SignedExtension, + J: SignedExtension, + K: SignedExtension, + L: SignedExtension, + M: SignedExtension, + N: SignedExtension, + O: SignedExtension, + P: SignedExtension, + Q: SignedExtension, + R: SignedExtension, + S: SignedExtension, + U: SignedExtension, + V: SignedExtension, + { + fn encode_extra_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_extra_to(v); + } + } + fn encode_additional_to(&self, v: &mut Vec) { + for ext in &self.params { + ext.encode_additional_to(v); + } + } + } + }; + /// Checks to see whether the type being given is empty, ie would require + /// 0 bytes to encode. + fn is_type_empty(type_id: u32, types: &scale_info::PortableRegistry) -> bool { + let Some(ty) = types.resolve(type_id) else { return false; + }; + use scale_info::TypeDef; + match &ty.type_def { + TypeDef::Composite(c) => { + c.fields.iter().all(|f| is_type_empty(f.ty.id, types)) + } + TypeDef::Array(a) => a.len == 0 || is_type_empty(a.type_param.id, types), + TypeDef::Tuple(t) => t.fields.iter().all(|f| is_type_empty(f.id, types)), + TypeDef::BitSequence(_) + | TypeDef::Variant(_) + | TypeDef::Sequence(_) + | TypeDef::Compact(_) + | TypeDef::Primitive(_) => false, + } + } + } + pub mod substrate { + //! Substrate specific configuration + use super::{ + Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, Hasher, Header, + }; + use codec::{Decode, Encode}; + use serde::{Deserialize, Serialize}; + pub use crate::utils::{AccountId32, MultiAddress, MultiSignature}; + pub use primitive_types::{H256, U256}; + /// Default set of commonly used types by Substrate runtimes. + pub enum SubstrateConfig {} + impl Config for SubstrateConfig { + type Hash = H256; + type AccountId = AccountId32; + type Address = MultiAddress; + type Signature = MultiSignature; + type Hasher = BlakeTwo256; + type Header = SubstrateHeader; + type ExtrinsicParams = SubstrateExtrinsicParams; + type AssetId = u32; + } + /// A struct representing the signed extra and additional parameters required + /// to construct a transaction for the default substrate node. + pub type SubstrateExtrinsicParams = DefaultExtrinsicParams; + /// A builder which leads to [`SubstrateExtrinsicParams`] being constructed. + /// This is what you provide to methods like `sign_and_submit()`. + pub type SubstrateExtrinsicParamsBuilder = DefaultExtrinsicParamsBuilder; + /// A type that can hash values using the blaks2_256 algorithm. + pub struct BlakeTwo256; + #[automatically_derived] + impl ::core::fmt::Debug for BlakeTwo256 { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str(f, "BlakeTwo256") + } + } + #[automatically_derived] + impl ::core::clone::Clone for BlakeTwo256 { + #[inline] + fn clone(&self) -> BlakeTwo256 { + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for BlakeTwo256 {} + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BlakeTwo256 {} + #[automatically_derived] + impl ::core::cmp::PartialEq for BlakeTwo256 { + #[inline] + fn eq(&self, other: &BlakeTwo256) -> bool { + true + } + } + #[automatically_derived] + impl ::core::cmp::Eq for BlakeTwo256 { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for BlakeTwo256 { + fn size_hint(&self) -> usize { + 0_usize + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) {} + } + #[automatically_derived] + impl ::codec::EncodeLike for BlakeTwo256 {} + }; + impl Hasher for BlakeTwo256 { + type Output = H256; + fn hash(s: &[u8]) -> Self::Output { + sp_core_hashing::blake2_256(s).into() + } + } + /// A generic Substrate header type, adapted from `sp_runtime::generic::Header`. + /// The block number and hasher can be configured to adapt this for other nodes. + #[serde(rename_all = "camelCase")] + pub struct SubstrateHeader + TryFrom, H: Hasher> { + /// The parent hash. + pub parent_hash: H::Output, + /// The block number. + #[serde( + serialize_with = "serialize_number", + deserialize_with = "deserialize_number" + )] + #[codec(compact)] + pub number: N, + /// The state trie merkle root + pub state_root: H::Output, + /// The merkle root of the extrinsics. + pub extrinsics_root: H::Output, + /// A chain-specific digest of data useful for light clients or referencing auxiliary data. + pub digest: Digest, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl + TryFrom, H: Hasher> ::codec::Encode + for SubstrateHeader + where + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + N: ::codec::HasCompact, + { + fn size_hint(&self) -> usize { + 0_usize + .saturating_add(::codec::Encode::size_hint(&self.parent_hash)) + .saturating_add( + ::codec::Encode::size_hint( + &<::Type as ::codec::EncodeAsRef< + '_, + N, + >>::RefType::from(&self.number), + ), + ) + .saturating_add(::codec::Encode::size_hint(&self.state_root)) + .saturating_add( + ::codec::Encode::size_hint(&self.extrinsics_root), + ) + .saturating_add(::codec::Encode::size_hint(&self.digest)) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&self.parent_hash, __codec_dest_edqy); + { + ::codec::Encode::encode_to( + &<::Type as ::codec::EncodeAsRef< + '_, + N, + >>::RefType::from(&self.number), + __codec_dest_edqy, + ); + } + ::codec::Encode::encode_to(&self.state_root, __codec_dest_edqy); + ::codec::Encode::encode_to(&self.extrinsics_root, __codec_dest_edqy); + ::codec::Encode::encode_to(&self.digest, __codec_dest_edqy); + } + } + #[automatically_derived] + impl + TryFrom, H: Hasher> ::codec::EncodeLike + for SubstrateHeader + where + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + H::Output: ::codec::Encode, + N: ::codec::HasCompact, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl + TryFrom, H: Hasher> ::codec::Decode + for SubstrateHeader + where + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + H::Output: ::codec::Decode, + N: ::codec::HasCompact, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(SubstrateHeader:: { + parent_hash: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `SubstrateHeader::parent_hash`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + number: { + let __codec_res_edqy = <::Type as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `SubstrateHeader::number`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy.into() + } + } + }, + state_root: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `SubstrateHeader::state_root`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + extrinsics_root: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e + .chain( + "Could not decode `SubstrateHeader::extrinsics_root`", + ), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + digest: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `SubstrateHeader::digest`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + #[automatically_derived] + impl< + N: ::core::fmt::Debug + Copy + Into + TryFrom, + H: ::core::fmt::Debug + Hasher, + > ::core::fmt::Debug for SubstrateHeader + where + H::Output: ::core::fmt::Debug, + H::Output: ::core::fmt::Debug, + H::Output: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "SubstrateHeader", + "parent_hash", + &self.parent_hash, + "number", + &self.number, + "state_root", + &self.state_root, + "extrinsics_root", + &self.extrinsics_root, + "digest", + &&self.digest, + ) + } + } + #[automatically_derived] + impl< + N: Copy + Into + TryFrom, + H: Hasher, + > ::core::marker::StructuralPartialEq for SubstrateHeader {} + #[automatically_derived] + impl< + N: ::core::cmp::PartialEq + Copy + Into + TryFrom, + H: ::core::cmp::PartialEq + Hasher, + > ::core::cmp::PartialEq for SubstrateHeader + where + H::Output: ::core::cmp::PartialEq, + H::Output: ::core::cmp::PartialEq, + H::Output: ::core::cmp::PartialEq, + { + #[inline] + fn eq(&self, other: &SubstrateHeader) -> bool { + self.parent_hash == other.parent_hash && self.number == other.number + && self.state_root == other.state_root + && self.extrinsics_root == other.extrinsics_root + && self.digest == other.digest + } + } + #[automatically_derived] + impl< + N: ::core::cmp::Eq + Copy + Into + TryFrom, + H: ::core::cmp::Eq + Hasher, + > ::core::cmp::Eq for SubstrateHeader + where + H::Output: ::core::cmp::Eq, + H::Output: ::core::cmp::Eq, + H::Output: ::core::cmp::Eq, + { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl< + N: ::core::clone::Clone + Copy + Into + TryFrom, + H: ::core::clone::Clone + Hasher, + > ::core::clone::Clone for SubstrateHeader + where + H::Output: ::core::clone::Clone, + H::Output: ::core::clone::Clone, + H::Output: ::core::clone::Clone, + { + #[inline] + fn clone(&self) -> SubstrateHeader { + SubstrateHeader { + parent_hash: ::core::clone::Clone::clone(&self.parent_hash), + number: ::core::clone::Clone::clone(&self.number), + state_root: ::core::clone::Clone::clone(&self.state_root), + extrinsics_root: ::core::clone::Clone::clone(&self.extrinsics_root), + digest: ::core::clone::Clone::clone(&self.digest), + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl + TryFrom, H: Hasher> _serde::Serialize + for SubstrateHeader + where + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "SubstrateHeader", + false as usize + 1 + 1 + 1 + 1 + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "parentHash", + &self.parent_hash, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "number", + { + #[doc(hidden)] + struct __SerializeWith< + '__a, + N: Copy + Into + TryFrom + '__a, + H: Hasher + '__a, + > + where + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + { + values: (&'__a N,), + phantom: _serde::__private::PhantomData< + SubstrateHeader, + >, + } + impl< + '__a, + N: Copy + Into + TryFrom + '__a, + H: Hasher + '__a, + > _serde::Serialize for __SerializeWith<'__a, N, H> + where + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + H::Output: _serde::Serialize, + { + fn serialize<__S>( + &self, + __s: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + serialize_number(self.values.0, __s) + } + } + &__SerializeWith { + values: (&self.number,), + phantom: _serde::__private::PhantomData::< + SubstrateHeader, + >, + } + }, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "stateRoot", + &self.state_root, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "extrinsicsRoot", + &self.extrinsics_root, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "digest", + &self.digest, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > _serde::Deserialize<'de> for SubstrateHeader + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __field2, + __field3, + __field4, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + 2u64 => _serde::__private::Ok(__Field::__field2), + 3u64 => _serde::__private::Ok(__Field::__field3), + 4u64 => _serde::__private::Ok(__Field::__field4), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "parentHash" => _serde::__private::Ok(__Field::__field0), + "number" => _serde::__private::Ok(__Field::__field1), + "stateRoot" => _serde::__private::Ok(__Field::__field2), + "extrinsicsRoot" => _serde::__private::Ok(__Field::__field3), + "digest" => _serde::__private::Ok(__Field::__field4), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"parentHash" => _serde::__private::Ok(__Field::__field0), + b"number" => _serde::__private::Ok(__Field::__field1), + b"stateRoot" => _serde::__private::Ok(__Field::__field2), + b"extrinsicsRoot" => { + _serde::__private::Ok(__Field::__field3) + } + b"digest" => _serde::__private::Ok(__Field::__field4), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + marker: _serde::__private::PhantomData>, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > _serde::de::Visitor<'de> for __Visitor<'de, N, H> + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + type Value = SubstrateHeader; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct SubstrateHeader", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + H::Output, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + let __field1 = match { + #[doc(hidden)] + struct __DeserializeWith< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + value: N, + phantom: _serde::__private::PhantomData< + SubstrateHeader, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > _serde::Deserialize<'de> for __DeserializeWith<'de, N, H> + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: deserialize_number(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::< + __DeserializeWith<'de, N, H>, + >(&mut __seq)?, + |__wrap| __wrap.value, + ) + } { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + let __field2 = match _serde::de::SeqAccess::next_element::< + H::Output, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 2usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + let __field3 = match _serde::de::SeqAccess::next_element::< + H::Output, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 3usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + let __field4 = match _serde::de::SeqAccess::next_element::< + Digest, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 4usize, + &"struct SubstrateHeader with 5 elements", + ), + ); + } + }; + _serde::__private::Ok(SubstrateHeader { + parent_hash: __field0, + number: __field1, + state_root: __field2, + extrinsics_root: __field3, + digest: __field4, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + let mut __field2: _serde::__private::Option = _serde::__private::None; + let mut __field3: _serde::__private::Option = _serde::__private::None; + let mut __field4: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "parentHash", + ), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("number"), + ); + } + __field1 = _serde::__private::Some({ + #[doc(hidden)] + struct __DeserializeWith< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + value: N, + phantom: _serde::__private::PhantomData< + SubstrateHeader, + >, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl< + 'de, + N: Copy + Into + TryFrom, + H: Hasher, + > _serde::Deserialize<'de> for __DeserializeWith<'de, N, H> + where + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + H::Output: _serde::Deserialize<'de>, + { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::__private::Ok(__DeserializeWith { + value: deserialize_number(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + match _serde::de::MapAccess::next_value::< + __DeserializeWith<'de, N, H>, + >(&mut __map) { + _serde::__private::Ok(__wrapper) => __wrapper.value, + _serde::__private::Err(__err) => { + return _serde::__private::Err(__err); + } + } + }); + } + __Field::__field2 => { + if _serde::__private::Option::is_some(&__field2) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "stateRoot", + ), + ); + } + __field2 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field3 => { + if _serde::__private::Option::is_some(&__field3) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field( + "extrinsicsRoot", + ), + ); + } + __field3 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field4 => { + if _serde::__private::Option::is_some(&__field4) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("digest"), + ); + } + __field4 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("parentHash")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::missing_field("number"), + ); + } + }; + let __field2 = match __field2 { + _serde::__private::Some(__field2) => __field2, + _serde::__private::None => { + _serde::__private::de::missing_field("stateRoot")? + } + }; + let __field3 = match __field3 { + _serde::__private::Some(__field3) => __field3, + _serde::__private::None => { + _serde::__private::de::missing_field("extrinsicsRoot")? + } + }; + let __field4 = match __field4 { + _serde::__private::Some(__field4) => __field4, + _serde::__private::None => { + _serde::__private::de::missing_field("digest")? + } + }; + _serde::__private::Ok(SubstrateHeader { + parent_hash: __field0, + number: __field1, + state_root: __field2, + extrinsics_root: __field3, + digest: __field4, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "parentHash", + "number", + "stateRoot", + "extrinsicsRoot", + "digest", + ]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "SubstrateHeader", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::< + SubstrateHeader, + >, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + impl Header for SubstrateHeader + where + N: Copy + Into + Into + TryFrom + Encode, + H: Hasher + Encode, + SubstrateHeader: Encode + Decode, + { + type Number = N; + type Hasher = H; + fn number(&self) -> Self::Number { + self.number + } + } + /// Generic header digest. From `sp_runtime::generic::digest`. + pub struct Digest { + /// A list of digest items. + pub logs: Vec, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for Digest { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.logs) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&&self.logs, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.logs) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.logs, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike for Digest {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for Digest { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(Digest { + logs: { + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `Digest::logs`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for Digest { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Digest", + "logs", + &&self.logs, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Digest {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Digest { + #[inline] + fn eq(&self, other: &Digest) -> bool { + self.logs == other.logs + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Digest { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Digest { + #[inline] + fn clone(&self) -> Digest { + Digest { + logs: ::core::clone::Clone::clone(&self.logs), + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Digest { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + "Digest", + false as usize + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + "logs", + &self.logs, + )?; + _serde::ser::SerializeStruct::end(__serde_state) + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Digest { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "logs" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"logs" => _serde::__private::Ok(__Field::__field0), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Digest; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct Digest", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + Vec, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct Digest with 1 element", + ), + ); + } + }; + _serde::__private::Ok(Digest { logs: __field0 }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option< + Vec, + > = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("logs"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::< + Vec, + >(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("logs")? + } + }; + _serde::__private::Ok(Digest { logs: __field0 }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &["logs"]; + _serde::Deserializer::deserialize_struct( + __deserializer, + "Digest", + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + #[automatically_derived] + impl ::core::default::Default for Digest { + #[inline] + fn default() -> Digest { + Digest { + logs: ::core::default::Default::default(), + } + } + } + /// Digest item that is able to encode/decode 'system' digest items and + /// provide opaque access to other items. From `sp_runtime::generic::digest`. + pub enum DigestItem { + /// A pre-runtime digest. + /// + /// These are messages from the consensus engine to the runtime, although + /// the consensus engine can (and should) read them itself to avoid + /// code and state duplication. It is erroneous for a runtime to produce + /// these, but this is not (yet) checked. + /// + /// NOTE: the runtime is not allowed to panic or fail in an `on_initialize` + /// call if an expected `PreRuntime` digest is not present. It is the + /// responsibility of a external block verifier to check this. Runtime API calls + /// will initialize the block without pre-runtime digests, so initialization + /// cannot fail when they are missing. + PreRuntime(ConsensusEngineId, Vec), + /// A message from the runtime to the consensus engine. This should *never* + /// be generated by the native code of any consensus engine, but this is not + /// checked (yet). + Consensus(ConsensusEngineId, Vec), + /// Put a Seal on it. This is only used by native code, and is never seen + /// by runtimes. + Seal(ConsensusEngineId, Vec), + /// Some other thing. Unsupported and experimental. + Other(Vec), + /// An indication for the light clients that the runtime execution + /// environment is updated. + /// + /// Currently this is triggered when: + /// 1. Runtime code blob is changed or + /// 2. `heap_pages` value is changed. + RuntimeEnvironmentUpdated, + } + #[automatically_derived] + impl ::core::fmt::Debug for DigestItem { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + DigestItem::PreRuntime(__self_0, __self_1) => { + ::core::fmt::Formatter::debug_tuple_field2_finish( + f, + "PreRuntime", + __self_0, + &__self_1, + ) + } + DigestItem::Consensus(__self_0, __self_1) => { + ::core::fmt::Formatter::debug_tuple_field2_finish( + f, + "Consensus", + __self_0, + &__self_1, + ) + } + DigestItem::Seal(__self_0, __self_1) => { + ::core::fmt::Formatter::debug_tuple_field2_finish( + f, + "Seal", + __self_0, + &__self_1, + ) + } + DigestItem::Other(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Other", + &__self_0, + ) + } + DigestItem::RuntimeEnvironmentUpdated => { + ::core::fmt::Formatter::write_str(f, "RuntimeEnvironmentUpdated") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DigestItem {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DigestItem { + #[inline] + fn eq(&self, other: &DigestItem) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + DigestItem::PreRuntime(__self_0, __self_1), + DigestItem::PreRuntime(__arg1_0, __arg1_1), + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + ( + DigestItem::Consensus(__self_0, __self_1), + DigestItem::Consensus(__arg1_0, __arg1_1), + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + ( + DigestItem::Seal(__self_0, __self_1), + DigestItem::Seal(__arg1_0, __arg1_1), + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + (DigestItem::Other(__self_0), DigestItem::Other(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DigestItem { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::clone::Clone for DigestItem { + #[inline] + fn clone(&self) -> DigestItem { + match self { + DigestItem::PreRuntime(__self_0, __self_1) => { + DigestItem::PreRuntime( + ::core::clone::Clone::clone(__self_0), + ::core::clone::Clone::clone(__self_1), + ) + } + DigestItem::Consensus(__self_0, __self_1) => { + DigestItem::Consensus( + ::core::clone::Clone::clone(__self_0), + ::core::clone::Clone::clone(__self_1), + ) + } + DigestItem::Seal(__self_0, __self_1) => { + DigestItem::Seal( + ::core::clone::Clone::clone(__self_0), + ::core::clone::Clone::clone(__self_1), + ) + } + DigestItem::Other(__self_0) => { + DigestItem::Other(::core::clone::Clone::clone(__self_0)) + } + DigestItem::RuntimeEnvironmentUpdated => { + DigestItem::RuntimeEnvironmentUpdated + } + } + } + } + #[repr(u32)] + enum DigestItemType { + Other = 0u32, + Consensus = 4u32, + Seal = 5u32, + PreRuntime = 6u32, + RuntimeEnvironmentUpdated = 8u32, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for DigestItemType { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + DigestItemType::Other => 0_usize, + DigestItemType::Consensus => 0_usize, + DigestItemType::Seal => 0_usize, + DigestItemType::PreRuntime => 0_usize, + DigestItemType::RuntimeEnvironmentUpdated => 0_usize, + _ => 0_usize, + } + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + match *self { + DigestItemType::Other => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(0u32 as ::core::primitive::u8); + } + DigestItemType::Consensus => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(4u32 as ::core::primitive::u8); + } + DigestItemType::Seal => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(5u32 as ::core::primitive::u8); + } + DigestItemType::PreRuntime => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(6u32 as ::core::primitive::u8); + } + DigestItemType::RuntimeEnvironmentUpdated => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(8u32 as ::core::primitive::u8); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::codec::EncodeLike for DigestItemType {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for DigestItemType { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `DigestItemType`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(DigestItemType::Other) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 4u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(DigestItemType::Consensus) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 5u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(DigestItemType::Seal) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 6u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(DigestItemType::PreRuntime) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 8u32 as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + DigestItemType::RuntimeEnvironmentUpdated, + ) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `DigestItemType`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + impl Encode for DigestItem { + fn encode(&self) -> Vec { + let mut v = Vec::new(); + match self { + Self::Consensus(val, data) => { + DigestItemType::Consensus.encode_to(&mut v); + (val, data).encode_to(&mut v); + } + Self::Seal(val, sig) => { + DigestItemType::Seal.encode_to(&mut v); + (val, sig).encode_to(&mut v); + } + Self::PreRuntime(val, data) => { + DigestItemType::PreRuntime.encode_to(&mut v); + (val, data).encode_to(&mut v); + } + Self::Other(val) => { + DigestItemType::Other.encode_to(&mut v); + val.encode_to(&mut v); + } + Self::RuntimeEnvironmentUpdated => { + DigestItemType::RuntimeEnvironmentUpdated.encode_to(&mut v); + } + } + v + } + } + impl Decode for DigestItem { + fn decode(input: &mut I) -> Result { + let item_type: DigestItemType = Decode::decode(input)?; + match item_type { + DigestItemType::PreRuntime => { + let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; + Ok(Self::PreRuntime(vals.0, vals.1)) + } + DigestItemType::Consensus => { + let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; + Ok(Self::Consensus(vals.0, vals.1)) + } + DigestItemType::Seal => { + let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; + Ok(Self::Seal(vals.0, vals.1)) + } + DigestItemType::Other => Ok(Self::Other(Decode::decode(input)?)), + DigestItemType::RuntimeEnvironmentUpdated => { + Ok(Self::RuntimeEnvironmentUpdated) + } + } + } + } + /// Consensus engine unique ID. From `sp_runtime::ConsensusEngineId`. + pub type ConsensusEngineId = [u8; 4]; + impl serde::Serialize for DigestItem { + fn serialize(&self, seq: S) -> Result + where + S: serde::Serializer, + { + self.using_encoded(|bytes| impl_serde::serialize::serialize(bytes, seq)) + } + } + impl<'a> serde::Deserialize<'a> for DigestItem { + fn deserialize(de: D) -> Result + where + D: serde::Deserializer<'a>, + { + let r = impl_serde::serialize::deserialize(de)?; + Decode::decode(&mut &r[..]) + .map_err(|e| serde::de::Error::custom({ + let res = ::alloc::fmt::format( + format_args!("Decode error: {0}", e), + ); + res + })) + } + } + fn serialize_number>( + val: &T, + s: S, + ) -> Result + where + S: serde::Serializer, + { + let u256: U256 = (*val).into(); + serde::Serialize::serialize(&u256, s) + } + fn deserialize_number<'a, D, T: TryFrom>(d: D) -> Result + where + D: serde::Deserializer<'a>, + { + use crate::backend::legacy::rpc_methods::NumberOrHex; + let number_or_hex = NumberOrHex::deserialize(d)?; + let u256 = number_or_hex.into_u256(); + TryFrom::try_from(u256) + .map_err(|_| serde::de::Error::custom("Try from failed")) + } + } + use crate::macros::cfg_substrate_compat; + use codec::{Decode, Encode}; + use core::fmt::Debug; + use scale_decode::DecodeAsType; + use scale_encode::EncodeAsType; + use serde::{de::DeserializeOwned, Serialize}; + pub use default_extrinsic_params::{ + DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, + }; + pub use extrinsic_params::{ + ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, + }; + pub use polkadot::{ + PolkadotConfig, PolkadotExtrinsicParams, PolkadotExtrinsicParamsBuilder, + }; + pub use signed_extensions::SignedExtension; + pub use substrate::{ + SubstrateConfig, SubstrateExtrinsicParams, SubstrateExtrinsicParamsBuilder, + }; + /// Runtime types. + pub trait Config: Sized + Send + Sync + 'static { + /// The output of the `Hasher` function. + type Hash: BlockHash; + /// The account ID type. + type AccountId: Debug + Clone + Encode; + /// The address type. + type Address: Debug + Encode + From; + /// The signature type. + type Signature: Debug + Encode; + /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). + type Hasher: Debug + Hasher; + /// The block header. + type Header: Debug + + Header + + Sync + + Send + + DeserializeOwned; + /// This type defines the extrinsic extra and additional parameters. + type ExtrinsicParams: ExtrinsicParams; + /// This is used to identify an asset in the `ChargeAssetTxPayment` signed extension. + type AssetId: Debug + Clone + Encode + DecodeAsType + EncodeAsType; + } + /// given some [`Config`], this return the other params needed for its `ExtrinsicParams`. + pub type OtherParamsFor = <::ExtrinsicParams as ExtrinsicParams< + T, + >>::OtherParams; + /// Block hashes must conform to a bunch of things to be used in Subxt. + pub trait BlockHash: Debug + Copy + Send + Sync + Decode + AsRef< + [u8], + > + Serialize + DeserializeOwned + Encode + PartialEq + Eq + std::hash::Hash {} + impl BlockHash for T + where + T: Debug + Copy + Send + Sync + Decode + AsRef<[u8]> + Serialize + + DeserializeOwned + Encode + PartialEq + Eq + std::hash::Hash, + {} + /// This represents the hasher used by a node to hash things like block headers + /// and extrinsics. + pub trait Hasher { + /// The type given back from the hash operation + type Output; + /// Hash some bytes to the given output type. + fn hash(s: &[u8]) -> Self::Output; + /// Hash some SCALE encodable type to the given output type. + fn hash_of(s: &S) -> Self::Output { + let out = s.encode(); + Self::hash(&out) + } + } + /// This represents the block header type used by a node. + pub trait Header: Sized + Encode + Decode { + /// The block number type for this header. + type Number: Into; + /// The hasher used to hash this header. + type Hasher: Hasher; + /// Return the block number of this header. + fn number(&self) -> Self::Number; + /// Hash this header. + fn hash(&self) -> ::Output { + Self::Hasher::hash_of(self) + } + } +} +pub mod constants { + //! Types associated with accessing constants. + mod constant_address { + use crate::{dynamic::DecodedValueThunk, metadata::DecodeWithMetadata}; + use derivative::Derivative; + use std::borrow::Cow; + /// This represents a constant address. Anything implementing this trait + /// can be used to fetch constants. + pub trait ConstantAddress { + /// The target type of the value that lives at this address. + type Target: DecodeWithMetadata; + /// The name of the pallet that the constant lives under. + fn pallet_name(&self) -> &str; + /// The name of the constant in a given pallet. + fn constant_name(&self) -> &str; + /// An optional hash which, if present, will be checked against + /// the node metadata to confirm that the return type matches what + /// we are expecting. + fn validation_hash(&self) -> Option<[u8; 32]> { + None + } + } + /// This represents the address of a constant. + #[derivative( + Clone(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + Ord(bound = ""), + PartialEq(bound = "") + )] + pub struct Address { + pallet_name: Cow<'static, str>, + constant_name: Cow<'static, str>, + constant_hash: Option<[u8; 32]>, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Address { + fn clone(&self) -> Self { + match *self { + Address { + pallet_name: ref __arg_0, + constant_name: ref __arg_1, + constant_hash: ref __arg_2, + _marker: ref __arg_3, + } => { + Address { + pallet_name: (*__arg_0).clone(), + constant_name: (*__arg_1).clone(), + constant_hash: (*__arg_2).clone(), + _marker: (*__arg_3).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Address { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Address { + pallet_name: ref __arg_0, + constant_name: ref __arg_1, + constant_hash: ref __arg_2, + _marker: ref __arg_3, + } => { + let mut __debug_trait_builder = __f.debug_struct("Address"); + let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); + let _ = __debug_trait_builder + .field("constant_name", &&(*__arg_1)); + let _ = __debug_trait_builder + .field("constant_hash", &&(*__arg_2)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_3)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for Address {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for Address { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + Address { + pallet_name: ref __self_0, + constant_name: ref __self_1, + constant_hash: ref __self_2, + _marker: ref __self_3, + } => { + match *other { + Address { + pallet_name: ref __other_0, + constant_name: ref __other_1, + constant_hash: ref __other_2, + _marker: ref __other_3, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + && &(*__self_3) == &(*__other_3) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::Ord for Address { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + Address { + pallet_name: ref __self_0, + constant_name: ref __self_1, + constant_hash: ref __self_2, + _marker: ref __self_3, + } => { + match *other { + Address { + pallet_name: ref __other_0, + constant_name: ref __other_1, + constant_hash: ref __other_2, + _marker: ref __other_3, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + impl PartialOrd for Address { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + /// The type of address typically used to return dynamic constant values. + pub type DynamicAddress = Address; + impl Address { + /// Create a new [`Address`] to use to look up a constant. + pub fn new( + pallet_name: impl Into, + constant_name: impl Into, + ) -> Self { + Self { + pallet_name: Cow::Owned(pallet_name.into()), + constant_name: Cow::Owned(constant_name.into()), + constant_hash: None, + _marker: std::marker::PhantomData, + } + } + /// Create a new [`Address`] that will be validated + /// against node metadata using the hash given. + #[doc(hidden)] + pub fn new_static( + pallet_name: &'static str, + constant_name: &'static str, + hash: [u8; 32], + ) -> Self { + Self { + pallet_name: Cow::Borrowed(pallet_name), + constant_name: Cow::Borrowed(constant_name), + constant_hash: Some(hash), + _marker: std::marker::PhantomData, + } + } + /// Do not validate this constant prior to accessing it. + pub fn unvalidated(self) -> Self { + Self { + pallet_name: self.pallet_name, + constant_name: self.constant_name, + constant_hash: None, + _marker: self._marker, + } + } + } + impl ConstantAddress for Address { + type Target = ReturnTy; + fn pallet_name(&self) -> &str { + &self.pallet_name + } + fn constant_name(&self) -> &str { + &self.constant_name + } + fn validation_hash(&self) -> Option<[u8; 32]> { + self.constant_hash + } + } + /// Construct a new dynamic constant lookup. + pub fn dynamic( + pallet_name: impl Into, + constant_name: impl Into, + ) -> DynamicAddress { + DynamicAddress::new(pallet_name, constant_name) + } + } + mod constants_client { + use super::ConstantAddress; + use crate::{ + client::OfflineClientT, error::{Error, MetadataError}, + metadata::DecodeWithMetadata, Config, + }; + use derivative::Derivative; + /// A client for accessing constants. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct ConstantsClient { + client: Client, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for ConstantsClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + ConstantsClient { client: ref __arg_0, _marker: ref __arg_1 } => { + ConstantsClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl ConstantsClient { + /// Create a new [`ConstantsClient`]. + pub fn new(client: Client) -> Self { + Self { + client, + _marker: std::marker::PhantomData, + } + } + } + impl> ConstantsClient { + /// Run the validation logic against some constant address you'd like to access. Returns `Ok(())` + /// if the address is valid (or if it's not possible to check since the address has no validation hash). + /// Return an error if the address was not valid or something went wrong trying to validate it (ie + /// the pallet or constant in question do not exist at all). + pub fn validate( + &self, + address: &Address, + ) -> Result<(), Error> { + if let Some(actual_hash) = address.validation_hash() { + let expected_hash = self + .client + .metadata() + .pallet_by_name_err(address.pallet_name())? + .constant_hash(address.constant_name()) + .ok_or_else(|| { + MetadataError::ConstantNameNotFound( + address.constant_name().to_owned(), + ) + })?; + if actual_hash != expected_hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + } + Ok(()) + } + /// Access the constant at the address given, returning the type defined by this address. + /// This is probably used with addresses given from static codegen, although you can manually + /// construct your own, too. + pub fn at( + &self, + address: &Address, + ) -> Result { + let metadata = self.client.metadata(); + self.validate(address)?; + let constant = metadata + .pallet_by_name_err(address.pallet_name())? + .constant_by_name(address.constant_name()) + .ok_or_else(|| { + MetadataError::ConstantNameNotFound( + address.constant_name().to_owned(), + ) + })?; + let value = ::decode_with_metadata( + &mut constant.value(), + constant.ty(), + &metadata, + )?; + Ok(value) + } + } + } + pub use constant_address::{dynamic, Address, ConstantAddress, DynamicAddress}; + pub use constants_client::ConstantsClient; +} +pub mod custom_values { + //! Types associated with accessing custom types + mod custom_value_address { + use derivative::Derivative; + use std::marker::PhantomData; + use crate::dynamic::DecodedValueThunk; + use crate::metadata::DecodeWithMetadata; + /// This represents the address of a custom value in in the metadata. + /// Anything, that implements the [CustomValueAddress] trait can be used, to fetch + /// custom values from the metadata. + /// The trait is implemented by [str] for dynamic loopup and [StaticAddress] for static queries. + pub trait CustomValueAddress { + /// The type of the custom value. + type Target: DecodeWithMetadata; + /// Should be set to `Yes` for Dynamic values and static values that have a valid type. + /// Should be `()` for custom values, that have an invalid type id. + type IsDecodable; + /// the name (key) by which the custom value can be accessed in the metadata. + fn name(&self) -> &str; + /// An optional hash which, if present, can be checked against node metadata. + fn validation_hash(&self) -> Option<[u8; 32]> { + None + } + } + impl CustomValueAddress for str { + type Target = DecodedValueThunk; + type IsDecodable = Yes; + fn name(&self) -> &str { + self + } + } + /// Used to signal whether a [`CustomValueAddress`] can be decoded. + pub struct Yes; + /// A static address to a custom value. + #[derivative( + Clone(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + Ord(bound = ""), + PartialEq(bound = "") + )] + pub struct StaticAddress { + name: &'static str, + hash: Option<[u8; 32]>, + phantom: PhantomData<(ReturnTy, IsDecodable)>, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone + for StaticAddress { + fn clone(&self) -> Self { + match *self { + StaticAddress { + name: ref __arg_0, + hash: ref __arg_1, + phantom: ref __arg_2, + } => { + StaticAddress { + name: (*__arg_0).clone(), + hash: (*__arg_1).clone(), + phantom: (*__arg_2).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug + for StaticAddress { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + StaticAddress { + name: ref __arg_0, + hash: ref __arg_1, + phantom: ref __arg_2, + } => { + let mut __debug_trait_builder = __f + .debug_struct("StaticAddress"); + let _ = __debug_trait_builder.field("name", &&(*__arg_0)); + let _ = __debug_trait_builder.field("hash", &&(*__arg_1)); + let _ = __debug_trait_builder.field("phantom", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq + for StaticAddress {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq + for StaticAddress { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + StaticAddress { + name: ref __self_0, + hash: ref __self_1, + phantom: ref __self_2, + } => { + match *other { + StaticAddress { + name: ref __other_0, + hash: ref __other_1, + phantom: ref __other_2, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::Ord + for StaticAddress { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + StaticAddress { + name: ref __self_0, + hash: ref __self_1, + phantom: ref __self_2, + } => { + match *other { + StaticAddress { + name: ref __other_0, + hash: ref __other_1, + phantom: ref __other_2, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + impl PartialOrd for StaticAddress { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + impl StaticAddress { + #[doc(hidden)] + /// Creates a new StaticAddress. + pub fn new_static( + name: &'static str, + hash: [u8; 32], + ) -> StaticAddress { + StaticAddress:: { + name, + hash: Some(hash), + phantom: PhantomData, + } + } + /// Do not validate this custom value prior to accessing it. + pub fn unvalidated(self) -> Self { + Self { + name: self.name, + hash: None, + phantom: self.phantom, + } + } + } + impl CustomValueAddress for StaticAddress { + type Target = R; + type IsDecodable = Y; + fn name(&self) -> &str { + self.name + } + fn validation_hash(&self) -> Option<[u8; 32]> { + self.hash + } + } + } + mod custom_values_client { + use crate::client::OfflineClientT; + use crate::custom_values::custom_value_address::{CustomValueAddress, Yes}; + use crate::error::MetadataError; + use crate::metadata::DecodeWithMetadata; + use crate::{Config, Error}; + use derivative::Derivative; + /// A client for accessing custom values stored in the metadata. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct CustomValuesClient { + client: Client, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for CustomValuesClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + CustomValuesClient { client: ref __arg_0, _marker: ref __arg_1 } => { + CustomValuesClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl CustomValuesClient { + /// Create a new [`CustomValuesClient`]. + pub fn new(client: Client) -> Self { + Self { + client, + _marker: std::marker::PhantomData, + } + } + } + impl> CustomValuesClient { + /// Access a custom value by the address it is registered under. This can be just a [str] to get back a dynamic value, + /// or a static address from the generated static interface to get a value of a static type returned. + pub fn at + ?Sized>( + &self, + address: &Address, + ) -> Result { + self.validate(address)?; + let metadata = self.client.metadata(); + let custom = metadata.custom(); + let custom_value = custom + .get(address.name()) + .ok_or_else(|| MetadataError::CustomValueNameNotFound( + address.name().to_string(), + ))?; + let value = ::decode_with_metadata( + &mut custom_value.bytes(), + custom_value.type_id(), + &metadata, + )?; + Ok(value) + } + /// Access the bytes of a custom value by the address it is registered under. + pub fn bytes_at( + &self, + address: &Address, + ) -> Result, Error> { + self.validate(address)?; + let metadata = self.client.metadata(); + let custom = metadata.custom(); + let custom_value = custom + .get(address.name()) + .ok_or_else(|| MetadataError::CustomValueNameNotFound( + address.name().to_string(), + ))?; + Ok(custom_value.bytes().to_vec()) + } + /// Run the validation logic against some custom value address you'd like to access. Returns `Ok(())` + /// if the address is valid (or if it's not possible to check since the address has no validation hash). + /// Returns an error if the address was not valid (wrong name, type or raw bytes) + pub fn validate( + &self, + address: &Address, + ) -> Result<(), Error> { + let metadata = self.client.metadata(); + if let Some(actual_hash) = address.validation_hash() { + let custom = metadata.custom(); + let custom_value = custom + .get(address.name()) + .ok_or_else(|| MetadataError::CustomValueNameNotFound( + address.name().into(), + ))?; + let expected_hash = custom_value.hash(); + if actual_hash != expected_hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + } + if metadata.custom().get(address.name()).is_none() { + return Err(MetadataError::IncompatibleCodegen.into()); + } + Ok(()) + } + } + } + pub use custom_value_address::{CustomValueAddress, StaticAddress, Yes}; + pub use custom_values_client::CustomValuesClient; +} +pub mod dynamic { + //! This module provides the entry points to create dynamic + //! transactions, storage and constant lookups. + use crate::{error::Error, metadata::{DecodeWithMetadata, Metadata}}; + use scale_decode::DecodeAsType; + pub use scale_value::{At, Value}; + /// A [`scale_value::Value`] type endowed with contextual information + /// regarding what type was used to decode each part of it. This implements + /// [`crate::metadata::DecodeWithMetadata`], and is used as a return type + /// for dynamic requests. + pub type DecodedValue = scale_value::Value; + pub use crate::tx::dynamic as tx; + pub use crate::constants::dynamic as constant; + pub use crate::storage::dynamic as storage; + pub use crate::runtime_api::dynamic as runtime_api_call; + /// This is the result of making a dynamic request to a node. From this, + /// we can return the raw SCALE bytes that we were handed back, or we can + /// complete the decoding of the bytes into a [`DecodedValue`] type. + pub struct DecodedValueThunk { + type_id: u32, + metadata: Metadata, + scale_bytes: Vec, + } + impl DecodeWithMetadata for DecodedValueThunk { + fn decode_with_metadata( + bytes: &mut &[u8], + type_id: u32, + metadata: &Metadata, + ) -> Result { + let mut v = Vec::with_capacity(bytes.len()); + v.extend_from_slice(bytes); + *bytes = &[]; + Ok(DecodedValueThunk { + type_id, + metadata: metadata.clone(), + scale_bytes: v, + }) + } + } + impl DecodedValueThunk { + /// Return the SCALE encoded bytes handed back from the node. + pub fn into_encoded(self) -> Vec { + self.scale_bytes + } + /// Return the SCALE encoded bytes handed back from the node without taking ownership of them. + pub fn encoded(&self) -> &[u8] { + &self.scale_bytes + } + /// Decode the SCALE encoded storage entry into a dynamic [`DecodedValue`] type. + pub fn to_value(&self) -> Result { + let val = DecodedValue::decode_as_type( + &mut &*self.scale_bytes, + self.type_id, + self.metadata.types(), + )?; + Ok(val) + } + /// decode the `DecodedValueThunk` into a concrete type. + pub fn as_type(&self) -> Result { + T::decode_as_type( + &mut &self.scale_bytes[..], + self.type_id, + self.metadata.types(), + ) + } + } +} +pub mod error { + //! Types representing the errors that can be returned. + mod dispatch_error { + //! A representation of the dispatch error; an error returned when + //! something fails in trying to submit/execute a transaction. + use crate::metadata::{DecodeWithMetadata, Metadata}; + use core::fmt::Debug; + use scale_decode::{visitor::DecodeAsTypeResult, DecodeAsType}; + use std::borrow::Cow; + use super::{Error, MetadataError}; + /// An error dispatching a transaction. + #[non_exhaustive] + pub enum DispatchError { + /// Some error occurred. + #[error("Some unknown error occurred.")] + Other, + /// Failed to lookup some data. + #[error("Failed to lookup some data.")] + CannotLookup, + /// A bad origin. + #[error("Bad origin.")] + BadOrigin, + /// A custom error in a module. + #[error("Pallet error: {0}")] + Module(ModuleError), + /// At least one consumer is remaining so the account cannot be destroyed. + #[error( + "At least one consumer is remaining so the account cannot be destroyed." + )] + ConsumerRemaining, + /// There are no providers so the account cannot be created. + #[error("There are no providers so the account cannot be created.")] + NoProviders, + /// There are too many consumers so the account cannot be created. + #[error("There are too many consumers so the account cannot be created.")] + TooManyConsumers, + /// An error to do with tokens. + #[error("Token error: {0}")] + Token(TokenError), + /// An arithmetic error. + #[error("Arithmetic error: {0}")] + Arithmetic(ArithmeticError), + /// The number of transactional layers has been reached, or we are not in a transactional layer. + #[error("Transactional error: {0}")] + Transactional(TransactionalError), + /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. + #[error( + "Resources exhausted, e.g. attempt to read/write data which is too large to manipulate." + )] + Exhausted, + /// The state is corrupt; this is generally not going to fix itself. + #[error("The state is corrupt; this is generally not going to fix itself.")] + Corruption, + /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. + #[error( + "Some resource (e.g. a preimage) is unavailable right now. This might fix itself later." + )] + Unavailable, + } + #[automatically_derived] + impl ::core::fmt::Debug for DispatchError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + DispatchError::Other => ::core::fmt::Formatter::write_str(f, "Other"), + DispatchError::CannotLookup => { + ::core::fmt::Formatter::write_str(f, "CannotLookup") + } + DispatchError::BadOrigin => { + ::core::fmt::Formatter::write_str(f, "BadOrigin") + } + DispatchError::Module(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Module", + &__self_0, + ) + } + DispatchError::ConsumerRemaining => { + ::core::fmt::Formatter::write_str(f, "ConsumerRemaining") + } + DispatchError::NoProviders => { + ::core::fmt::Formatter::write_str(f, "NoProviders") + } + DispatchError::TooManyConsumers => { + ::core::fmt::Formatter::write_str(f, "TooManyConsumers") + } + DispatchError::Token(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Token", + &__self_0, + ) + } + DispatchError::Arithmetic(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Arithmetic", + &__self_0, + ) + } + DispatchError::Transactional(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Transactional", + &__self_0, + ) + } + DispatchError::Exhausted => { + ::core::fmt::Formatter::write_str(f, "Exhausted") + } + DispatchError::Corruption => { + ::core::fmt::Formatter::write_str(f, "Corruption") + } + DispatchError::Unavailable => { + ::core::fmt::Formatter::write_str(f, "Unavailable") + } + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for DispatchError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for DispatchError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + DispatchError::Other {} => { + __formatter.write_str("Some unknown error occurred.") + } + DispatchError::CannotLookup {} => { + __formatter.write_str("Failed to lookup some data.") + } + DispatchError::BadOrigin {} => __formatter.write_str("Bad origin."), + DispatchError::Module(_0) => { + __formatter + .write_fmt( + format_args!("Pallet error: {0}", _0.as_display()), + ) + } + DispatchError::ConsumerRemaining {} => { + __formatter + .write_str( + "At least one consumer is remaining so the account cannot be destroyed.", + ) + } + DispatchError::NoProviders {} => { + __formatter + .write_str( + "There are no providers so the account cannot be created.", + ) + } + DispatchError::TooManyConsumers {} => { + __formatter + .write_str( + "There are too many consumers so the account cannot be created.", + ) + } + DispatchError::Token(_0) => { + __formatter + .write_fmt(format_args!("Token error: {0}", _0.as_display())) + } + DispatchError::Arithmetic(_0) => { + __formatter + .write_fmt( + format_args!("Arithmetic error: {0}", _0.as_display()), + ) + } + DispatchError::Transactional(_0) => { + __formatter + .write_fmt( + format_args!("Transactional error: {0}", _0.as_display()), + ) + } + DispatchError::Exhausted {} => { + __formatter + .write_str( + "Resources exhausted, e.g. attempt to read/write data which is too large to manipulate.", + ) + } + DispatchError::Corruption {} => { + __formatter + .write_str( + "The state is corrupt; this is generally not going to fix itself.", + ) + } + DispatchError::Unavailable {} => { + __formatter + .write_str( + "Some resource (e.g. a preimage) is unavailable right now. This might fix itself later.", + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for DispatchError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for DispatchError { + #[inline] + fn eq(&self, other: &DispatchError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + DispatchError::Module(__self_0), + DispatchError::Module(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + DispatchError::Token(__self_0), + DispatchError::Token(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + DispatchError::Arithmetic(__self_0), + DispatchError::Arithmetic(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + DispatchError::Transactional(__self_0), + DispatchError::Transactional(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for DispatchError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + /// An error relating to tokens when dispatching a transaction. + #[non_exhaustive] + pub enum TokenError { + /// Funds are unavailable. + #[error("Funds are unavailable.")] + FundsUnavailable, + /// Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved. + #[error( + "Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved." + )] + OnlyProvider, + /// Account cannot exist with the funds that would be given. + #[error("Account cannot exist with the funds that would be given.")] + BelowMinimum, + /// Account cannot be created. + #[error("Account cannot be created.")] + CannotCreate, + /// The asset in question is unknown. + #[error("The asset in question is unknown.")] + UnknownAsset, + /// Funds exist but are frozen. + #[error("Funds exist but are frozen.")] + Frozen, + /// Operation is not supported by the asset. + #[error("Operation is not supported by the asset.")] + Unsupported, + /// Account cannot be created for a held balance. + #[error("Account cannot be created for a held balance.")] + CannotCreateHold, + /// Withdrawal would cause unwanted loss of account. + #[error("Withdrawal would cause unwanted loss of account.")] + NotExpendable, + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for TokenError { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = TokenError; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "FundsUnavailable" { + return Ok(TokenError::FundsUnavailable); + } + if value.name() == "OnlyProvider" { + return Ok(TokenError::OnlyProvider); + } + if value.name() == "BelowMinimum" { + return Ok(TokenError::BelowMinimum); + } + if value.name() == "CannotCreate" { + return Ok(TokenError::CannotCreate); + } + if value.name() == "UnknownAsset" { + return Ok(TokenError::UnknownAsset); + } + if value.name() == "Frozen" { + return Ok(TokenError::Frozen); + } + if value.name() == "Unsupported" { + return Ok(TokenError::Unsupported); + } + if value.name() == "CannotCreateHold" { + return Ok(TokenError::CannotCreateHold); + } + if value.name() == "NotExpendable" { + return Ok(TokenError::NotExpendable); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + "FundsUnavailable", + "OnlyProvider", + "BelowMinimum", + "CannotCreate", + "UnknownAsset", + "Frozen", + "Unsupported", + "CannotCreateHold", + "NotExpendable", + ]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for TokenError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + TokenError::FundsUnavailable => "FundsUnavailable", + TokenError::OnlyProvider => "OnlyProvider", + TokenError::BelowMinimum => "BelowMinimum", + TokenError::CannotCreate => "CannotCreate", + TokenError::UnknownAsset => "UnknownAsset", + TokenError::Frozen => "Frozen", + TokenError::Unsupported => "Unsupported", + TokenError::CannotCreateHold => "CannotCreateHold", + TokenError::NotExpendable => "NotExpendable", + }, + ) + } + } + #[allow(unused_qualifications)] + impl std::error::Error for TokenError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for TokenError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + TokenError::FundsUnavailable {} => { + __formatter.write_str("Funds are unavailable.") + } + TokenError::OnlyProvider {} => { + __formatter + .write_str( + "Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved.", + ) + } + TokenError::BelowMinimum {} => { + __formatter + .write_str( + "Account cannot exist with the funds that would be given.", + ) + } + TokenError::CannotCreate {} => { + __formatter.write_str("Account cannot be created.") + } + TokenError::UnknownAsset {} => { + __formatter.write_str("The asset in question is unknown.") + } + TokenError::Frozen {} => { + __formatter.write_str("Funds exist but are frozen.") + } + TokenError::Unsupported {} => { + __formatter.write_str("Operation is not supported by the asset.") + } + TokenError::CannotCreateHold {} => { + __formatter + .write_str("Account cannot be created for a held balance.") + } + TokenError::NotExpendable {} => { + __formatter + .write_str( + "Withdrawal would cause unwanted loss of account.", + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TokenError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TokenError { + #[inline] + fn eq(&self, other: &TokenError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TokenError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + /// An error relating to arithmetic when dispatching a transaction. + #[non_exhaustive] + pub enum ArithmeticError { + /// Underflow. + #[error("Underflow.")] + Underflow, + /// Overflow. + #[error("Overflow.")] + Overflow, + /// Division by zero. + #[error("Division by zero.")] + DivisionByZero, + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for ArithmeticError { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = ArithmeticError; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "Underflow" { + return Ok(ArithmeticError::Underflow); + } + if value.name() == "Overflow" { + return Ok(ArithmeticError::Overflow); + } + if value.name() == "DivisionByZero" { + return Ok(ArithmeticError::DivisionByZero); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + "Underflow", + "Overflow", + "DivisionByZero", + ]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for ArithmeticError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + ArithmeticError::Underflow => "Underflow", + ArithmeticError::Overflow => "Overflow", + ArithmeticError::DivisionByZero => "DivisionByZero", + }, + ) + } + } + #[allow(unused_qualifications)] + impl std::error::Error for ArithmeticError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for ArithmeticError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + ArithmeticError::Underflow {} => __formatter.write_str("Underflow."), + ArithmeticError::Overflow {} => __formatter.write_str("Overflow."), + ArithmeticError::DivisionByZero {} => { + __formatter.write_str("Division by zero.") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ArithmeticError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ArithmeticError { + #[inline] + fn eq(&self, other: &ArithmeticError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + impl ::core::cmp::Eq for ArithmeticError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + /// An error relating to thr transactional layers when dispatching a transaction. + #[non_exhaustive] + pub enum TransactionalError { + /// Too many transactional layers have been spawned. + #[error("Too many transactional layers have been spawned.")] + LimitReached, + /// A transactional layer was expected, but does not exist. + #[error("A transactional layer was expected, but does not exist.")] + NoLayer, + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for TransactionalError { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = TransactionalError; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "LimitReached" { + return Ok(TransactionalError::LimitReached); + } + if value.name() == "NoLayer" { + return Ok(TransactionalError::NoLayer); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new(["LimitReached", "NoLayer"]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for TransactionalError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + TransactionalError::LimitReached => "LimitReached", + TransactionalError::NoLayer => "NoLayer", + }, + ) + } + } + #[allow(unused_qualifications)] + impl std::error::Error for TransactionalError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for TransactionalError { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + TransactionalError::LimitReached {} => { + __formatter + .write_str( + "Too many transactional layers have been spawned.", + ) + } + TransactionalError::NoLayer {} => { + __formatter + .write_str( + "A transactional layer was expected, but does not exist.", + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionalError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionalError { + #[inline] + fn eq(&self, other: &TransactionalError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TransactionalError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + /// Details about a module error that has occurred. + #[non_exhaustive] + pub struct ModuleError { + metadata: Metadata, + /// Bytes representation: + /// - `bytes[0]`: pallet index + /// - `bytes[1]`: error index + /// - `bytes[2..]`: 3 bytes specific for the module error + bytes: [u8; 5], + } + #[automatically_derived] + impl ::core::clone::Clone for ModuleError { + #[inline] + fn clone(&self) -> ModuleError { + ModuleError { + metadata: ::core::clone::Clone::clone(&self.metadata), + bytes: ::core::clone::Clone::clone(&self.bytes), + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for ModuleError {} + impl PartialEq for ModuleError { + fn eq(&self, other: &Self) -> bool { + self.bytes == other.bytes + } + } + impl Eq for ModuleError {} + /// Custom `Debug` implementation, ignores the very large `metadata` field, using it instead (as + /// intended) to resolve the actual pallet and error names. This is much more useful for debugging. + impl Debug for ModuleError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let details = self.details_string(); + f.write_fmt(format_args!("ModuleError(<{0}>)", details)) + } + } + impl std::fmt::Display for ModuleError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let details = self.details_string(); + f.write_fmt(format_args!("{0}", details)) + } + } + impl ModuleError { + /// Return more details about this error. + pub fn details(&self) -> Result { + let pallet = self.metadata.pallet_by_index_err(self.pallet_index())?; + let variant = pallet + .error_variant_by_index(self.error_index()) + .ok_or_else(|| MetadataError::VariantIndexNotFound( + self.error_index(), + ))?; + Ok(ModuleErrorDetails { + pallet, + variant, + }) + } + /// Return a formatted string of the resolved error details for debugging/display purposes. + pub fn details_string(&self) -> String { + match self.details() { + Ok(details) => { + let res = ::alloc::fmt::format( + format_args!( + "{0}::{1}", details.pallet.name(), details.variant.name + ), + ); + res + } + Err(_) => { + let res = ::alloc::fmt::format( + format_args!( + "Unknown pallet error \'{0:?}\' (pallet and error details cannot be retrieved)", + self.bytes + ), + ); + res + } + } + } + /// Return the underlying module error data that was decoded. + pub fn bytes(&self) -> [u8; 5] { + self.bytes + } + /// Obtain the pallet index from the underlying byte data. + pub fn pallet_index(&self) -> u8 { + self.bytes[0] + } + /// Obtain the error index from the underlying byte data. + pub fn error_index(&self) -> u8 { + self.bytes[1] + } + /// Attempts to decode the ModuleError into the top outer Error enum. + pub fn as_root_error(&self) -> Result { + let decoded = E::decode_as_type( + &mut &self.bytes[..], + self.metadata.outer_enums().error_enum_ty(), + self.metadata.types(), + )?; + Ok(decoded) + } + } + /// Details about the module error. + pub struct ModuleErrorDetails<'a> { + /// The pallet that the error is in + pub pallet: crate::metadata::types::PalletMetadata<'a>, + /// The variant representing the error + pub variant: &'a scale_info::Variant, + } + impl DispatchError { + /// Attempt to decode a runtime [`DispatchError`]. + #[doc(hidden)] + pub fn decode_from<'a>( + bytes: impl Into>, + metadata: Metadata, + ) -> Result { + let bytes = bytes.into(); + let dispatch_error_ty_id = metadata + .dispatch_error_ty() + .ok_or(MetadataError::DispatchErrorNotFound)?; + enum DecodedDispatchError { + Other, + CannotLookup, + BadOrigin, + Module(DecodedModuleErrorBytes), + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(TokenError), + Arithmetic(ArithmeticError), + Transactional(TransactionalError), + Exhausted, + Corruption, + Unavailable, + } + const _: () = { + struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for DecodedDispatchError { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = DecodedDispatchError; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant< + 'scale, + 'info, + >, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "Other" { + return Ok(DecodedDispatchError::Other); + } + if value.name() == "CannotLookup" { + return Ok(DecodedDispatchError::CannotLookup); + } + if value.name() == "BadOrigin" { + return Ok(DecodedDispatchError::BadOrigin); + } + if value.name() == "Module" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + DecodedDispatchError::Module({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "ConsumerRemaining" { + return Ok(DecodedDispatchError::ConsumerRemaining); + } + if value.name() == "NoProviders" { + return Ok(DecodedDispatchError::NoProviders); + } + if value.name() == "TooManyConsumers" { + return Ok(DecodedDispatchError::TooManyConsumers); + } + if value.name() == "Token" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + DecodedDispatchError::Token({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Arithmetic" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + DecodedDispatchError::Arithmetic({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Transactional" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + DecodedDispatchError::Transactional({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Exhausted" { + return Ok(DecodedDispatchError::Exhausted); + } + if value.name() == "Corruption" { + return Ok(DecodedDispatchError::Corruption); + } + if value.name() == "Unavailable" { + return Ok(DecodedDispatchError::Unavailable); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + "Other", + "CannotLookup", + "BadOrigin", + "Module", + "ConsumerRemaining", + "NoProviders", + "TooManyConsumers", + "Token", + "Arithmetic", + "Transactional", + "Exhausted", + "Corruption", + "Unavailable", + ]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite< + 'scale, + 'info, + >, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple< + 'scale, + 'info, + >, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + struct DecodedModuleErrorBytes(Vec); + struct DecodedModuleErrorBytesVisitor; + impl scale_decode::Visitor for DecodedModuleErrorBytesVisitor { + type Error = scale_decode::Error; + type Value<'scale, 'info> = DecodedModuleErrorBytes; + fn unchecked_decode_as_type<'scale, 'info>( + self, + input: &mut &'scale [u8], + _type_id: scale_decode::visitor::TypeId, + _types: &'info scale_info::PortableRegistry, + ) -> DecodeAsTypeResult< + Self, + Result, Self::Error>, + > { + DecodeAsTypeResult::Decoded( + Ok(DecodedModuleErrorBytes(input.to_vec())), + ) + } + } + impl scale_decode::IntoVisitor for DecodedModuleErrorBytes { + type Visitor = DecodedModuleErrorBytesVisitor; + fn into_visitor() -> Self::Visitor { + DecodedModuleErrorBytesVisitor + } + } + let decoded_dispatch_err = DecodedDispatchError::decode_with_metadata( + &mut &*bytes, + dispatch_error_ty_id, + &metadata, + )?; + let dispatch_error = match decoded_dispatch_err { + DecodedDispatchError::Other => DispatchError::Other, + DecodedDispatchError::CannotLookup => DispatchError::CannotLookup, + DecodedDispatchError::BadOrigin => DispatchError::BadOrigin, + DecodedDispatchError::ConsumerRemaining => { + DispatchError::ConsumerRemaining + } + DecodedDispatchError::NoProviders => DispatchError::NoProviders, + DecodedDispatchError::TooManyConsumers => { + DispatchError::TooManyConsumers + } + DecodedDispatchError::Token(val) => DispatchError::Token(val), + DecodedDispatchError::Arithmetic(val) => { + DispatchError::Arithmetic(val) + } + DecodedDispatchError::Transactional(val) => { + DispatchError::Transactional(val) + } + DecodedDispatchError::Exhausted => DispatchError::Exhausted, + DecodedDispatchError::Corruption => DispatchError::Corruption, + DecodedDispatchError::Unavailable => DispatchError::Unavailable, + DecodedDispatchError::Module(module_bytes) => { + let module_bytes = module_bytes.0; + let bytes = if module_bytes.len() == 2 { + [module_bytes[0], module_bytes[1], 0, 0, 0] + } else if module_bytes.len() == 5 { + [ + module_bytes[0], + module_bytes[1], + module_bytes[2], + module_bytes[3], + module_bytes[4], + ] + } else { + { + use ::tracing::__macro_support::Callsite as _; + static __CALLSITE: ::tracing::callsite::DefaultCallsite = { + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "event subxt/src/error/dispatch_error.rs:318", + "subxt::error::dispatch_error", + ::tracing::Level::WARN, + ::core::option::Option::Some( + "subxt/src/error/dispatch_error.rs", + ), + ::core::option::Option::Some(318u32), + ::core::option::Option::Some( + "subxt::error::dispatch_error", + ), + ::tracing_core::field::FieldSet::new( + &["message"], + ::tracing_core::callsite::Identifier(&__CALLSITE), + ), + ::tracing::metadata::Kind::EVENT, + ) + }; + ::tracing::callsite::DefaultCallsite::new(&META) + }; + let enabled = ::tracing::Level::WARN + <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::WARN + <= ::tracing::level_filters::LevelFilter::current() + && { + let interest = __CALLSITE.interest(); + !interest.is_never() + && ::tracing::__macro_support::__is_enabled( + __CALLSITE.metadata(), + interest, + ) + }; + if enabled { + (|value_set: ::tracing::field::ValueSet| { + let meta = __CALLSITE.metadata(); + ::tracing::Event::dispatch(meta, &value_set); + })({ + #[allow(unused_imports)] + use ::tracing::field::{debug, display, Value}; + let mut iter = __CALLSITE.metadata().fields().iter(); + __CALLSITE + .metadata() + .fields() + .value_set( + &[ + ( + &::core::iter::Iterator::next(&mut iter) + .expect("FieldSet corrupted (this is a bug)"), + ::core::option::Option::Some( + &format_args!( + "Can\'t decode error sp_runtime::DispatchError: bytes do not match known shapes" + ) as &dyn Value, + ), + ), + ], + ) + }); + } else { + } + }; + return Err(super::Error::Unknown(bytes.to_vec())); + }; + DispatchError::Module(ModuleError { metadata, bytes }) + } + }; + Ok(dispatch_error) + } + } + } + pub use dispatch_error::{ + ArithmeticError, DispatchError, ModuleError, TokenError, TransactionalError, + }; + use subxt_metadata::StorageHasher; + pub use crate::config::ExtrinsicParamsError; + pub use crate::metadata::Metadata; + pub use scale_decode::Error as DecodeError; + pub use scale_encode::Error as EncodeError; + pub use subxt_metadata::TryFromError as MetadataTryFromError; + /// The underlying error enum, generic over the type held by the `Runtime` + /// variant. Prefer to use the [`Error`] and [`Error`] aliases over + /// using this type directly. + #[non_exhaustive] + pub enum Error { + /// Io error. + #[error("Io error: {0}")] + Io(#[from] std::io::Error), + /// Codec error. + #[error("Scale codec error: {0}")] + Codec(#[from] codec::Error), + /// Rpc error. + #[error("Rpc error: {0}")] + Rpc(#[from] RpcError), + /// Serde serialization error + #[error("Serde json error: {0}")] + Serialization(#[from] serde_json::error::Error), + /// Error working with metadata. + #[error("Metadata error: {0}")] + Metadata(#[from] MetadataError), + /// Error decoding metadata. + #[error("Metadata Decoding error: {0}")] + MetadataDecoding(#[from] MetadataTryFromError), + /// Runtime error. + #[error("Runtime error: {0}")] + Runtime(#[from] DispatchError), + /// Error decoding to a [`crate::dynamic::Value`]. + #[error("Error decoding into dynamic value: {0}")] + Decode(#[from] DecodeError), + /// Error encoding from a [`crate::dynamic::Value`]. + #[error("Error encoding from dynamic value: {0}")] + Encode(#[from] EncodeError), + /// Transaction progress error. + #[error("Transaction error: {0}")] + Transaction(#[from] TransactionError), + /// Error constructing the appropriate extrinsic params. + #[error("Extrinsic params error: {0}")] + ExtrinsicParams(#[from] ExtrinsicParamsError), + /// Block related error. + #[error("Block error: {0}")] + Block(#[from] BlockError), + /// An error encoding a storage address. + #[error("Error encoding storage address: {0}")] + StorageAddress(#[from] StorageAddressError), + /// The bytes representing an error that we were unable to decode. + #[error("An error occurred but it could not be decoded: {0:?}")] + Unknown(Vec), + /// Other error. + #[error("Other error: {0}")] + Other(String), + } + #[automatically_derived] + impl ::core::fmt::Debug for Error { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + Error::Io(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Io", &__self_0) + } + Error::Codec(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Codec", + &__self_0, + ) + } + Error::Rpc(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Rpc", + &__self_0, + ) + } + Error::Serialization(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Serialization", + &__self_0, + ) + } + Error::Metadata(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Metadata", + &__self_0, + ) + } + Error::MetadataDecoding(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "MetadataDecoding", + &__self_0, + ) + } + Error::Runtime(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Runtime", + &__self_0, + ) + } + Error::Decode(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Decode", + &__self_0, + ) + } + Error::Encode(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Encode", + &__self_0, + ) + } + Error::Transaction(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Transaction", + &__self_0, + ) + } + Error::ExtrinsicParams(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ExtrinsicParams", + &__self_0, + ) + } + Error::Block(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Block", + &__self_0, + ) + } + Error::StorageAddress(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "StorageAddress", + &__self_0, + ) + } + Error::Unknown(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Unknown", + &__self_0, + ) + } + Error::Other(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Other", + &__self_0, + ) + } + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for Error { + fn source(&self) -> ::core::option::Option<&(dyn std::error::Error + 'static)> { + use thiserror::__private::AsDynError as _; + #[allow(deprecated)] + match self { + Error::Io { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Codec { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Rpc { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Serialization { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Metadata { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::MetadataDecoding { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Runtime { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Decode { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Encode { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Transaction { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::ExtrinsicParams { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Block { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::StorageAddress { 0: source, .. } => { + ::core::option::Option::Some(source.as_dyn_error()) + } + Error::Unknown { .. } => ::core::option::Option::None, + Error::Other { .. } => ::core::option::Option::None, + } + } + } + #[allow(unused_qualifications)] + impl ::core::fmt::Display for Error { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + Error::Io(_0) => { + __formatter.write_fmt(format_args!("Io error: {0}", _0.as_display())) + } + Error::Codec(_0) => { + __formatter + .write_fmt( + format_args!("Scale codec error: {0}", _0.as_display()), + ) + } + Error::Rpc(_0) => { + __formatter + .write_fmt(format_args!("Rpc error: {0}", _0.as_display())) + } + Error::Serialization(_0) => { + __formatter + .write_fmt( + format_args!("Serde json error: {0}", _0.as_display()), + ) + } + Error::Metadata(_0) => { + __formatter + .write_fmt(format_args!("Metadata error: {0}", _0.as_display())) + } + Error::MetadataDecoding(_0) => { + __formatter + .write_fmt( + format_args!("Metadata Decoding error: {0}", _0.as_display()), + ) + } + Error::Runtime(_0) => { + __formatter + .write_fmt(format_args!("Runtime error: {0}", _0.as_display())) + } + Error::Decode(_0) => { + __formatter + .write_fmt( + format_args!( + "Error decoding into dynamic value: {0}", _0.as_display() + ), + ) + } + Error::Encode(_0) => { + __formatter + .write_fmt( + format_args!( + "Error encoding from dynamic value: {0}", _0.as_display() + ), + ) + } + Error::Transaction(_0) => { + __formatter + .write_fmt( + format_args!("Transaction error: {0}", _0.as_display()), + ) + } + Error::ExtrinsicParams(_0) => { + __formatter + .write_fmt( + format_args!("Extrinsic params error: {0}", _0.as_display()), + ) + } + Error::Block(_0) => { + __formatter + .write_fmt(format_args!("Block error: {0}", _0.as_display())) + } + Error::StorageAddress(_0) => { + __formatter + .write_fmt( + format_args!( + "Error encoding storage address: {0}", _0.as_display() + ), + ) + } + Error::Unknown(_0) => { + __formatter + .write_fmt( + format_args!( + "An error occurred but it could not be decoded: {0:?}", _0 + ), + ) + } + Error::Other(_0) => { + __formatter + .write_fmt(format_args!("Other error: {0}", _0.as_display())) + } + } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: std::io::Error) -> Self { + Error::Io { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: codec::Error) -> Self { + Error::Codec { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: RpcError) -> Self { + Error::Rpc { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: serde_json::error::Error) -> Self { + Error::Serialization { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: MetadataError) -> Self { + Error::Metadata { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: MetadataTryFromError) -> Self { + Error::MetadataDecoding { + 0: source, + } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: DispatchError) -> Self { + Error::Runtime { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: DecodeError) -> Self { + Error::Decode { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: EncodeError) -> Self { + Error::Encode { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: TransactionError) -> Self { + Error::Transaction { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: ExtrinsicParamsError) -> Self { + Error::ExtrinsicParams { + 0: source, + } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: BlockError) -> Self { + Error::Block { 0: source } + } + } + #[allow(unused_qualifications)] + impl ::core::convert::From for Error { + #[allow(deprecated)] + fn from(source: StorageAddressError) -> Self { + Error::StorageAddress { 0: source } + } + } + impl<'a> From<&'a str> for Error { + fn from(error: &'a str) -> Self { + Error::Other(error.into()) + } + } + impl From for Error { + fn from(error: String) -> Self { + Error::Other(error) + } + } + impl From for Error { + fn from(value: std::convert::Infallible) -> Self { + match value {} + } + } + impl Error { + /// Checks whether the error was caused by a RPC re-connection. + pub fn is_disconnected_will_reconnect(&self) -> bool { + match self { + Error::Rpc(RpcError::DisconnectedWillReconnect(_)) => true, + _ => false, + } + } + } + /// An RPC error. Since we are generic over the RPC client that is used, + /// the error is boxed and could be casted. + #[non_exhaustive] + pub enum RpcError { + /// Error related to the RPC client. + #[error("RPC error: {0}")] + ClientError(Box), + /// This error signals that the request was rejected for some reason. + /// The specific reason is provided. + #[error("RPC error: request rejected: {0}")] + RequestRejected(String), + /// The RPC subscription dropped. + #[error("RPC error: subscription dropped.")] + SubscriptionDropped, + /// The requested URL is insecure. + #[error("RPC error: insecure URL: {0}")] + InsecureUrl(String), + /// The connection was lost and automatically reconnected. + #[error( + "RPC error: the connection was lost `{0}`; reconnect automatically initiated" + )] + DisconnectedWillReconnect(String), + } + #[automatically_derived] + impl ::core::fmt::Debug for RpcError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + RpcError::ClientError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ClientError", + &__self_0, + ) + } + RpcError::RequestRejected(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "RequestRejected", + &__self_0, + ) + } + RpcError::SubscriptionDropped => { + ::core::fmt::Formatter::write_str(f, "SubscriptionDropped") + } + RpcError::InsecureUrl(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "InsecureUrl", + &__self_0, + ) + } + RpcError::DisconnectedWillReconnect(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "DisconnectedWillReconnect", + &__self_0, + ) + } + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for RpcError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for RpcError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + RpcError::ClientError(_0) => { + __formatter + .write_fmt(format_args!("RPC error: {0}", _0.as_display())) + } + RpcError::RequestRejected(_0) => { + __formatter + .write_fmt( + format_args!( + "RPC error: request rejected: {0}", _0.as_display() + ), + ) + } + RpcError::SubscriptionDropped {} => { + __formatter.write_str("RPC error: subscription dropped.") + } + RpcError::InsecureUrl(_0) => { + __formatter + .write_fmt( + format_args!("RPC error: insecure URL: {0}", _0.as_display()), + ) + } + RpcError::DisconnectedWillReconnect(_0) => { + __formatter + .write_fmt( + format_args!( + "RPC error: the connection was lost `{0}`; reconnect automatically initiated", + _0.as_display() + ), + ) + } + } + } + } + impl RpcError { + /// Create a `RequestRejected` error from anything that can be turned into a string. + pub fn request_rejected>(s: S) -> RpcError { + RpcError::RequestRejected(s.into()) + } + } + /// Block error + #[non_exhaustive] + pub enum BlockError { + /// An error containing the hash of the block that was not found. + #[error( + "Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)" + )] + NotFound(String), + /// Extrinsic type ID cannot be resolved with the provided metadata. + #[error( + "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata" + )] + MissingType, + /// Unsupported signature. + #[error("Unsupported extrinsic version, only version 4 is supported currently")] + /// The extrinsic has an unsupported version. + UnsupportedVersion(u8), + /// Decoding error. + #[error("Cannot decode extrinsic: {0}")] + DecodingError(codec::Error), + } + #[automatically_derived] + impl ::core::clone::Clone for BlockError { + #[inline] + fn clone(&self) -> BlockError { + match self { + BlockError::NotFound(__self_0) => { + BlockError::NotFound(::core::clone::Clone::clone(__self_0)) + } + BlockError::MissingType => BlockError::MissingType, + BlockError::UnsupportedVersion(__self_0) => { + BlockError::UnsupportedVersion(::core::clone::Clone::clone(__self_0)) + } + BlockError::DecodingError(__self_0) => { + BlockError::DecodingError(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for BlockError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + BlockError::NotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "NotFound", + &__self_0, + ) + } + BlockError::MissingType => { + ::core::fmt::Formatter::write_str(f, "MissingType") + } + BlockError::UnsupportedVersion(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "UnsupportedVersion", + &__self_0, + ) + } + BlockError::DecodingError(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "DecodingError", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for BlockError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[allow(unused_qualifications)] + impl std::error::Error for BlockError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for BlockError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + BlockError::NotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)", + _0.as_display() + ), + ) + } + BlockError::MissingType {} => { + __formatter + .write_str( + "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata", + ) + } + BlockError::UnsupportedVersion(_0) => { + __formatter + .write_str( + "Unsupported extrinsic version, only version 4 is supported currently", + ) + } + BlockError::DecodingError(_0) => { + __formatter + .write_fmt( + format_args!("Cannot decode extrinsic: {0}", _0.as_display()), + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for BlockError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for BlockError { + #[inline] + fn eq(&self, other: &BlockError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + (BlockError::NotFound(__self_0), BlockError::NotFound(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + ( + BlockError::UnsupportedVersion(__self_0), + BlockError::UnsupportedVersion(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + BlockError::DecodingError(__self_0), + BlockError::DecodingError(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + impl BlockError { + /// Produce an error that a block with the given hash cannot be found. + pub fn not_found(hash: impl AsRef<[u8]>) -> BlockError { + let hash = { + let res = ::alloc::fmt::format(format_args!("0x{0}", hex::encode(hash))); + res + }; + BlockError::NotFound(hash) + } + } + /// Transaction error. + #[non_exhaustive] + pub enum TransactionError { + /// The block hash that the transaction was added to could not be found. + /// This is probably because the block was retracted before being finalized. + #[error( + "The block containing the transaction can no longer be found (perhaps it was on a non-finalized fork?)" + )] + BlockNotFound, + /// An error happened on the node that the transaction was submitted to. + #[error("Error handling transaction: {0}")] + Error(String), + /// The transaction was deemed invalid. + #[error("The transaction is not valid: {0}")] + Invalid(String), + /// The transaction was dropped. + #[error("The transaction was dropped: {0}")] + Dropped(String), + } + #[automatically_derived] + impl ::core::clone::Clone for TransactionError { + #[inline] + fn clone(&self) -> TransactionError { + match self { + TransactionError::BlockNotFound => TransactionError::BlockNotFound, + TransactionError::Error(__self_0) => { + TransactionError::Error(::core::clone::Clone::clone(__self_0)) + } + TransactionError::Invalid(__self_0) => { + TransactionError::Invalid(::core::clone::Clone::clone(__self_0)) + } + TransactionError::Dropped(__self_0) => { + TransactionError::Dropped(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionError::BlockNotFound => { + ::core::fmt::Formatter::write_str(f, "BlockNotFound") + } + TransactionError::Error(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Error", + &__self_0, + ) + } + TransactionError::Invalid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Invalid", + &__self_0, + ) + } + TransactionError::Dropped(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Dropped", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for TransactionError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[allow(unused_qualifications)] + impl std::error::Error for TransactionError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for TransactionError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + TransactionError::BlockNotFound {} => { + __formatter + .write_str( + "The block containing the transaction can no longer be found (perhaps it was on a non-finalized fork?)", + ) + } + TransactionError::Error(_0) => { + __formatter + .write_fmt( + format_args!( + "Error handling transaction: {0}", _0.as_display() + ), + ) + } + TransactionError::Invalid(_0) => { + __formatter + .write_fmt( + format_args!( + "The transaction is not valid: {0}", _0.as_display() + ), + ) + } + TransactionError::Dropped(_0) => { + __formatter + .write_fmt( + format_args!( + "The transaction was dropped: {0}", _0.as_display() + ), + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionError { + #[inline] + fn eq(&self, other: &TransactionError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionError::Error(__self_0), + TransactionError::Error(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + TransactionError::Invalid(__self_0), + TransactionError::Invalid(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + TransactionError::Dropped(__self_0), + TransactionError::Dropped(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + /// Something went wrong trying to encode a storage address. + #[non_exhaustive] + pub enum StorageAddressError { + /// Storage map type must be a composite type. + #[error("Storage map type must be a composite type")] + MapTypeMustBeTuple, + /// Storage lookup does not have the expected number of keys. + #[error("Storage lookup requires {expected} keys but got {actual} keys")] + WrongNumberOfKeys { + /// The actual number of keys needed, based on the metadata. + actual: usize, + /// The number of keys provided in the storage address. + expected: usize, + }, + /// This storage entry in the metadata does not have the correct number of hashers to fields. + #[error( + "Storage entry in metadata does not have the correct number of hashers to fields" + )] + WrongNumberOfHashers { + /// The number of hashers in the metadata for this storage entry. + hashers: usize, + /// The number of fields in the metadata for this storage entry. + fields: usize, + }, + /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. + #[error( + "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata." + )] + UnexpectedAddressBytes, + /// An invalid hasher was used to reconstruct a value from a chunk of bytes that is part of a storage address. Hashers where the hash does not contain the original value are invalid for this purpose. + #[error( + "An invalid hasher was used to reconstruct a value of type {ty_name} (id={ty_id}) from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher" + )] + HasherCannotReconstructKey { + /// Type id of the key's type. + ty_id: u32, + /// Type name of the key's type. + ty_name: String, + /// The invalid hasher that caused this error. + hasher: StorageHasher, + }, + } + #[automatically_derived] + impl ::core::clone::Clone for StorageAddressError { + #[inline] + fn clone(&self) -> StorageAddressError { + match self { + StorageAddressError::MapTypeMustBeTuple => { + StorageAddressError::MapTypeMustBeTuple + } + StorageAddressError::WrongNumberOfKeys { + actual: __self_0, + expected: __self_1, + } => { + StorageAddressError::WrongNumberOfKeys { + actual: ::core::clone::Clone::clone(__self_0), + expected: ::core::clone::Clone::clone(__self_1), + } + } + StorageAddressError::WrongNumberOfHashers { + hashers: __self_0, + fields: __self_1, + } => { + StorageAddressError::WrongNumberOfHashers { + hashers: ::core::clone::Clone::clone(__self_0), + fields: ::core::clone::Clone::clone(__self_1), + } + } + StorageAddressError::UnexpectedAddressBytes => { + StorageAddressError::UnexpectedAddressBytes + } + StorageAddressError::HasherCannotReconstructKey { + ty_id: __self_0, + ty_name: __self_1, + hasher: __self_2, + } => { + StorageAddressError::HasherCannotReconstructKey { + ty_id: ::core::clone::Clone::clone(__self_0), + ty_name: ::core::clone::Clone::clone(__self_1), + hasher: ::core::clone::Clone::clone(__self_2), + } + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for StorageAddressError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + StorageAddressError::MapTypeMustBeTuple => { + ::core::fmt::Formatter::write_str(f, "MapTypeMustBeTuple") + } + StorageAddressError::WrongNumberOfKeys { + actual: __self_0, + expected: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "WrongNumberOfKeys", + "actual", + __self_0, + "expected", + &__self_1, + ) + } + StorageAddressError::WrongNumberOfHashers { + hashers: __self_0, + fields: __self_1, + } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "WrongNumberOfHashers", + "hashers", + __self_0, + "fields", + &__self_1, + ) + } + StorageAddressError::UnexpectedAddressBytes => { + ::core::fmt::Formatter::write_str(f, "UnexpectedAddressBytes") + } + StorageAddressError::HasherCannotReconstructKey { + ty_id: __self_0, + ty_name: __self_1, + hasher: __self_2, + } => { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "HasherCannotReconstructKey", + "ty_id", + __self_0, + "ty_name", + __self_1, + "hasher", + &__self_2, + ) + } + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for StorageAddressError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for StorageAddressError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + StorageAddressError::MapTypeMustBeTuple {} => { + __formatter.write_str("Storage map type must be a composite type") + } + StorageAddressError::WrongNumberOfKeys { actual, expected } => { + __formatter + .write_fmt( + format_args!( + "Storage lookup requires {0} keys but got {1} keys", + expected.as_display(), actual.as_display() + ), + ) + } + StorageAddressError::WrongNumberOfHashers { hashers, fields } => { + __formatter + .write_str( + "Storage entry in metadata does not have the correct number of hashers to fields", + ) + } + StorageAddressError::UnexpectedAddressBytes {} => { + __formatter + .write_str( + "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata.", + ) + } + StorageAddressError::HasherCannotReconstructKey { + ty_id, + ty_name, + hasher, + } => { + __formatter + .write_fmt( + format_args!( + "An invalid hasher was used to reconstruct a value of type {0} (id={1}) from a hash formed by a {2:?} hasher. This is only possible for concat-style hashers or the identity hasher", + ty_name.as_display(), ty_id.as_display(), hasher + ), + ) + } + } + } + } + /// Something went wrong trying to access details in the metadata. + #[non_exhaustive] + pub enum MetadataError { + /// The DispatchError type isn't available in the metadata + #[error("The DispatchError type isn't available")] + DispatchErrorNotFound, + /// Type not found in metadata. + #[error("Type with ID {0} not found")] + TypeNotFound(u32), + /// Pallet not found (index). + #[error("Pallet with index {0} not found")] + PalletIndexNotFound(u8), + /// Pallet not found (name). + #[error("Pallet with name {0} not found")] + PalletNameNotFound(String), + /// Variant not found. + #[error("Variant with index {0} not found")] + VariantIndexNotFound(u8), + /// Constant not found. + #[error("Constant with name {0} not found")] + ConstantNameNotFound(String), + /// Call not found. + #[error("Call with name {0} not found")] + CallNameNotFound(String), + /// Runtime trait not found. + #[error("Runtime trait with name {0} not found")] + RuntimeTraitNotFound(String), + /// Runtime method not found. + #[error("Runtime method with name {0} not found")] + RuntimeMethodNotFound(String), + /// Call type not found in metadata. + #[error("Call type not found in pallet with index {0}")] + CallTypeNotFoundInPallet(u8), + /// Event type not found in metadata. + #[error("Event type not found in pallet with index {0}")] + EventTypeNotFoundInPallet(u8), + /// Storage details not found in metadata. + #[error("Storage details not found in pallet with name {0}")] + StorageNotFoundInPallet(String), + /// Storage entry not found. + #[error("Storage entry {0} not found")] + StorageEntryNotFound(String), + /// The generated interface used is not compatible with the node. + #[error("The generated code is not compatible with the node")] + IncompatibleCodegen, + /// Custom value not found. + #[error("Custom value with name {0} not found")] + CustomValueNameNotFound(String), + } + #[automatically_derived] + impl ::core::clone::Clone for MetadataError { + #[inline] + fn clone(&self) -> MetadataError { + match self { + MetadataError::DispatchErrorNotFound => { + MetadataError::DispatchErrorNotFound + } + MetadataError::TypeNotFound(__self_0) => { + MetadataError::TypeNotFound(::core::clone::Clone::clone(__self_0)) + } + MetadataError::PalletIndexNotFound(__self_0) => { + MetadataError::PalletIndexNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::PalletNameNotFound(__self_0) => { + MetadataError::PalletNameNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::VariantIndexNotFound(__self_0) => { + MetadataError::VariantIndexNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::ConstantNameNotFound(__self_0) => { + MetadataError::ConstantNameNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::CallNameNotFound(__self_0) => { + MetadataError::CallNameNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::RuntimeTraitNotFound(__self_0) => { + MetadataError::RuntimeTraitNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::RuntimeMethodNotFound(__self_0) => { + MetadataError::RuntimeMethodNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::CallTypeNotFoundInPallet(__self_0) => { + MetadataError::CallTypeNotFoundInPallet( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::EventTypeNotFoundInPallet(__self_0) => { + MetadataError::EventTypeNotFoundInPallet( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::StorageNotFoundInPallet(__self_0) => { + MetadataError::StorageNotFoundInPallet( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::StorageEntryNotFound(__self_0) => { + MetadataError::StorageEntryNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + MetadataError::IncompatibleCodegen => MetadataError::IncompatibleCodegen, + MetadataError::CustomValueNameNotFound(__self_0) => { + MetadataError::CustomValueNameNotFound( + ::core::clone::Clone::clone(__self_0), + ) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for MetadataError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + MetadataError::DispatchErrorNotFound => { + ::core::fmt::Formatter::write_str(f, "DispatchErrorNotFound") + } + MetadataError::TypeNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "TypeNotFound", + &__self_0, + ) + } + MetadataError::PalletIndexNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "PalletIndexNotFound", + &__self_0, + ) + } + MetadataError::PalletNameNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "PalletNameNotFound", + &__self_0, + ) + } + MetadataError::VariantIndexNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "VariantIndexNotFound", + &__self_0, + ) + } + MetadataError::ConstantNameNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ConstantNameNotFound", + &__self_0, + ) + } + MetadataError::CallNameNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "CallNameNotFound", + &__self_0, + ) + } + MetadataError::RuntimeTraitNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "RuntimeTraitNotFound", + &__self_0, + ) + } + MetadataError::RuntimeMethodNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "RuntimeMethodNotFound", + &__self_0, + ) + } + MetadataError::CallTypeNotFoundInPallet(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "CallTypeNotFoundInPallet", + &__self_0, + ) + } + MetadataError::EventTypeNotFoundInPallet(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "EventTypeNotFoundInPallet", + &__self_0, + ) + } + MetadataError::StorageNotFoundInPallet(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "StorageNotFoundInPallet", + &__self_0, + ) + } + MetadataError::StorageEntryNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "StorageEntryNotFound", + &__self_0, + ) + } + MetadataError::IncompatibleCodegen => { + ::core::fmt::Formatter::write_str(f, "IncompatibleCodegen") + } + MetadataError::CustomValueNameNotFound(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "CustomValueNameNotFound", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for MetadataError {} + #[automatically_derived] + impl ::core::cmp::PartialEq for MetadataError { + #[inline] + fn eq(&self, other: &MetadataError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + MetadataError::TypeNotFound(__self_0), + MetadataError::TypeNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::PalletIndexNotFound(__self_0), + MetadataError::PalletIndexNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::PalletNameNotFound(__self_0), + MetadataError::PalletNameNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::VariantIndexNotFound(__self_0), + MetadataError::VariantIndexNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::ConstantNameNotFound(__self_0), + MetadataError::ConstantNameNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::CallNameNotFound(__self_0), + MetadataError::CallNameNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::RuntimeTraitNotFound(__self_0), + MetadataError::RuntimeTraitNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::RuntimeMethodNotFound(__self_0), + MetadataError::RuntimeMethodNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::CallTypeNotFoundInPallet(__self_0), + MetadataError::CallTypeNotFoundInPallet(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::EventTypeNotFoundInPallet(__self_0), + MetadataError::EventTypeNotFoundInPallet(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::StorageNotFoundInPallet(__self_0), + MetadataError::StorageNotFoundInPallet(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::StorageEntryNotFound(__self_0), + MetadataError::StorageEntryNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MetadataError::CustomValueNameNotFound(__self_0), + MetadataError::CustomValueNameNotFound(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[allow(unused_qualifications)] + impl std::error::Error for MetadataError {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for MetadataError { + fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use thiserror::__private::AsDisplay as _; + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + MetadataError::DispatchErrorNotFound {} => { + __formatter.write_str("The DispatchError type isn't available") + } + MetadataError::TypeNotFound(_0) => { + __formatter + .write_fmt( + format_args!("Type with ID {0} not found", _0.as_display()), + ) + } + MetadataError::PalletIndexNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Pallet with index {0} not found", _0.as_display() + ), + ) + } + MetadataError::PalletNameNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Pallet with name {0} not found", _0.as_display() + ), + ) + } + MetadataError::VariantIndexNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Variant with index {0} not found", _0.as_display() + ), + ) + } + MetadataError::ConstantNameNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Constant with name {0} not found", _0.as_display() + ), + ) + } + MetadataError::CallNameNotFound(_0) => { + __formatter + .write_fmt( + format_args!("Call with name {0} not found", _0.as_display()), + ) + } + MetadataError::RuntimeTraitNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Runtime trait with name {0} not found", _0.as_display() + ), + ) + } + MetadataError::RuntimeMethodNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Runtime method with name {0} not found", _0.as_display() + ), + ) + } + MetadataError::CallTypeNotFoundInPallet(_0) => { + __formatter + .write_fmt( + format_args!( + "Call type not found in pallet with index {0}", _0 + .as_display() + ), + ) + } + MetadataError::EventTypeNotFoundInPallet(_0) => { + __formatter + .write_fmt( + format_args!( + "Event type not found in pallet with index {0}", _0 + .as_display() + ), + ) + } + MetadataError::StorageNotFoundInPallet(_0) => { + __formatter + .write_fmt( + format_args!( + "Storage details not found in pallet with name {0}", _0 + .as_display() + ), + ) + } + MetadataError::StorageEntryNotFound(_0) => { + __formatter + .write_fmt( + format_args!("Storage entry {0} not found", _0.as_display()), + ) + } + MetadataError::IncompatibleCodegen {} => { + __formatter + .write_str("The generated code is not compatible with the node") + } + MetadataError::CustomValueNameNotFound(_0) => { + __formatter + .write_fmt( + format_args!( + "Custom value with name {0} not found", _0.as_display() + ), + ) + } + } + } + } +} +pub mod events { + //! This module exposes the types and such necessary for working with events. + //! The two main entry points into events are [`crate::OnlineClient::events()`] + //! and calls like [crate::tx::TxProgress::wait_for_finalized_success()]. + mod events_client { + use crate::backend::{Backend, BackendExt, BlockRef}; + use crate::{client::OnlineClientT, error::Error, events::Events, Config}; + use derivative::Derivative; + use std::future::Future; + /// A client for working with events. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct EventsClient { + client: Client, + _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for EventsClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + EventsClient { client: ref __arg_0, _marker: ref __arg_1 } => { + EventsClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl EventsClient { + /// Create a new [`EventsClient`]. + pub fn new(client: Client) -> Self { + Self { + client, + _marker: std::marker::PhantomData, + } + } + } + impl EventsClient + where + T: Config, + Client: OnlineClientT, + { + /// Obtain events at some block hash. + /// + /// # Warning + /// + /// This call only supports blocks produced since the most recent + /// runtime upgrade. You can attempt to retrieve events from older blocks, + /// but may run into errors attempting to work with them. + pub fn at( + &self, + block_ref: impl Into>, + ) -> impl Future, Error>> + Send + 'static { + self.at_or_latest(Some(block_ref.into())) + } + /// Obtain events for the latest block. + pub fn at_latest( + &self, + ) -> impl Future, Error>> + Send + 'static { + self.at_or_latest(None) + } + /// Obtain events at some block hash. + fn at_or_latest( + &self, + block_ref: Option>, + ) -> impl Future, Error>> + Send + 'static { + let client = self.client.clone(); + async move { + let block_ref = match block_ref { + Some(r) => r, + None => client.backend().latest_finalized_block_ref().await?, + }; + let event_bytes = get_event_bytes(client.backend(), block_ref.hash()) + .await?; + Ok(Events::new(client.metadata(), block_ref.hash(), event_bytes)) + } + } + } + fn system_events_key() -> [u8; 32] { + let a = sp_core_hashing::twox_128(b"System"); + let b = sp_core_hashing::twox_128(b"Events"); + let mut res = [0; 32]; + res[0..16].clone_from_slice(&a); + res[16..32].clone_from_slice(&b); + res + } + pub(crate) async fn get_event_bytes( + backend: &dyn Backend, + block_hash: T::Hash, + ) -> Result, Error> { + Ok( + backend + .storage_fetch_value(system_events_key().to_vec(), block_hash) + .await? + .unwrap_or_default(), + ) + } + } + mod events_type { + //! A representation of a block of events. + use super::{Phase, StaticEvent}; + use crate::{ + client::OnlineClientT, error::{Error, MetadataError}, + events::events_client::get_event_bytes, metadata::types::PalletMetadata, + Config, Metadata, + }; + use codec::{Compact, Decode}; + use derivative::Derivative; + use scale_decode::DecodeAsType; + use std::sync::Arc; + /// A collection of events obtained from a block, bundled with the necessary + /// information needed to decode and iterate over them. + #[derivative(Clone(bound = ""))] + pub struct Events { + metadata: Metadata, + block_hash: T::Hash, + event_bytes: Arc<[u8]>, + start_idx: usize, + num_events: u32, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Events { + fn clone(&self) -> Self { + match *self { + Events { + metadata: ref __arg_0, + block_hash: ref __arg_1, + event_bytes: ref __arg_2, + start_idx: ref __arg_3, + num_events: ref __arg_4, + } => { + Events { + metadata: (*__arg_0).clone(), + block_hash: (*__arg_1).clone(), + event_bytes: (*__arg_2).clone(), + start_idx: (*__arg_3).clone(), + num_events: (*__arg_4).clone(), + } + } + } + } + } + impl std::fmt::Debug for Events { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Events") + .field("block_hash", &self.block_hash) + .field("event_bytes", &self.event_bytes) + .field("start_idx", &self.start_idx) + .field("num_events", &self.num_events) + .finish() + } + } + impl Events { + pub(crate) fn new( + metadata: Metadata, + block_hash: T::Hash, + event_bytes: Vec, + ) -> Self { + let cursor = &mut &*event_bytes; + let num_events = >::decode(cursor).unwrap_or(Compact(0)).0; + let start_idx = event_bytes.len() - cursor.len(); + Self { + metadata, + block_hash, + event_bytes: event_bytes.into(), + start_idx, + num_events, + } + } + /// Obtain the events from a block hash given custom metadata and a client. + /// + /// # Notes + /// + /// - Prefer to use [`crate::events::EventsClient::at`] to obtain the events. + /// - Subxt may fail to decode things that aren't from a runtime using the + /// latest metadata version. + /// - The client may not be able to obtain the block at the given hash. Only + /// archive nodes keep hold of all past block information. + pub async fn new_from_client( + metadata: Metadata, + block_hash: T::Hash, + client: Client, + ) -> Result + where + Client: OnlineClientT, + { + let event_bytes = get_event_bytes(client.backend(), block_hash).await?; + Ok(Events::new(metadata, block_hash, event_bytes)) + } + /// The number of events. + pub fn len(&self) -> u32 { + self.num_events + } + /// Are there no events in this block? + pub fn is_empty(&self) -> bool { + self.num_events == 0 + } + /// Return the block hash that these events are from. + pub fn block_hash(&self) -> T::Hash { + self.block_hash + } + /// Iterate over all of the events, using metadata to dynamically + /// decode them as we go, and returning the raw bytes and other associated + /// details. If an error occurs, all subsequent iterations return `None`. + pub fn iter( + &self, + ) -> impl Iterator< + Item = Result, Error>, + > + Send + Sync + 'static { + let event_bytes = self.event_bytes.clone(); + let metadata = self.metadata.clone(); + let num_events = self.num_events; + let mut pos = self.start_idx; + let mut index = 0; + std::iter::from_fn(move || { + if event_bytes.len() <= pos || num_events == index { + None + } else { + match EventDetails::decode_from( + metadata.clone(), + event_bytes.clone(), + pos, + index, + ) { + Ok(event_details) => { + pos += event_details.bytes().len(); + index += 1; + Some(Ok(event_details)) + } + Err(e) => { + pos = event_bytes.len(); + Some(Err(e)) + } + } + } + }) + } + /// Iterate through the events using metadata to dynamically decode and skip + /// them, and return only those which should decode to the provided `Ev` type. + /// If an error occurs, all subsequent iterations return `None`. + pub fn find( + &self, + ) -> impl Iterator> + '_ { + self.iter() + .filter_map(|ev| { + ev.and_then(|ev| ev.as_event::().map_err(Into::into)) + .transpose() + }) + } + /// Iterate through the events using metadata to dynamically decode and skip + /// them, and return the first event found which decodes to the provided `Ev` type. + pub fn find_first(&self) -> Result, Error> { + self.find::().next().transpose() + } + /// Iterate through the events using metadata to dynamically decode and skip + /// them, and return the last event found which decodes to the provided `Ev` type. + pub fn find_last(&self) -> Result, Error> { + self.find::().last().transpose() + } + /// Find an event that decodes to the type provided. Returns true if it was found. + pub fn has(&self) -> Result { + Ok(self.find::().next().transpose()?.is_some()) + } + } + /// The event details. + pub struct EventDetails { + phase: Phase, + /// The index of the event in the list of events in a given block. + index: u32, + all_bytes: Arc<[u8]>, + start_idx: usize, + event_start_idx: usize, + event_fields_start_idx: usize, + event_fields_end_idx: usize, + end_idx: usize, + metadata: Metadata, + topics: Vec, + } + #[automatically_derived] + impl ::core::fmt::Debug for EventDetails + where + T::Hash: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + let names: &'static _ = &[ + "phase", + "index", + "all_bytes", + "start_idx", + "event_start_idx", + "event_fields_start_idx", + "event_fields_end_idx", + "end_idx", + "metadata", + "topics", + ]; + let values: &[&dyn ::core::fmt::Debug] = &[ + &self.phase, + &self.index, + &self.all_bytes, + &self.start_idx, + &self.event_start_idx, + &self.event_fields_start_idx, + &self.event_fields_end_idx, + &self.end_idx, + &self.metadata, + &&self.topics, + ]; + ::core::fmt::Formatter::debug_struct_fields_finish( + f, + "EventDetails", + names, + values, + ) + } + } + #[automatically_derived] + impl ::core::clone::Clone for EventDetails + where + T::Hash: ::core::clone::Clone, + { + #[inline] + fn clone(&self) -> EventDetails { + EventDetails { + phase: ::core::clone::Clone::clone(&self.phase), + index: ::core::clone::Clone::clone(&self.index), + all_bytes: ::core::clone::Clone::clone(&self.all_bytes), + start_idx: ::core::clone::Clone::clone(&self.start_idx), + event_start_idx: ::core::clone::Clone::clone(&self.event_start_idx), + event_fields_start_idx: ::core::clone::Clone::clone( + &self.event_fields_start_idx, + ), + event_fields_end_idx: ::core::clone::Clone::clone( + &self.event_fields_end_idx, + ), + end_idx: ::core::clone::Clone::clone(&self.end_idx), + metadata: ::core::clone::Clone::clone(&self.metadata), + topics: ::core::clone::Clone::clone(&self.topics), + } + } + } + impl EventDetails { + fn decode_from( + metadata: Metadata, + all_bytes: Arc<[u8]>, + start_idx: usize, + index: u32, + ) -> Result, Error> { + let input = &mut &all_bytes[start_idx..]; + let phase = Phase::decode(input)?; + let event_start_idx = all_bytes.len() - input.len(); + let pallet_index = u8::decode(input)?; + let variant_index = u8::decode(input)?; + let event_fields_start_idx = all_bytes.len() - input.len(); + let event_pallet = metadata.pallet_by_index_err(pallet_index)?; + let event_variant = event_pallet + .event_variant_by_index(variant_index) + .ok_or(MetadataError::VariantIndexNotFound(variant_index))?; + { + use ::tracing::__macro_support::Callsite as _; + static __CALLSITE: ::tracing::callsite::DefaultCallsite = { + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "event subxt/src/events/events_type.rs:220", + "subxt::events::events_type", + ::tracing::Level::DEBUG, + ::core::option::Option::Some( + "subxt/src/events/events_type.rs", + ), + ::core::option::Option::Some(220u32), + ::core::option::Option::Some("subxt::events::events_type"), + ::tracing_core::field::FieldSet::new( + &["message"], + ::tracing_core::callsite::Identifier(&__CALLSITE), + ), + ::tracing::metadata::Kind::EVENT, + ) + }; + ::tracing::callsite::DefaultCallsite::new(&META) + }; + let enabled = ::tracing::Level::DEBUG + <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::DEBUG + <= ::tracing::level_filters::LevelFilter::current() + && { + let interest = __CALLSITE.interest(); + !interest.is_never() + && ::tracing::__macro_support::__is_enabled( + __CALLSITE.metadata(), + interest, + ) + }; + if enabled { + (|value_set: ::tracing::field::ValueSet| { + let meta = __CALLSITE.metadata(); + ::tracing::Event::dispatch(meta, &value_set); + })({ + #[allow(unused_imports)] + use ::tracing::field::{debug, display, Value}; + let mut iter = __CALLSITE.metadata().fields().iter(); + __CALLSITE + .metadata() + .fields() + .value_set( + &[ + ( + &::core::iter::Iterator::next(&mut iter) + .expect("FieldSet corrupted (this is a bug)"), + ::core::option::Option::Some( + &format_args!( + "Decoding Event \'{0}::{1}\'", event_pallet.name(), & + event_variant.name + ) as &dyn Value, + ), + ), + ], + ) + }); + } else { + } + }; + for field_metadata in &event_variant.fields { + scale_decode::visitor::decode_with_visitor( + input, + field_metadata.ty.id, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) + .map_err(scale_decode::Error::from)?; + } + let event_fields_end_idx = all_bytes.len() - input.len(); + let topics = Vec::::decode(input)?; + let end_idx = all_bytes.len() - input.len(); + Ok(EventDetails { + phase, + index, + start_idx, + event_start_idx, + event_fields_start_idx, + event_fields_end_idx, + end_idx, + all_bytes, + metadata, + topics, + }) + } + /// When was the event produced? + pub fn phase(&self) -> Phase { + self.phase + } + /// What index is this event in the stored events for this block. + pub fn index(&self) -> u32 { + self.index + } + /// The index of the pallet that the event originated from. + pub fn pallet_index(&self) -> u8 { + self.all_bytes[self.event_fields_start_idx - 2] + } + /// The index of the event variant that the event originated from. + pub fn variant_index(&self) -> u8 { + self.all_bytes[self.event_fields_start_idx - 1] + } + /// The name of the pallet from whence the Event originated. + pub fn pallet_name(&self) -> &str { + self.event_metadata().pallet.name() + } + /// The name of the event (ie the name of the variant that it corresponds to). + pub fn variant_name(&self) -> &str { + &self.event_metadata().variant.name + } + /// Fetch details from the metadata for this event. + pub fn event_metadata(&self) -> EventMetadataDetails { + let pallet = self + .metadata + .pallet_by_index(self.pallet_index()) + .expect( + "event pallet to be found; we did this already during decoding", + ); + let variant = pallet + .event_variant_by_index(self.variant_index()) + .expect( + "event variant to be found; we did this already during decoding", + ); + EventMetadataDetails { + pallet, + variant, + } + } + /// Return _all_ of the bytes representing this event, which include, in order: + /// - The phase. + /// - Pallet and event index. + /// - Event fields. + /// - Event Topics. + pub fn bytes(&self) -> &[u8] { + &self.all_bytes[self.start_idx..self.end_idx] + } + /// Return the bytes representing the fields stored in this event. + pub fn field_bytes(&self) -> &[u8] { + &self.all_bytes[self.event_fields_start_idx..self.event_fields_end_idx] + } + /// Decode and provide the event fields back in the form of a [`scale_value::Composite`] + /// type which represents the named or unnamed fields that were present in the event. + pub fn field_values( + &self, + ) -> Result, Error> { + let bytes = &mut self.field_bytes(); + let event_metadata = self.event_metadata(); + let mut fields = event_metadata + .variant + .fields + .iter() + .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); + use scale_decode::DecodeAsFields; + let decoded = >::decode_as_fields(bytes, &mut fields, self.metadata.types())?; + Ok(decoded) + } + /// Attempt to decode these [`EventDetails`] into a type representing the event fields. + /// Such types are exposed in the codegen as `pallet_name::events::EventName` types. + pub fn as_event(&self) -> Result, Error> { + let ev_metadata = self.event_metadata(); + if ev_metadata.pallet.name() == E::PALLET + && ev_metadata.variant.name == E::EVENT + { + let mut fields = ev_metadata + .variant + .fields + .iter() + .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); + let decoded = E::decode_as_fields( + &mut self.field_bytes(), + &mut fields, + self.metadata.types(), + )?; + Ok(Some(decoded)) + } else { + Ok(None) + } + } + /// Attempt to decode these [`EventDetails`] into a root event type (which includes + /// the pallet and event enum variants as well as the event fields). A compatible + /// type for this is exposed via static codegen as a root level `Event` type. + pub fn as_root_event(&self) -> Result { + let bytes = &self + .all_bytes[self.event_start_idx..self.event_fields_end_idx]; + let decoded = E::decode_as_type( + &mut &bytes[..], + self.metadata.outer_enums().event_enum_ty(), + self.metadata.types(), + )?; + Ok(decoded) + } + /// Return the topics associated with this event. + pub fn topics(&self) -> &[T::Hash] { + &self.topics + } + } + /// Details for the given event plucked from the metadata. + pub struct EventMetadataDetails<'a> { + pub pallet: PalletMetadata<'a>, + pub variant: &'a scale_info::Variant, + } + } + use codec::{Decode, Encode}; + pub use events_client::EventsClient; + pub use events_type::{EventDetails, Events}; + use scale_decode::DecodeAsFields; + /// Trait to uniquely identify the events's identity from the runtime metadata. + /// + /// Generated API structures that represent an event implement this trait. + /// + /// The trait is utilized to decode emitted events from a block, via obtaining the + /// form of the `Event` from the metadata. + pub trait StaticEvent: DecodeAsFields { + /// Pallet name. + const PALLET: &'static str; + /// Event name. + const EVENT: &'static str; + /// Returns true if the given pallet and event names match this event. + fn is_event(pallet: &str, event: &str) -> bool { + Self::PALLET == pallet && Self::EVENT == event + } + } + /// A phase of a block's execution. + pub enum Phase { + /// Applying an extrinsic. + ApplyExtrinsic(u32), + /// Finalizing the block. + Finalization, + /// Initializing the block. + Initialization, + } + #[automatically_derived] + impl ::core::marker::Copy for Phase {} + #[automatically_derived] + impl ::core::clone::Clone for Phase { + #[inline] + fn clone(&self) -> Phase { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Phase { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + Phase::ApplyExtrinsic(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "ApplyExtrinsic", + &__self_0, + ) + } + Phase::Finalization => { + ::core::fmt::Formatter::write_str(f, "Finalization") + } + Phase::Initialization => { + ::core::fmt::Formatter::write_str(f, "Initialization") + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Phase { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Phase {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Phase { + #[inline] + fn eq(&self, other: &Phase) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + Phase::ApplyExtrinsic(__self_0), + Phase::ApplyExtrinsic(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for Phase { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e.chain("Could not decode `Phase`, failed to read variant byte") + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + Phase::ApplyExtrinsic({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `Phase::ApplyExtrinsic.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(Phase::Finalization) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(Phase::Initialization) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into("Could not decode `Phase`, variant doesn't exist"), + ) + })(); + } + } + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for Phase { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + Phase::ApplyExtrinsic(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + Phase::Finalization => 0_usize, + Phase::Initialization => 0_usize, + _ => 0_usize, + } + } + fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>( + &self, + __codec_dest_edqy: &mut __CodecOutputEdqy, + ) { + match *self { + Phase::ApplyExtrinsic(ref aa) => { + __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + Phase::Finalization => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); + } + Phase::Initialization => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::codec::EncodeLike for Phase {} + }; +} +pub mod metadata { + //! Types representing the metadata obtained from a node. + mod decode_encode_traits { + use super::Metadata; + use crate::error::Error; + /// This trait is implemented for all types that also implement [`scale_decode::DecodeAsType`]. + pub trait DecodeWithMetadata: Sized { + /// Given some metadata and a type ID, attempt to SCALE decode the provided bytes into `Self`. + fn decode_with_metadata( + bytes: &mut &[u8], + type_id: u32, + metadata: &Metadata, + ) -> Result; + } + impl DecodeWithMetadata for T { + fn decode_with_metadata( + bytes: &mut &[u8], + type_id: u32, + metadata: &Metadata, + ) -> Result { + let val = T::decode_as_type(bytes, type_id, metadata.types())?; + Ok(val) + } + } + /// This trait is implemented for all types that also implement [`scale_encode::EncodeAsType`]. + pub trait EncodeWithMetadata { + /// SCALE encode this type to bytes, possibly with the help of metadata. + fn encode_with_metadata( + &self, + type_id: u32, + metadata: &Metadata, + bytes: &mut Vec, + ) -> Result<(), Error>; + } + impl EncodeWithMetadata for T { + /// SCALE encode this type to bytes, possibly with the help of metadata. + fn encode_with_metadata( + &self, + type_id: u32, + metadata: &Metadata, + bytes: &mut Vec, + ) -> Result<(), Error> { + self.encode_as_type_to(type_id, metadata.types(), bytes)?; + Ok(()) + } + } + } + mod metadata_type { + use crate::error::MetadataError; + use std::sync::Arc; + /// A cheaply clone-able representation of the runtime metadata received from a node. + pub struct Metadata { + inner: Arc, + } + #[automatically_derived] + impl ::core::clone::Clone for Metadata { + #[inline] + fn clone(&self) -> Metadata { + Metadata { + inner: ::core::clone::Clone::clone(&self.inner), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Metadata { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "Metadata", + "inner", + &&self.inner, + ) + } + } + impl std::ops::Deref for Metadata { + type Target = subxt_metadata::Metadata; + fn deref(&self) -> &Self::Target { + &self.inner + } + } + impl Metadata { + pub(crate) fn new(md: subxt_metadata::Metadata) -> Self { + Metadata { inner: Arc::new(md) } + } + /// Identical to `metadata.pallet_by_name()`, but returns an error if the pallet is not found. + pub fn pallet_by_name_err( + &self, + name: &str, + ) -> Result { + self.pallet_by_name(name) + .ok_or_else(|| MetadataError::PalletNameNotFound(name.to_owned())) + } + /// Identical to `metadata.pallet_by_index()`, but returns an error if the pallet is not found. + pub fn pallet_by_index_err( + &self, + index: u8, + ) -> Result { + self.pallet_by_index(index) + .ok_or(MetadataError::PalletIndexNotFound(index)) + } + /// Identical to `metadata.runtime_api_trait_by_name()`, but returns an error if the trait is not found. + pub fn runtime_api_trait_by_name_err( + &self, + name: &str, + ) -> Result { + self.runtime_api_trait_by_name(name) + .ok_or_else(|| MetadataError::RuntimeTraitNotFound(name.to_owned())) + } + } + impl From for Metadata { + fn from(md: subxt_metadata::Metadata) -> Self { + Metadata::new(md) + } + } + impl TryFrom for Metadata { + type Error = subxt_metadata::TryFromError; + fn try_from( + value: frame_metadata::RuntimeMetadataPrefixed, + ) -> Result { + subxt_metadata::Metadata::try_from(value).map(Metadata::from) + } + } + impl codec::Decode for Metadata { + fn decode(input: &mut I) -> Result { + subxt_metadata::Metadata::decode(input).map(Metadata::new) + } + } + } + pub use decode_encode_traits::{DecodeWithMetadata, EncodeWithMetadata}; + pub use metadata_type::Metadata; + pub use subxt_metadata as types; +} +pub mod runtime_api { + //! Types associated with executing runtime API calls. + mod runtime_client { + use super::runtime_types::RuntimeApi; + use crate::{backend::BlockRef, client::OnlineClientT, error::Error, Config}; + use derivative::Derivative; + use std::{future::Future, marker::PhantomData}; + /// Execute runtime API calls. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct RuntimeApiClient { + client: Client, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for RuntimeApiClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + RuntimeApiClient { client: ref __arg_0, _marker: ref __arg_1 } => { + RuntimeApiClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl RuntimeApiClient { + /// Create a new [`RuntimeApiClient`] + pub fn new(client: Client) -> Self { + Self { + client, + _marker: PhantomData, + } + } + } + impl RuntimeApiClient + where + T: Config, + Client: OnlineClientT, + { + /// Obtain a runtime API interface at some block hash. + pub fn at( + &self, + block_ref: impl Into>, + ) -> RuntimeApi { + RuntimeApi::new(self.client.clone(), block_ref.into()) + } + /// Obtain a runtime API interface at the latest block hash. + pub fn at_latest( + &self, + ) -> impl Future< + Output = Result, Error>, + > + Send + 'static { + let client = self.client.clone(); + async move { + let block_ref = client.backend().latest_finalized_block_ref().await?; + Ok(RuntimeApi::new(client, block_ref)) + } + } + } + } + mod runtime_payload { + use core::marker::PhantomData; + use derivative::Derivative; + use scale_encode::EncodeAsFields; + use scale_value::Composite; + use std::borrow::Cow; + use crate::dynamic::DecodedValueThunk; + use crate::error::MetadataError; + use crate::{metadata::DecodeWithMetadata, Error, Metadata}; + /// This represents a runtime API payload that can call into the runtime of node. + /// + /// # Components + /// + /// - associated return type + /// + /// Resulting bytes of the call are interpreted into this type. + /// + /// - runtime function name + /// + /// The function name of the runtime API call. This is obtained by concatenating + /// the runtime trait name with the trait's method. + /// + /// For example, the substrate runtime trait [Metadata](https://github.com/paritytech/substrate/blob/cb954820a8d8d765ce75021e244223a3b4d5722d/primitives/api/src/lib.rs#L745) + /// contains the `metadata_at_version` function. The corresponding runtime function + /// is `Metadata_metadata_at_version`. + /// + /// - encoded arguments + /// + /// Each argument of the runtime function must be scale-encoded. + pub trait RuntimeApiPayload { + /// The return type of the function call. + type ReturnType: DecodeWithMetadata; + /// The runtime API trait name. + fn trait_name(&self) -> &str; + /// The runtime API method name. + fn method_name(&self) -> &str; + /// Scale encode the arguments data. + fn encode_args_to( + &self, + metadata: &Metadata, + out: &mut Vec, + ) -> Result<(), Error>; + /// Encode arguments data and return the output. This is a convenience + /// wrapper around [`RuntimeApiPayload::encode_args_to`]. + fn encode_args(&self, metadata: &Metadata) -> Result, Error> { + let mut v = Vec::new(); + self.encode_args_to(metadata, &mut v)?; + Ok(v) + } + /// Returns the statically generated validation hash. + fn validation_hash(&self) -> Option<[u8; 32]> { + None + } + } + /// A runtime API payload containing the generic argument data + /// and interpreting the result of the call as `ReturnTy`. + /// + /// This can be created from static values (ie those generated + /// via the `subxt` macro) or dynamic values via [`dynamic`]. + #[derivative( + Clone(bound = "ArgsData: Clone"), + Debug(bound = "ArgsData: std::fmt::Debug"), + Eq(bound = "ArgsData: std::cmp::Eq"), + Ord(bound = "ArgsData: std::cmp::Ord"), + PartialEq(bound = "ArgsData: std::cmp::PartialEq"), + PartialOrd(bound = "ArgsData: std::cmp::PartialOrd") + )] + pub struct Payload { + trait_name: Cow<'static, str>, + method_name: Cow<'static, str>, + args_data: ArgsData, + validation_hash: Option<[u8; 32]>, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Payload + where + ArgsData: Clone, + { + fn clone(&self) -> Self { + match *self { + Payload { + trait_name: ref __arg_0, + method_name: ref __arg_1, + args_data: ref __arg_2, + validation_hash: ref __arg_3, + _marker: ref __arg_4, + } => { + Payload { + trait_name: (*__arg_0).clone(), + method_name: (*__arg_1).clone(), + args_data: (*__arg_2).clone(), + validation_hash: (*__arg_3).clone(), + _marker: (*__arg_4).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Payload + where + ArgsData: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Payload { + trait_name: ref __arg_0, + method_name: ref __arg_1, + args_data: ref __arg_2, + validation_hash: ref __arg_3, + _marker: ref __arg_4, + } => { + let mut __debug_trait_builder = __f.debug_struct("Payload"); + let _ = __debug_trait_builder.field("trait_name", &&(*__arg_0)); + let _ = __debug_trait_builder.field("method_name", &&(*__arg_1)); + let _ = __debug_trait_builder.field("args_data", &&(*__arg_2)); + let _ = __debug_trait_builder + .field("validation_hash", &&(*__arg_3)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_4)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for Payload + where + ArgsData: std::cmp::Eq, + {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for Payload + where + ArgsData: std::cmp::PartialEq, + { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + Payload { + trait_name: ref __self_0, + method_name: ref __self_1, + args_data: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Payload { + trait_name: ref __other_0, + method_name: ref __other_1, + args_data: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + && &(*__self_3) == &(*__other_3) + && &(*__self_4) == &(*__other_4) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialOrd for Payload + where + ArgsData: std::cmp::PartialOrd, + { + fn partial_cmp( + &self, + other: &Self, + ) -> ::std::option::Option<::std::cmp::Ordering> { + match *self { + Payload { + trait_name: ref __self_0, + method_name: ref __self_1, + args_data: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Payload { + trait_name: ref __other_0, + method_name: ref __other_1, + args_data: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_0), + &(*__other_0), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_1), + &(*__other_1), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_2), + &(*__other_2), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_3), + &(*__other_3), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_4), + &(*__other_4), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::Ord for Payload + where + ArgsData: std::cmp::Ord, + { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + Payload { + trait_name: ref __self_0, + method_name: ref __self_1, + args_data: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Payload { + trait_name: ref __other_0, + method_name: ref __other_1, + args_data: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_4), &(*__other_4)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + impl RuntimeApiPayload + for Payload { + type ReturnType = ReturnTy; + fn trait_name(&self) -> &str { + &self.trait_name + } + fn method_name(&self) -> &str { + &self.method_name + } + fn encode_args_to( + &self, + metadata: &Metadata, + out: &mut Vec, + ) -> Result<(), Error> { + let api_method = metadata + .runtime_api_trait_by_name_err(&self.trait_name)? + .method_by_name(&self.method_name) + .ok_or_else(|| MetadataError::RuntimeMethodNotFound( + (*self.method_name).to_owned(), + ))?; + let mut fields = api_method + .inputs() + .map(|input| scale_encode::Field::named(input.ty, &input.name)); + self.args_data.encode_as_fields_to(&mut fields, metadata.types(), out)?; + Ok(()) + } + fn validation_hash(&self) -> Option<[u8; 32]> { + self.validation_hash + } + } + /// A dynamic runtime API payload. + pub type DynamicRuntimeApiPayload = Payload, DecodedValueThunk>; + impl Payload { + /// Create a new [`Payload`]. + pub fn new( + trait_name: impl Into, + method_name: impl Into, + args_data: ArgsData, + ) -> Self { + Payload { + trait_name: Cow::Owned(trait_name.into()), + method_name: Cow::Owned(method_name.into()), + args_data, + validation_hash: None, + _marker: PhantomData, + } + } + /// Create a new static [`Payload`] using static function name + /// and scale-encoded argument data. + /// + /// This is only expected to be used from codegen. + #[doc(hidden)] + pub fn new_static( + trait_name: &'static str, + method_name: &'static str, + args_data: ArgsData, + hash: [u8; 32], + ) -> Payload { + Payload { + trait_name: Cow::Borrowed(trait_name), + method_name: Cow::Borrowed(method_name), + args_data, + validation_hash: Some(hash), + _marker: std::marker::PhantomData, + } + } + /// Do not validate this call prior to submitting it. + pub fn unvalidated(self) -> Self { + Self { + validation_hash: None, + ..self + } + } + /// Returns the trait name. + pub fn trait_name(&self) -> &str { + &self.trait_name + } + /// Returns the method name. + pub fn method_name(&self) -> &str { + &self.method_name + } + /// Returns the arguments data. + pub fn args_data(&self) -> &ArgsData { + &self.args_data + } + } + /// Create a new [`DynamicRuntimeApiPayload`]. + pub fn dynamic( + trait_name: impl Into, + method_name: impl Into, + args_data: impl Into>, + ) -> DynamicRuntimeApiPayload { + Payload::new(trait_name, method_name, args_data.into()) + } + } + mod runtime_types { + use crate::{ + backend::{BackendExt, BlockRef}, + client::OnlineClientT, error::{Error, MetadataError}, + metadata::DecodeWithMetadata, Config, + }; + use codec::Decode; + use derivative::Derivative; + use std::{future::Future, marker::PhantomData}; + use super::RuntimeApiPayload; + /// Execute runtime API calls. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct RuntimeApi { + client: Client, + block_ref: BlockRef, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for RuntimeApi + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + RuntimeApi { + client: ref __arg_0, + block_ref: ref __arg_1, + _marker: ref __arg_2, + } => { + RuntimeApi { + client: (*__arg_0).clone(), + block_ref: (*__arg_1).clone(), + _marker: (*__arg_2).clone(), + } + } + } + } + } + impl RuntimeApi { + /// Create a new [`RuntimeApi`] + pub(crate) fn new(client: Client, block_ref: BlockRef) -> Self { + Self { + client, + block_ref, + _marker: PhantomData, + } + } + } + impl RuntimeApi + where + T: Config, + Client: OnlineClientT, + { + /// Execute a raw runtime API call. + pub fn call_raw<'a, Res: Decode>( + &self, + function: &'a str, + call_parameters: Option<&'a [u8]>, + ) -> impl Future> + 'a { + let client = self.client.clone(); + let block_hash = self.block_ref.hash(); + async move { + let data: Res = client + .backend() + .call_decoding(function, call_parameters, block_hash) + .await?; + Ok(data) + } + } + /// Execute a runtime API call. + pub fn call( + &self, + payload: Call, + ) -> impl Future> { + let client = self.client.clone(); + let block_hash = self.block_ref.hash(); + async move { + let metadata = client.metadata(); + let api_trait = metadata + .runtime_api_trait_by_name_err(payload.trait_name())?; + let api_method = api_trait + .method_by_name(payload.method_name()) + .ok_or_else(|| { + MetadataError::RuntimeMethodNotFound( + payload.method_name().to_owned(), + ) + })?; + if let Some(static_hash) = payload.validation_hash() { + let Some(runtime_hash) = api_trait + .method_hash(payload.method_name()) else { + return Err(MetadataError::IncompatibleCodegen.into()); + }; + if static_hash != runtime_hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + } + let params = payload.encode_args(&metadata)?; + let call_name = { + let res = ::alloc::fmt::format( + format_args!( + "{0}_{1}", payload.trait_name(), payload.method_name() + ), + ); + res + }; + let bytes = client + .backend() + .call(&call_name, Some(params.as_slice()), block_hash) + .await?; + let value = ::decode_with_metadata( + &mut &bytes[..], + api_method.output_ty(), + &metadata, + )?; + Ok(value) + } + } + } + } + pub use runtime_client::RuntimeApiClient; + pub use runtime_payload::{ + dynamic, DynamicRuntimeApiPayload, Payload, RuntimeApiPayload, + }; + pub use runtime_types::RuntimeApi; +} +pub mod storage { + //! Types associated with accessing and working with storage items. + mod storage_address { + use crate::{ + dynamic::DecodedValueThunk, + error::{Error, MetadataError, StorageAddressError}, + metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, + utils::{Encoded, Static}, + }; + use derivative::Derivative; + use scale_info::TypeDef; + use std::borrow::Cow; + use subxt_metadata::{StorageEntryType, StorageHasher}; + use super::StorageKey; + /// This represents a storage address. Anything implementing this trait + /// can be used to fetch and iterate over storage entries. + pub trait StorageAddress { + /// The target type of the value that lives at this address. + type Target: DecodeWithMetadata; + /// The keys type used to construct this address. + type Keys: StorageKey; + /// Can an entry be fetched from this address? + /// Set this type to [`Yes`] to enable the corresponding calls to be made. + type IsFetchable; + /// Can a default entry be obtained from this address? + /// Set this type to [`Yes`] to enable the corresponding calls to be made. + type IsDefaultable; + /// Can this address be iterated over? + /// Set this type to [`Yes`] to enable the corresponding calls to be made. + type IsIterable; + /// The name of the pallet that the entry lives under. + fn pallet_name(&self) -> &str; + /// The name of the entry in a given pallet that the item is at. + fn entry_name(&self) -> &str; + /// Output the non-prefix bytes; that is, any additional bytes that need + /// to be appended to the key to dig into maps. + fn append_entry_bytes( + &self, + metadata: &Metadata, + bytes: &mut Vec, + ) -> Result<(), Error>; + /// An optional hash which, if present, will be checked against + /// the node metadata to confirm that the return type matches what + /// we are expecting. + fn validation_hash(&self) -> Option<[u8; 32]> { + None + } + } + /// Used to signal whether a [`StorageAddress`] can be iterated, + /// fetched and returned with a default value in the type system. + pub struct Yes; + /// A concrete storage address. This can be created from static values (ie those generated + /// via the `subxt` macro) or dynamic values via [`dynamic`]. + #[derivative( + Clone(bound = "Keys: Clone"), + Debug(bound = "Keys: std::fmt::Debug"), + Eq(bound = "Keys: std::cmp::Eq"), + Ord(bound = "Keys: std::cmp::Ord"), + PartialEq(bound = "Keys: std::cmp::PartialEq"), + PartialOrd(bound = "Keys: std::cmp::PartialOrd") + )] + pub struct Address< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > { + pallet_name: Cow<'static, str>, + entry_name: Cow<'static, str>, + keys: Keys, + validation_hash: Option<[u8; 32]>, + _marker: std::marker::PhantomData< + (ReturnTy, Fetchable, Defaultable, Iterable), + >, + } + #[allow(unused_qualifications)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::clone::Clone + for Address + where + Keys: Clone, + { + fn clone(&self) -> Self { + match *self { + Address { + pallet_name: ref __arg_0, + entry_name: ref __arg_1, + keys: ref __arg_2, + validation_hash: ref __arg_3, + _marker: ref __arg_4, + } => { + Address { + pallet_name: (*__arg_0).clone(), + entry_name: (*__arg_1).clone(), + keys: (*__arg_2).clone(), + validation_hash: (*__arg_3).clone(), + _marker: (*__arg_4).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::fmt::Debug for Address + where + Keys: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Address { + pallet_name: ref __arg_0, + entry_name: ref __arg_1, + keys: ref __arg_2, + validation_hash: ref __arg_3, + _marker: ref __arg_4, + } => { + let mut __debug_trait_builder = __f.debug_struct("Address"); + let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); + let _ = __debug_trait_builder.field("entry_name", &&(*__arg_1)); + let _ = __debug_trait_builder.field("keys", &&(*__arg_2)); + let _ = __debug_trait_builder + .field("validation_hash", &&(*__arg_3)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_4)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq + for Address + where + Keys: std::cmp::Eq, + {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::cmp::PartialEq + for Address + where + Keys: std::cmp::PartialEq, + { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + Address { + pallet_name: ref __self_0, + entry_name: ref __self_1, + keys: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Address { + pallet_name: ref __other_0, + entry_name: ref __other_1, + keys: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + && &(*__self_3) == &(*__other_3) + && &(*__self_4) == &(*__other_4) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::cmp::PartialOrd + for Address + where + Keys: std::cmp::PartialOrd, + { + fn partial_cmp( + &self, + other: &Self, + ) -> ::std::option::Option<::std::cmp::Ordering> { + match *self { + Address { + pallet_name: ref __self_0, + entry_name: ref __self_1, + keys: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Address { + pallet_name: ref __other_0, + entry_name: ref __other_1, + keys: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_0), + &(*__other_0), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_1), + &(*__other_1), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_2), + &(*__other_2), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_3), + &(*__other_3), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_4), + &(*__other_4), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl< + Keys: StorageKey, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > ::std::cmp::Ord for Address + where + Keys: std::cmp::Ord, + { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + Address { + pallet_name: ref __self_0, + entry_name: ref __self_1, + keys: ref __self_2, + validation_hash: ref __self_3, + _marker: ref __self_4, + } => { + match *other { + Address { + pallet_name: ref __other_0, + entry_name: ref __other_1, + keys: ref __other_2, + validation_hash: ref __other_3, + _marker: ref __other_4, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_4), &(*__other_4)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + /// A storage key for static encoded values. + /// The original value is only present at construction, but can be decoded from the contained bytes. + #[derivative(Clone(bound = ""), Debug(bound = ""))] + pub struct StaticStorageKey { + pub(super) bytes: Static, + pub(super) _marker: std::marker::PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for StaticStorageKey { + fn clone(&self) -> Self { + match *self { + StaticStorageKey { bytes: ref __arg_0, _marker: ref __arg_1 } => { + StaticStorageKey { + bytes: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for StaticStorageKey { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + StaticStorageKey { bytes: ref __arg_0, _marker: ref __arg_1 } => { + let mut __debug_trait_builder = __f + .debug_struct("StaticStorageKey"); + let _ = __debug_trait_builder.field("bytes", &&(*__arg_0)); + let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + impl StaticStorageKey { + /// Creates a new static storage key + pub fn new(key: &K) -> Self { + StaticStorageKey { + bytes: Static(Encoded(key.encode())), + _marker: std::marker::PhantomData, + } + } + /// Returns the scale-encoded bytes that make up this key + pub fn bytes(&self) -> &[u8] { + &self.bytes.0.0 + } + } + /// A typical storage address constructed at runtime rather than via the `subxt` macro; this + /// has no restriction on what it can be used for (since we don't statically know). + pub type DynamicAddress = Address; + impl DynamicAddress { + /// Creates a new dynamic address. As `Keys` you can use a `Vec` + pub fn new( + pallet_name: impl Into, + entry_name: impl Into, + keys: Keys, + ) -> Self { + Self { + pallet_name: Cow::Owned(pallet_name.into()), + entry_name: Cow::Owned(entry_name.into()), + keys, + validation_hash: None, + _marker: std::marker::PhantomData, + } + } + } + impl< + Keys, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > Address + where + Keys: StorageKey, + ReturnTy: DecodeWithMetadata, + { + /// Create a new [`Address`] using static strings for the pallet and call name. + /// This is only expected to be used from codegen. + #[doc(hidden)] + pub fn new_static( + pallet_name: &'static str, + entry_name: &'static str, + keys: Keys, + hash: [u8; 32], + ) -> Self { + Self { + pallet_name: Cow::Borrowed(pallet_name), + entry_name: Cow::Borrowed(entry_name), + keys, + validation_hash: Some(hash), + _marker: std::marker::PhantomData, + } + } + } + impl< + Keys, + ReturnTy, + Fetchable, + Defaultable, + Iterable, + > Address + where + Keys: StorageKey, + ReturnTy: DecodeWithMetadata, + { + /// Do not validate this storage entry prior to accessing it. + pub fn unvalidated(self) -> Self { + Self { + validation_hash: None, + ..self + } + } + /// Return bytes representing the root of this storage entry (ie a hash of + /// the pallet and entry name). Use [`crate::storage::StorageClient::address_bytes()`] + /// to obtain the bytes representing the entire address. + pub fn to_root_bytes(&self) -> Vec { + super::utils::storage_address_root_bytes(self) + } + } + impl StorageAddress + for Address + where + Keys: StorageKey, + ReturnTy: DecodeWithMetadata, + { + type Target = ReturnTy; + type Keys = Keys; + type IsFetchable = Fetchable; + type IsDefaultable = Defaultable; + type IsIterable = Iterable; + fn pallet_name(&self) -> &str { + &self.pallet_name + } + fn entry_name(&self) -> &str { + &self.entry_name + } + fn append_entry_bytes( + &self, + metadata: &Metadata, + bytes: &mut Vec, + ) -> Result<(), Error> { + let pallet = metadata.pallet_by_name_err(self.pallet_name())?; + let storage = pallet + .storage() + .ok_or_else(|| MetadataError::StorageNotFoundInPallet( + self.pallet_name().to_owned(), + ))?; + let entry = storage + .entry_by_name(self.entry_name()) + .ok_or_else(|| MetadataError::StorageEntryNotFound( + self.entry_name().to_owned(), + ))?; + let keys_iter = self.keys.keys_iter(); + let keys_len = self.keys.keys_len(); + if keys_len == 0 { + return Ok(()); + } + let StorageEntryType::Map { hashers, key_ty, .. } = entry + .entry_type() else { + return Err( + StorageAddressError::WrongNumberOfKeys { + expected: 0, + actual: keys_len, + } + .into(), + ); + }; + let ty = metadata + .types() + .resolve(*key_ty) + .ok_or(MetadataError::TypeNotFound(*key_ty))?; + let type_ids = match &ty.type_def { + TypeDef::Tuple(tuple) => { + either::Either::Left(tuple.fields.iter().map(|f| f.id)) + } + _other => either::Either::Right(std::iter::once(*key_ty)), + }; + if hashers.len() == 1 { + let mut input = Vec::new(); + let iter = keys_iter.zip(type_ids); + for (key, type_id) in iter { + key.encode_with_metadata(type_id, metadata, &mut input)?; + } + hash_bytes(&input, &hashers[0], bytes); + } else if hashers.len() >= type_ids.len() { + let iter = keys_iter.zip(type_ids).zip(hashers); + for ((key, type_id), hasher) in iter { + let mut input = Vec::new(); + key.encode_with_metadata(type_id, metadata, &mut input)?; + hash_bytes(&input, hasher, bytes); + } + } else { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: type_ids.len(), + } + .into(), + ); + } + Ok(()) + } + fn validation_hash(&self) -> Option<[u8; 32]> { + self.validation_hash + } + } + /// Construct a new dynamic storage lookup. + pub fn dynamic( + pallet_name: impl Into, + entry_name: impl Into, + storage_entry_keys: Keys, + ) -> DynamicAddress { + DynamicAddress::new(pallet_name, entry_name, storage_entry_keys) + } + /// Take some SCALE encoded bytes and a [`StorageHasher`] and hash the bytes accordingly. + fn hash_bytes(input: &[u8], hasher: &StorageHasher, bytes: &mut Vec) { + match hasher { + StorageHasher::Identity => bytes.extend(input), + StorageHasher::Blake2_128 => { + bytes.extend(sp_core_hashing::blake2_128(input)) + } + StorageHasher::Blake2_128Concat => { + bytes.extend(sp_core_hashing::blake2_128(input)); + bytes.extend(input); + } + StorageHasher::Blake2_256 => { + bytes.extend(sp_core_hashing::blake2_256(input)) + } + StorageHasher::Twox128 => bytes.extend(sp_core_hashing::twox_128(input)), + StorageHasher::Twox256 => bytes.extend(sp_core_hashing::twox_256(input)), + StorageHasher::Twox64Concat => { + bytes.extend(sp_core_hashing::twox_64(input)); + bytes.extend(input); + } + } + } + } + mod storage_client { + use super::{ + storage_type::{validate_storage_address, Storage}, + utils, StorageAddress, + }; + use crate::{ + backend::BlockRef, client::{OfflineClientT, OnlineClientT}, + error::Error, Config, + }; + use derivative::Derivative; + use std::{future::Future, marker::PhantomData}; + /// Query the runtime storage. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct StorageClient { + client: Client, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for StorageClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + StorageClient { client: ref __arg_0, _marker: ref __arg_1 } => { + StorageClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl StorageClient { + /// Create a new [`StorageClient`] + pub fn new(client: Client) -> Self { + Self { + client, + _marker: PhantomData, + } + } + } + impl StorageClient + where + T: Config, + Client: OfflineClientT, + { + /// Run the validation logic against some storage address you'd like to access. Returns `Ok(())` + /// if the address is valid (or if it's not possible to check since the address has no validation hash). + /// Return an error if the address was not valid or something went wrong trying to validate it (ie + /// the pallet or storage entry in question do not exist at all). + pub fn validate( + &self, + address: &Address, + ) -> Result<(), Error> { + let metadata = self.client.metadata(); + let pallet_metadata = metadata + .pallet_by_name_err(address.pallet_name())?; + validate_storage_address(address, pallet_metadata) + } + /// Convert some storage address into the raw bytes that would be submitted to the node in order + /// to retrieve the entries at the root of the associated address. + pub fn address_root_bytes( + &self, + address: &Address, + ) -> Vec { + utils::storage_address_root_bytes(address) + } + /// Convert some storage address into the raw bytes that would be submitted to the node in order + /// to retrieve an entry. This fails if [`StorageAddress::append_entry_bytes`] does; in the built-in + /// implementation this would be if the pallet and storage entry being asked for is not available on the + /// node you're communicating with, or if the metadata is missing some type information (which should not + /// happen). + pub fn address_bytes( + &self, + address: &Address, + ) -> Result, Error> { + utils::storage_address_bytes(address, &self.client.metadata()) + } + } + impl StorageClient + where + T: Config, + Client: OnlineClientT, + { + /// Obtain storage at some block hash. + pub fn at( + &self, + block_ref: impl Into>, + ) -> Storage { + Storage::new(self.client.clone(), block_ref.into()) + } + /// Obtain storage at the latest block hash. + pub fn at_latest( + &self, + ) -> impl Future< + Output = Result, Error>, + > + Send + 'static { + let client = self.client.clone(); + async move { + let block_ref = client.backend().latest_finalized_block_ref().await?; + Ok(Storage::new(client, block_ref)) + } + } + } + } + mod storage_key { + use super::{ + storage_address::StaticStorageKey, + utils::{ + hash_contains_unhashed_value, strip_storage_addess_root_bytes, + strip_storage_hash_bytes, + }, + }; + use crate::{ + dynamic::DecodedValueThunk, error::{Error, StorageAddressError}, + metadata::{DecodeWithMetadata, Metadata}, + utils::{Encoded, Static}, + }; + use scale_encode::EncodeAsType; + use subxt_metadata::StorageHasher; + /// This trait should be implemented by anything that can be used as one or multiple storage keys. + pub trait StorageKey { + /// Iterator over the storage keys, each key implements EncodeAsType to + /// give the corresponding bytes to a `StorageHasher`. + fn keys_iter(&self) -> impl Iterator; + /// How many keys are there in total? Each key is an element that needs to be individually hashed. + fn keys_len(&self) -> usize; + /// Attempts to decode the StorageKey from a storage address that has been stripped of its root bytes. + /// + /// Example: Imagine The `StorageKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. + /// Then the memory layout of the storage address is: + /// ```txt + /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | + /// ``` + /// `cursor` should point into a region after those first 16 bytes, at the start of a new hash. + /// `hashers_and_ty_ids` should consume all the hashers that have been used for decoding, such that there are less hashers coming to the next key. + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static; + } + /// Implement `StorageKey` for `()` which can be used for keyless storage entries. + impl StorageKey for () { + fn keys_iter(&self) -> impl Iterator { + std::iter::empty() + } + fn keys_len(&self) -> usize { + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + _metadata: &Metadata, + ) -> Result { + if hashers_and_ty_ids.is_empty() { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into(), + ); + } + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; + Ok(()) + } + } + impl StorageKey + for StaticStorageKey { + fn keys_iter(&self) -> impl Iterator { + std::iter::once(&self.bytes as &dyn EncodeAsType) + } + fn keys_len(&self) -> usize { + 1 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into(), + ); + }; + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; + decode_storage_key_from_hash(cursor, hasher, *ty_id, metadata) + } + } + pub fn decode_storage_key_from_hash( + cursor: &mut &[u8], + hasher: &StorageHasher, + ty_id: u32, + metadata: &Metadata, + ) -> Result, Error> { + strip_storage_hash_bytes(cursor, hasher)?; + let bytes = *cursor; + if let Err(err) + = scale_decode::visitor::decode_with_visitor( + cursor, + ty_id, + metadata.types(), + scale_decode::visitor::IgnoreVisitor, + ) { + return Err(scale_decode::Error::from(err).into()); + } + let bytes_decoded = bytes.len() - cursor.len(); + if !hash_contains_unhashed_value(hasher) && bytes_decoded > 0 { + let ty_name = metadata + .types() + .resolve(ty_id) + .expect( + "ty_id is in metadata, because decode_with_visitor did not fail above; qed", + ) + .path + .to_string(); + return Err( + StorageAddressError::HasherCannotReconstructKey { + ty_id, + ty_name, + hasher: *hasher, + } + .into(), + ); + } + let key_bytes = bytes[..bytes_decoded].to_vec(); + let key = StaticStorageKey { + bytes: Static(Encoded(key_bytes)), + _marker: std::marker::PhantomData::, + }; + Ok(key) + } + impl StorageKey for Vec { + fn keys_iter(&self) -> impl Iterator { + self.iter().map(|e| e as &dyn EncodeAsType) + } + fn keys_len(&self) -> usize { + self.len() + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); + let mut result: Vec = ::alloc::vec::Vec::new(); + let mut n = 0; + while !cursor.is_empty() { + let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { + return Err(StorageAddressError::UnexpectedAddressBytes.into()); + }; + strip_storage_hash_bytes(cursor, hasher)?; + let decoded = DecodedValueThunk::decode_with_metadata( + cursor, + *ty_id, + metadata, + )?; + let value = decoded.to_value()?; + result.push(value.remove_context()); + n += 1; + } + *hashers_and_ty_ids = &hashers_and_ty_ids[n..]; + Ok(result) + } + } + #[rustfmt::skip] + const _: () = { + { + impl StorageKey for (A, B) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl StorageKey + for (A, B, C) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + > StorageKey for (A, B, C, D) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + E: StorageKey, + > StorageKey for (A, B, C, D, E) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + (self.4.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + (0 * 4 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[4]; + let key = E::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + E: StorageKey, + F: StorageKey, + > StorageKey for (A, B, C, D, E, F) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + (self.4.keys_len()) + + (self.5.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[4]; + let key = E::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[5]; + let key = F::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + E: StorageKey, + F: StorageKey, + G: StorageKey, + > StorageKey for (A, B, C, D, E, F, G) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + (self.4.keys_len()) + + (self.5.keys_len()) + (self.6.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + (0 * 6 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[4]; + let key = E::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[5]; + let key = F::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[6]; + let key = G::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + { + impl< + A: StorageKey, + B: StorageKey, + C: StorageKey, + D: StorageKey, + E: StorageKey, + F: StorageKey, + G: StorageKey, + H: StorageKey, + > StorageKey for (A, B, C, D, E, F, G, H) { + fn keys_iter(&self) -> impl Iterator { + () + } + fn keys_len(&self) -> usize { + (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) + + (self.3.keys_len()) + (self.4.keys_len()) + + (self.5.keys_len()) + (self.6.keys_len()) + + (self.7.keys_len()) + 0 + } + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + metadata: &Metadata, + ) -> Result + where + Self: Sized + 'static, + { + const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) + + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + (0 * 6 + 1) + + (0 * 7 + 1) + 0; + let tuple: Self = ( + { + let (hasher, ty_id) = &hashers_and_ty_ids[0]; + let key = A::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[1]; + let key = B::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[2]; + let key = C::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[3]; + let key = D::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[4]; + let key = E::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[5]; + let key = F::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[6]; + let key = G::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + { + let (hasher, ty_id) = &hashers_and_ty_ids[7]; + let key = H::decode_from_bytes( + cursor, + hashers_and_ty_ids, + metadata, + )?; + key + }, + ); + return Ok(tuple); + } + } + }; + }; + } + mod storage_type { + use super::storage_address::{StorageAddress, Yes}; + use super::utils::strip_storage_addess_root_bytes; + use super::StorageKey; + use crate::{ + backend::{BackendExt, BlockRef}, + client::OnlineClientT, error::{Error, MetadataError, StorageAddressError}, + metadata::{DecodeWithMetadata, Metadata}, + Config, + }; + use codec::Decode; + use derivative::Derivative; + use futures::StreamExt; + use scale_info::TypeDef; + use std::{future::Future, marker::PhantomData}; + use subxt_metadata::StorageHasher; + use subxt_metadata::{PalletMetadata, StorageEntryMetadata, StorageEntryType}; + /// This is returned from a couple of storage functions. + pub use crate::backend::StreamOfResults; + /// Query the runtime storage. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct Storage { + client: Client, + block_ref: BlockRef, + _marker: PhantomData, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Storage + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + Storage { + client: ref __arg_0, + block_ref: ref __arg_1, + _marker: ref __arg_2, + } => { + Storage { + client: (*__arg_0).clone(), + block_ref: (*__arg_1).clone(), + _marker: (*__arg_2).clone(), + } + } + } + } + } + impl Storage { + /// Create a new [`Storage`] + pub(crate) fn new(client: Client, block_ref: BlockRef) -> Self { + Self { + client, + block_ref, + _marker: PhantomData, + } + } + } + impl Storage + where + T: Config, + Client: OnlineClientT, + { + /// Fetch the raw encoded value at the key given. + pub fn fetch_raw( + &self, + key: impl Into>, + ) -> impl Future>, Error>> + 'static { + let client = self.client.clone(); + let key = key.into(); + let block_ref = self.block_ref.clone(); + async move { + let data = client + .backend() + .storage_fetch_value(key, block_ref.hash()) + .await?; + Ok(data) + } + } + /// Stream all of the raw keys underneath the key given + pub fn fetch_raw_keys( + &self, + key: impl Into>, + ) -> impl Future< + Output = Result>, Error>, + > + 'static { + let client = self.client.clone(); + let block_hash = self.block_ref.hash(); + let key = key.into(); + async move { + let keys = client + .backend() + .storage_fetch_descendant_keys(key, block_hash) + .await?; + Ok(keys) + } + } + /// Fetch a decoded value from storage at a given address. + /// + /// # Example + /// + /// ```no_run + /// use subxt::{ PolkadotConfig, OnlineClient }; + /// + /// #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] + /// pub mod polkadot {} + /// + /// # #[tokio::main] + /// # async fn main() { + /// let api = OnlineClient::::new().await.unwrap(); + /// + /// // Address to a storage entry we'd like to access. + /// let address = polkadot::storage().xcm_pallet().queries(&12345); + /// + /// // Fetch just the keys, returning up to 10 keys. + /// let value = api + /// .storage() + /// .at_latest() + /// .await + /// .unwrap() + /// .fetch(&address) + /// .await + /// .unwrap(); + /// + /// println!("Value: {:?}", value); + /// # } + /// ``` + pub fn fetch<'address, Address>( + &self, + address: &'address Address, + ) -> impl Future, Error>> + 'address + where + Address: StorageAddress + 'address, + { + let client = self.clone(); + async move { + let metadata = client.client.metadata(); + let (pallet, entry) = lookup_entry_details( + address.pallet_name(), + address.entry_name(), + &metadata, + )?; + validate_storage_address(address, pallet)?; + let lookup_bytes = super::utils::storage_address_bytes( + address, + &metadata, + )?; + if let Some(data) = client.fetch_raw(lookup_bytes).await? { + let val = decode_storage_with_metadata::< + Address::Target, + >(&mut &*data, &metadata, entry)?; + Ok(Some(val)) + } else { + Ok(None) + } + } + } + /// Fetch a StorageKey that has a default value with an optional block hash. + pub fn fetch_or_default<'address, Address>( + &self, + address: &'address Address, + ) -> impl Future> + 'address + where + Address: StorageAddress + + 'address, + { + let client = self.clone(); + async move { + let pallet_name = address.pallet_name(); + let entry_name = address.entry_name(); + if let Some(data) = client.fetch(address).await? { + Ok(data) + } else { + let metadata = client.client.metadata(); + let (_pallet_metadata, storage_entry) = lookup_entry_details( + pallet_name, + entry_name, + &metadata, + )?; + let return_ty_id = return_type_from_storage_entry_type( + storage_entry.entry_type(), + ); + let bytes = &mut storage_entry.default_bytes(); + let val = Address::Target::decode_with_metadata( + bytes, + return_ty_id, + &metadata, + )?; + Ok(val) + } + } + } + /// Returns an iterator of key value pairs. + /// + /// ```no_run + /// use subxt::{ PolkadotConfig, OnlineClient }; + /// + /// #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] + /// pub mod polkadot {} + /// + /// # #[tokio::main] + /// # async fn main() { + /// let api = OnlineClient::::new().await.unwrap(); + /// + /// // Address to the root of a storage entry that we'd like to iterate over. + /// let address = polkadot::storage().xcm_pallet().version_notifiers_iter(); + /// + /// // Iterate over keys and values at that address. + /// let mut iter = api + /// .storage() + /// .at_latest() + /// .await + /// .unwrap() + /// .iter(address) + /// .await + /// .unwrap(); + /// + /// while let Some(Ok(kv)) = iter.next().await { + /// println!("Key bytes: 0x{}", hex::encode(&kv.key_bytes)); + /// println!("Value: {}", kv.value); + /// } + /// # } + /// ``` + pub fn iter
( + &self, + address: Address, + ) -> impl Future< + Output = Result>, Error>, + > + 'static + where + Address: StorageAddress + 'static, + Address::Keys: 'static + Sized, + { + let client = self.client.clone(); + let block_ref = self.block_ref.clone(); + async move { + let metadata = client.metadata(); + let (pallet, entry) = lookup_entry_details( + address.pallet_name(), + address.entry_name(), + &metadata, + )?; + validate_storage_address(&address, pallet)?; + let entry = entry.entry_type(); + let return_type_id = entry.value_ty(); + let hasher_type_id_pairs = storage_hasher_type_id_pairs( + entry, + &metadata, + )?; + let address_bytes = super::utils::storage_address_bytes( + &address, + &metadata, + )?; + let s = client + .backend() + .storage_fetch_descendant_values(address_bytes, block_ref.hash()) + .await? + .map(move |kv| { + let kv = match kv { + Ok(kv) => kv, + Err(e) => return Err(e), + }; + let value = Address::Target::decode_with_metadata( + &mut &*kv.value, + return_type_id, + &metadata, + )?; + let key_bytes = kv.key; + let cursor = &mut &key_bytes[..]; + strip_storage_addess_root_bytes(cursor)?; + let keys = ::decode_from_bytes( + cursor, + &hasher_type_id_pairs, + &metadata, + )?; + Ok(StorageKeyValuePair::
{ + keys, + key_bytes, + value, + }) + }); + let s = StreamOfResults::new(Box::pin(s)); + Ok(s) + } + } + /// The storage version of a pallet. + /// The storage version refers to the `frame_support::traits::Metadata::StorageVersion` type. + pub async fn storage_version( + &self, + pallet_name: impl AsRef, + ) -> Result { + self.client + .metadata() + .pallet_by_name(pallet_name.as_ref()) + .ok_or_else(|| MetadataError::PalletNameNotFound( + pallet_name.as_ref().into(), + ))?; + pub const STORAGE_VERSION_STORAGE_KEY_POSTFIX: &[u8] = b":__STORAGE_VERSION__:"; + let mut key_bytes: Vec = ::alloc::vec::Vec::new(); + key_bytes + .extend(&sp_core_hashing::twox_128(pallet_name.as_ref().as_bytes())); + key_bytes + .extend( + &sp_core_hashing::twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX), + ); + let storage_version_bytes = self + .fetch_raw(key_bytes) + .await? + .ok_or_else(|| { + { + let res = ::alloc::fmt::format( + format_args!( + "Unexpected: entry for storage version in pallet \"{0}\" not found", + pallet_name.as_ref() + ), + ); + res + } + })?; + u16::decode(&mut &storage_version_bytes[..]).map_err(Into::into) + } + /// Fetch the runtime WASM code. + pub async fn runtime_wasm_code(&self) -> Result, Error> { + const CODE: &str = ":code"; + self.fetch_raw(CODE.as_bytes()) + .await? + .ok_or_else(|| { + { + let res = ::alloc::fmt::format( + format_args!( + "Unexpected: entry for well known key \"{0}\" not found", + CODE + ), + ); + res + } + .into() + }) + } + } + pub(crate) fn storage_hasher_type_id_pairs( + entry: &StorageEntryType, + metadata: &Metadata, + ) -> Result, Error> { + match entry { + StorageEntryType::Plain(_) => Ok(::alloc::vec::Vec::new()), + StorageEntryType::Map { hashers, key_ty, .. } => { + let ty = metadata + .types() + .resolve(*key_ty) + .ok_or(MetadataError::TypeNotFound(*key_ty))?; + match &ty.type_def { + TypeDef::Tuple(tuple) => { + if hashers.len() < tuple.fields.len() { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: tuple.fields.len(), + } + .into(), + ); + } + let pairs: Vec<(StorageHasher, u32)> = tuple + .fields + .iter() + .zip(hashers.iter()) + .map(|(e, h)| (*h, e.id)) + .collect(); + Ok(pairs) + } + _other => { + if hashers.is_empty() { + return Err( + StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into(), + ); + } + Ok( + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([(hashers[0], *key_ty)]), + ), + ) + } + } + } + } + } + /// A pair of keys and values together with all the bytes that make up the storage address. + /// `keys` is `None` if non-concat hashers are used. In this case the keys could not be extracted back from the key_bytes. + pub struct StorageKeyValuePair { + /// The bytes that make up the address of the storage entry. + pub key_bytes: Vec, + /// The keys that can be used to construct the address of this storage entry. + pub keys: T::Keys, + /// The value of the storage entry. + pub value: T::Target, + } + #[automatically_derived] + impl ::core::clone::Clone + for StorageKeyValuePair + where + T::Keys: ::core::clone::Clone, + T::Target: ::core::clone::Clone, + { + #[inline] + fn clone(&self) -> StorageKeyValuePair { + StorageKeyValuePair { + key_bytes: ::core::clone::Clone::clone(&self.key_bytes), + keys: ::core::clone::Clone::clone(&self.keys), + value: ::core::clone::Clone::clone(&self.value), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug + for StorageKeyValuePair + where + T::Keys: ::core::fmt::Debug, + T::Target: ::core::fmt::Debug, + { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field3_finish( + f, + "StorageKeyValuePair", + "key_bytes", + &self.key_bytes, + "keys", + &self.keys, + "value", + &&self.value, + ) + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for StorageKeyValuePair + where + T::Keys: ::core::cmp::Eq, + T::Target: ::core::cmp::Eq, + { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for StorageKeyValuePair {} + #[automatically_derived] + impl ::core::cmp::PartialEq + for StorageKeyValuePair + where + T::Keys: ::core::cmp::PartialEq, + T::Target: ::core::cmp::PartialEq, + { + #[inline] + fn eq(&self, other: &StorageKeyValuePair) -> bool { + self.key_bytes == other.key_bytes && self.keys == other.keys + && self.value == other.value + } + } + #[automatically_derived] + impl ::core::cmp::Ord + for StorageKeyValuePair + where + T::Keys: ::core::cmp::Ord, + T::Target: ::core::cmp::Ord, + { + #[inline] + fn cmp(&self, other: &StorageKeyValuePair) -> ::core::cmp::Ordering { + match ::core::cmp::Ord::cmp(&self.key_bytes, &other.key_bytes) { + ::core::cmp::Ordering::Equal => { + match ::core::cmp::Ord::cmp(&self.keys, &other.keys) { + ::core::cmp::Ordering::Equal => { + ::core::cmp::Ord::cmp(&self.value, &other.value) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd + for StorageKeyValuePair + where + T::Keys: ::core::cmp::PartialOrd, + T::Target: ::core::cmp::PartialOrd, + { + #[inline] + fn partial_cmp( + &self, + other: &StorageKeyValuePair, + ) -> ::core::option::Option<::core::cmp::Ordering> { + match ::core::cmp::PartialOrd::partial_cmp( + &self.key_bytes, + &other.key_bytes, + ) { + ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { + match ::core::cmp::PartialOrd::partial_cmp( + &self.keys, + &other.keys, + ) { + ::core::option::Option::Some( + ::core::cmp::Ordering::Equal, + ) => { + ::core::cmp::PartialOrd::partial_cmp( + &self.value, + &other.value, + ) + } + cmp => cmp, + } + } + cmp => cmp, + } + } + } + /// Validate a storage address against the metadata. + pub(crate) fn validate_storage_address( + address: &Address, + pallet: PalletMetadata<'_>, + ) -> Result<(), Error> { + if let Some(hash) = address.validation_hash() { + validate_storage(pallet, address.entry_name(), hash)?; + } + Ok(()) + } + /// Return details about the given storage entry. + fn lookup_entry_details<'a>( + pallet_name: &str, + entry_name: &str, + metadata: &'a Metadata, + ) -> Result<(PalletMetadata<'a>, &'a StorageEntryMetadata), Error> { + let pallet_metadata = metadata.pallet_by_name_err(pallet_name)?; + let storage_metadata = pallet_metadata + .storage() + .ok_or_else(|| MetadataError::StorageNotFoundInPallet( + pallet_name.to_owned(), + ))?; + let storage_entry = storage_metadata + .entry_by_name(entry_name) + .ok_or_else(|| MetadataError::StorageEntryNotFound( + entry_name.to_owned(), + ))?; + Ok((pallet_metadata, storage_entry)) + } + /// Validate a storage entry against the metadata. + fn validate_storage( + pallet: PalletMetadata<'_>, + storage_name: &str, + hash: [u8; 32], + ) -> Result<(), Error> { + let Some(expected_hash) = pallet.storage_hash(storage_name) else { + return Err(MetadataError::IncompatibleCodegen.into()); + }; + if expected_hash != hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + Ok(()) + } + /// Fetch the return type out of a [`StorageEntryType`]. + fn return_type_from_storage_entry_type(entry: &StorageEntryType) -> u32 { + match entry { + StorageEntryType::Plain(ty) => *ty, + StorageEntryType::Map { value_ty, .. } => *value_ty, + } + } + /// Given some bytes, a pallet and storage name, decode the response. + fn decode_storage_with_metadata( + bytes: &mut &[u8], + metadata: &Metadata, + storage_metadata: &StorageEntryMetadata, + ) -> Result { + let ty = storage_metadata.entry_type(); + let return_ty = return_type_from_storage_entry_type(ty); + let val = T::decode_with_metadata(bytes, return_ty, metadata)?; + Ok(val) + } + } + pub mod utils { + //! these utility methods complement the [`StorageAddress`] trait, but + //! aren't things that should ever be overridden, and so don't exist on + //! the trait itself. + use subxt_metadata::StorageHasher; + use super::StorageAddress; + use crate::{ + error::{Error, StorageAddressError}, + metadata::Metadata, + }; + /// Return the root of a given [`StorageAddress`]: hash the pallet name and entry name + /// and append those bytes to the output. + pub(crate) fn write_storage_address_root_bytes( + addr: &Address, + out: &mut Vec, + ) { + out.extend(sp_core_hashing::twox_128(addr.pallet_name().as_bytes())); + out.extend(sp_core_hashing::twox_128(addr.entry_name().as_bytes())); + } + /// Outputs the [`storage_address_root_bytes`] as well as any additional bytes that represent + /// a lookup in a storage map at that location. + pub(crate) fn storage_address_bytes( + addr: &Address, + metadata: &Metadata, + ) -> Result, Error> { + let mut bytes = Vec::new(); + write_storage_address_root_bytes(addr, &mut bytes); + addr.append_entry_bytes(metadata, &mut bytes)?; + Ok(bytes) + } + /// Outputs a vector containing the bytes written by [`write_storage_address_root_bytes`]. + pub(crate) fn storage_address_root_bytes( + addr: &Address, + ) -> Vec { + let mut bytes = Vec::new(); + write_storage_address_root_bytes(addr, &mut bytes); + bytes + } + /// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. + pub(crate) fn strip_storage_addess_root_bytes( + address_bytes: &mut &[u8], + ) -> Result<(), StorageAddressError> { + if address_bytes.len() >= 16 { + *address_bytes = &address_bytes[16..]; + Ok(()) + } else { + Err(StorageAddressError::UnexpectedAddressBytes) + } + } + /// Strips the first few bytes off a hash to possibly skip to the plan key value, + /// if [`hash_contains_unhashed_value()`] for this StorageHasher. + /// + /// Returns `Err(..)` if there are not enough bytes. + /// Returns `Ok(())` otherwise + pub fn strip_storage_hash_bytes( + hash: &mut &[u8], + hasher: &StorageHasher, + ) -> Result<(), StorageAddressError> { + let bytes_to_strip = match hasher { + StorageHasher::Blake2_128Concat => 16, + StorageHasher::Twox64Concat => 8, + StorageHasher::Blake2_128 => 16, + StorageHasher::Blake2_256 => 32, + StorageHasher::Twox128 => 16, + StorageHasher::Twox256 => 32, + StorageHasher::Identity => 0, + }; + if hash.len() < bytes_to_strip { + return Err(StorageAddressError::UnexpectedAddressBytes); + } + *hash = &hash[bytes_to_strip..]; + Ok(()) + } + /// This value is contained within the hash for concat-stle hashers + /// ([`StorageHasher::Identity`] or [`StorageHasher::Identity`]) and the + /// identity hash function ([`StorageHasher::Identity`]). + pub fn hash_contains_unhashed_value(hasher: &StorageHasher) -> bool { + match hasher { + StorageHasher::Blake2_128Concat + | StorageHasher::Twox64Concat + | StorageHasher::Identity => true, + _ => false, + } + } + } + pub use storage_client::StorageClient; + pub use storage_type::{Storage, StorageKeyValuePair}; + /// Types representing an address which describes where a storage + /// entry lives and how to properly decode it. + pub mod address { + pub use super::storage_address::{ + dynamic, Address, DynamicAddress, StaticStorageKey, StorageAddress, Yes, + }; + } + pub use storage_key::StorageKey; + pub use storage_address::{dynamic, Address, DynamicAddress, StorageAddress}; +} +pub mod tx { + //! Create and submit extrinsics. + //! + //! An extrinsic is submitted with an "signed extra" and "additional" parameters, which can be + //! different for each chain. The trait [`crate::config::ExtrinsicParams`] determines exactly which + //! additional and signed extra parameters are used when constructing an extrinsic, and is a part + //! of the chain configuration (see [`crate::config::Config`]). + use crate::macros::cfg_substrate_compat; + mod signer { + //! A library to **sub**mit e**xt**rinsics to a + //! [substrate](https://github.com/paritytech/substrate) node via RPC. + use crate::macros::cfg_substrate_compat; + use crate::Config; + /// Signing transactions requires a [`Signer`]. This is responsible for + /// providing the "from" account that the transaction is being signed by, + /// as well as actually signing a SCALE encoded payload. + pub trait Signer { + /// Return the "from" account ID. + fn account_id(&self) -> T::AccountId; + /// Return the "from" address. + fn address(&self) -> T::Address; + /// Takes a signer payload for an extrinsic, and returns a signature based on it. + /// + /// Some signers may fail, for instance because the hardware on which the keys are located has + /// refused the operation. + fn sign(&self, signer_payload: &[u8]) -> T::Signature; + } + } + mod tx_client { + use std::borrow::Cow; + use crate::{ + backend::{BackendExt, BlockRef, TransactionStatus}, + client::{OfflineClientT, OnlineClientT}, + config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, Hasher}, + error::{Error, MetadataError}, + tx::{Signer as SignerT, TxPayload, TxProgress}, + utils::{Encoded, PhantomDataSendSync}, + }; + use codec::{Compact, Decode, Encode}; + use derivative::Derivative; + use sp_core_hashing::blake2_256; + /// A client for working with transactions. + #[derivative(Clone(bound = "Client: Clone"))] + pub struct TxClient { + client: Client, + _marker: PhantomDataSendSync, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for TxClient + where + Client: Clone, + { + fn clone(&self) -> Self { + match *self { + TxClient { client: ref __arg_0, _marker: ref __arg_1 } => { + TxClient { + client: (*__arg_0).clone(), + _marker: (*__arg_1).clone(), + } + } + } + } + } + impl TxClient { + /// Create a new [`TxClient`] + pub fn new(client: Client) -> Self { + Self { + client, + _marker: PhantomDataSendSync::new(), + } + } + } + impl> TxClient { + /// Run the validation logic against some extrinsic you'd like to submit. Returns `Ok(())` + /// if the call is valid (or if it's not possible to check since the call has no validation hash). + /// Return an error if the call was not valid or something went wrong trying to validate it (ie + /// the pallet or call in question do not exist at all). + pub fn validate(&self, call: &Call) -> Result<(), Error> + where + Call: TxPayload, + { + if let Some(details) = call.validation_details() { + let expected_hash = self + .client + .metadata() + .pallet_by_name_err(details.pallet_name)? + .call_hash(details.call_name) + .ok_or_else(|| MetadataError::CallNameNotFound( + details.call_name.to_owned(), + ))?; + if details.hash != expected_hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + } + Ok(()) + } + /// Return the SCALE encoded bytes representing the call data of the transaction. + pub fn call_data(&self, call: &Call) -> Result, Error> + where + Call: TxPayload, + { + let metadata = self.client.metadata(); + let mut bytes = Vec::new(); + call.encode_call_data_to(&metadata, &mut bytes)?; + Ok(bytes) + } + /// Creates an unsigned extrinsic without submitting it. + pub fn create_unsigned( + &self, + call: &Call, + ) -> Result, Error> + where + Call: TxPayload, + { + self.validate(call)?; + let extrinsic = { + let mut encoded_inner = Vec::new(); + 4u8.encode_to(&mut encoded_inner); + call.encode_call_data_to( + &self.client.metadata(), + &mut encoded_inner, + )?; + let len = Compact( + u32::try_from(encoded_inner.len()) + .expect("extrinsic size expected to be <4GB"), + ); + let mut encoded = Vec::new(); + len.encode_to(&mut encoded); + encoded.extend(encoded_inner); + encoded + }; + Ok(SubmittableExtrinsic::from_bytes(self.client.clone(), extrinsic)) + } + /// Create a partial extrinsic. + pub fn create_partial_signed_with_nonce( + &self, + call: &Call, + account_nonce: u64, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + { + self.validate(call)?; + let call_data = self.call_data(call)?; + let additional_and_extra_params = >::new(account_nonce, self.client.clone(), other_params)?; + Ok(PartialExtrinsic { + client: self.client.clone(), + call_data, + additional_and_extra_params, + }) + } + /// Creates a signed extrinsic without submitting it. + pub fn create_signed_with_nonce( + &self, + call: &Call, + signer: &Signer, + account_nonce: u64, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + Signer: SignerT, + { + self.validate(call)?; + let partial_signed = self + .create_partial_signed_with_nonce( + call, + account_nonce, + other_params, + )?; + Ok(partial_signed.sign(signer)) + } + } + impl TxClient + where + T: Config, + C: OnlineClientT, + { + /// Get the account nonce for a given account ID. + pub async fn account_nonce( + &self, + account_id: &T::AccountId, + ) -> Result { + let block_ref = self + .client + .backend() + .latest_finalized_block_ref() + .await?; + crate::blocks::get_account_nonce( + &self.client, + account_id, + block_ref.hash(), + ) + .await + } + /// Creates a partial signed extrinsic, without submitting it. + pub async fn create_partial_signed( + &self, + call: &Call, + account_id: &T::AccountId, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + { + let account_nonce = self.account_nonce(account_id).await?; + self.create_partial_signed_with_nonce(call, account_nonce, other_params) + } + /// Creates a signed extrinsic, without submitting it. + pub async fn create_signed( + &self, + call: &Call, + signer: &Signer, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + Signer: SignerT, + { + let account_nonce = self.account_nonce(&signer.account_id()).await?; + self.create_signed_with_nonce(call, signer, account_nonce, other_params) + } + /// Creates and signs an extrinsic and submits it to the chain. Passes default parameters + /// to construct the "signed extra" and "additional" payloads needed by the extrinsic. + /// + /// Returns a [`TxProgress`], which can be used to track the status of the transaction + /// and obtain details about it, once it has made it into a block. + pub async fn sign_and_submit_then_watch_default( + &self, + call: &Call, + signer: &Signer, + ) -> Result, Error> + where + Call: TxPayload, + Signer: SignerT, + >::OtherParams: Default, + { + self.sign_and_submit_then_watch(call, signer, Default::default()).await + } + /// Creates and signs an extrinsic and submits it to the chain. + /// + /// Returns a [`TxProgress`], which can be used to track the status of the transaction + /// and obtain details about it, once it has made it into a block. + pub async fn sign_and_submit_then_watch( + &self, + call: &Call, + signer: &Signer, + other_params: >::OtherParams, + ) -> Result, Error> + where + Call: TxPayload, + Signer: SignerT, + { + self.create_signed(call, signer, other_params) + .await? + .submit_and_watch() + .await + } + /// Creates and signs an extrinsic and submits to the chain for block inclusion. Passes + /// default parameters to construct the "signed extra" and "additional" payloads needed + /// by the extrinsic. + /// + /// Returns `Ok` with the extrinsic hash if it is valid extrinsic. + /// + /// # Note + /// + /// Success does not mean the extrinsic has been included in the block, just that it is valid + /// and has been included in the transaction pool. + pub async fn sign_and_submit_default( + &self, + call: &Call, + signer: &Signer, + ) -> Result + where + Call: TxPayload, + Signer: SignerT, + >::OtherParams: Default, + { + self.sign_and_submit(call, signer, Default::default()).await + } + /// Creates and signs an extrinsic and submits to the chain for block inclusion. + /// + /// Returns `Ok` with the extrinsic hash if it is valid extrinsic. + /// + /// # Note + /// + /// Success does not mean the extrinsic has been included in the block, just that it is valid + /// and has been included in the transaction pool. + pub async fn sign_and_submit( + &self, + call: &Call, + signer: &Signer, + other_params: >::OtherParams, + ) -> Result + where + Call: TxPayload, + Signer: SignerT, + { + self.create_signed(call, signer, other_params).await?.submit().await + } + } + /// This payload contains the information needed to produce an extrinsic. + pub struct PartialExtrinsic { + client: C, + call_data: Vec, + additional_and_extra_params: T::ExtrinsicParams, + } + impl PartialExtrinsic + where + T: Config, + C: OfflineClientT, + { + fn with_signer_payload(&self, f: F) -> R + where + F: for<'a> FnOnce(Cow<'a, [u8]>) -> R, + { + let mut bytes = self.call_data.clone(); + self.additional_and_extra_params.encode_extra_to(&mut bytes); + self.additional_and_extra_params.encode_additional_to(&mut bytes); + if bytes.len() > 256 { + f(Cow::Borrowed(blake2_256(&bytes).as_ref())) + } else { + f(Cow::Owned(bytes)) + } + } + /// Return the signer payload for this extrinsic. These are the bytes that must + /// be signed in order to produce a valid signature for the extrinsic. + pub fn signer_payload(&self) -> Vec { + self.with_signer_payload(|bytes| bytes.to_vec()) + } + /// Return the bytes representing the call data for this partially constructed + /// extrinsic. + pub fn call_data(&self) -> &[u8] { + &self.call_data + } + /// Convert this [`PartialExtrinsic`] into a [`SubmittableExtrinsic`], ready to submit. + /// The provided `signer` is responsible for providing the "from" address for the transaction, + /// as well as providing a signature to attach to it. + pub fn sign(&self, signer: &Signer) -> SubmittableExtrinsic + where + Signer: SignerT, + { + let signature = self.with_signer_payload(|bytes| signer.sign(&bytes)); + self.sign_with_address_and_signature(&signer.address(), &signature) + } + /// Convert this [`PartialExtrinsic`] into a [`SubmittableExtrinsic`], ready to submit. + /// An address, and something representing a signature that can be SCALE encoded, are both + /// needed in order to construct it. If you have a `Signer` to hand, you can use + /// [`PartialExtrinsic::sign()`] instead. + pub fn sign_with_address_and_signature( + &self, + address: &T::Address, + signature: &T::Signature, + ) -> SubmittableExtrinsic { + let extrinsic = { + let mut encoded_inner = Vec::new(); + (0b10000000 + 4u8).encode_to(&mut encoded_inner); + address.encode_to(&mut encoded_inner); + signature.encode_to(&mut encoded_inner); + self.additional_and_extra_params.encode_extra_to(&mut encoded_inner); + encoded_inner.extend(&self.call_data); + let len = Compact( + u32::try_from(encoded_inner.len()) + .expect("extrinsic size expected to be <4GB"), + ); + let mut encoded = Vec::new(); + len.encode_to(&mut encoded); + encoded.extend(encoded_inner); + encoded + }; + SubmittableExtrinsic::from_bytes(self.client.clone(), extrinsic) + } + } + /// This represents an extrinsic that has been signed and is ready to submit. + pub struct SubmittableExtrinsic { + client: C, + encoded: Encoded, + marker: std::marker::PhantomData, + } + impl SubmittableExtrinsic + where + T: Config, + C: OfflineClientT, + { + /// Create a [`SubmittableExtrinsic`] from some already-signed and prepared + /// extrinsic bytes, and some client (anything implementing [`OfflineClientT`] + /// or [`OnlineClientT`]). + /// + /// Prefer to use [`TxClient`] to create and sign extrinsics. This is simply + /// exposed in case you want to skip this process and submit something you've + /// already created. + pub fn from_bytes(client: C, tx_bytes: Vec) -> Self { + Self { + client, + encoded: Encoded(tx_bytes), + marker: std::marker::PhantomData, + } + } + /// Calculate and return the hash of the extrinsic, based on the configured hasher. + pub fn hash(&self) -> T::Hash { + T::Hasher::hash_of(&self.encoded) + } + /// Returns the SCALE encoded extrinsic bytes. + pub fn encoded(&self) -> &[u8] { + &self.encoded.0 + } + /// Consumes [`SubmittableExtrinsic`] and returns the SCALE encoded + /// extrinsic bytes. + pub fn into_encoded(self) -> Vec { + self.encoded.0 + } + } + impl SubmittableExtrinsic + where + T: Config, + C: OnlineClientT, + { + /// Submits the extrinsic to the chain. + /// + /// Returns a [`TxProgress`], which can be used to track the status of the transaction + /// and obtain details about it, once it has made it into a block. + pub async fn submit_and_watch(&self) -> Result, Error> { + let ext_hash = self.hash(); + let sub = self + .client + .backend() + .submit_transaction(&self.encoded.0) + .await?; + Ok(TxProgress::new(sub, self.client.clone(), ext_hash)) + } + /// Submits the extrinsic to the chain for block inclusion. + /// + /// It's usually better to call `submit_and_watch` to get an idea of the progress of the + /// submission and whether it's eventually successful or not. This call does not guarantee + /// success, and is just sending the transaction to the chain. + pub async fn submit(&self) -> Result { + let ext_hash = self.hash(); + let mut sub = self + .client + .backend() + .submit_transaction(&self.encoded.0) + .await?; + match sub.next().await { + Some(Ok(status)) => { + match status { + TransactionStatus::Validated + | TransactionStatus::Broadcasted { .. } + | TransactionStatus::InBestBlock { .. } + | TransactionStatus::NoLongerInBestBlock + | TransactionStatus::InFinalizedBlock { .. } => Ok(ext_hash), + TransactionStatus::Error { message } => { + Err( + Error::Other({ + let res = ::alloc::fmt::format( + format_args!("Transaction error: {0}", message), + ); + res + }), + ) + } + TransactionStatus::Invalid { message } => { + Err( + Error::Other({ + let res = ::alloc::fmt::format( + format_args!("Transaction invalid: {0}", message), + ); + res + }), + ) + } + TransactionStatus::Dropped { message } => { + Err( + Error::Other({ + let res = ::alloc::fmt::format( + format_args!("Transaction dropped: {0}", message), + ); + res + }), + ) + } + } + } + Some(Err(e)) => Err(e), + None => { + Err( + Error::Other( + "Transaction broadcast was unsuccessful; stream terminated early" + .into(), + ), + ) + } + } + } + /// Validate a transaction by submitting it to the relevant Runtime API. A transaction that is + /// valid can be added to a block, but may still end up in an error state. + /// + /// Returns `Ok` with a [`ValidationResult`], which is the result of attempting to dry run the extrinsic. + pub async fn validate(&self) -> Result { + let latest_block_ref = self + .client + .backend() + .latest_finalized_block_ref() + .await?; + self.validate_at(latest_block_ref).await + } + /// Validate a transaction by submitting it to the relevant Runtime API. A transaction that is + /// valid can be added to a block, but may still end up in an error state. + /// + /// Returns `Ok` with a [`ValidationResult`], which is the result of attempting to dry run the extrinsic. + pub async fn validate_at( + &self, + at: impl Into>, + ) -> Result { + let block_hash = at.into().hash(); + let mut params = Vec::with_capacity(8 + self.encoded.0.len() + 8); + 2u8.encode_to(&mut params); + params.extend(self.encoded().iter()); + block_hash.encode_to(&mut params); + let res: Vec = self + .client + .backend() + .call( + "TaggedTransactionQueue_validate_transaction", + Some(¶ms), + block_hash, + ) + .await?; + ValidationResult::try_from_bytes(res) + } + /// This returns an estimate for what the extrinsic is expected to cost to execute, less any tips. + /// The actual amount paid can vary from block to block based on node traffic and other factors. + pub async fn partial_fee_estimate(&self) -> Result { + let mut params = self.encoded().to_vec(); + (self.encoded().len() as u32).encode_to(&mut params); + let latest_block_ref = self + .client + .backend() + .latest_finalized_block_ref() + .await?; + let (_, _, _, partial_fee) = self + .client + .backend() + .call_decoding::< + (Compact, Compact, u8, u128), + >( + "TransactionPaymentApi_query_info", + Some(¶ms), + latest_block_ref.hash(), + ) + .await?; + Ok(partial_fee) + } + } + impl ValidationResult { + #[allow(clippy::get_first)] + fn try_from_bytes(bytes: Vec) -> Result { + if bytes.get(0) == Some(&0) { + let res = TransactionValid::decode(&mut &bytes[1..])?; + Ok(ValidationResult::Valid(res)) + } else if bytes.get(0) == Some(&1) && bytes.get(1) == Some(&0) { + let res = TransactionInvalid::decode(&mut &bytes[2..])?; + Ok(ValidationResult::Invalid(res)) + } else if bytes.get(0) == Some(&1) && bytes.get(1) == Some(&1) { + let res = TransactionUnknown::decode(&mut &bytes[2..])?; + Ok(ValidationResult::Unknown(res)) + } else { + Err(crate::Error::Unknown(bytes)) + } + } + } + /// The result of performing [`SubmittableExtrinsic::validate()`]. + pub enum ValidationResult { + /// The transaction is valid + Valid(TransactionValid), + /// The transaction is invalid + Invalid(TransactionInvalid), + /// Unable to validate the transaction + Unknown(TransactionUnknown), + } + #[automatically_derived] + impl ::core::clone::Clone for ValidationResult { + #[inline] + fn clone(&self) -> ValidationResult { + match self { + ValidationResult::Valid(__self_0) => { + ValidationResult::Valid(::core::clone::Clone::clone(__self_0)) + } + ValidationResult::Invalid(__self_0) => { + ValidationResult::Invalid(::core::clone::Clone::clone(__self_0)) + } + ValidationResult::Unknown(__self_0) => { + ValidationResult::Unknown(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for ValidationResult { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + ValidationResult::Valid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Valid", + &__self_0, + ) + } + ValidationResult::Invalid(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Invalid", + &__self_0, + ) + } + ValidationResult::Unknown(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Unknown", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for ValidationResult {} + #[automatically_derived] + impl ::core::cmp::PartialEq for ValidationResult { + #[inline] + fn eq(&self, other: &ValidationResult) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + ValidationResult::Valid(__self_0), + ValidationResult::Valid(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + ValidationResult::Invalid(__self_0), + ValidationResult::Invalid(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + ValidationResult::Unknown(__self_0), + ValidationResult::Unknown(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + impl ValidationResult { + /// Is the transaction valid. + pub fn is_valid(&self) -> bool { + match self { + ValidationResult::Valid(_) => true, + _ => false, + } + } + } + /// Transaction is valid; here is some more information about it. + pub struct TransactionValid { + /// Priority of the transaction. + /// + /// Priority determines the ordering of two transactions that have all + /// their dependencies (required tags) satisfied. + pub priority: u64, + /// Transaction dependencies + /// + /// A non-empty list signifies that some other transactions which provide + /// given tags are required to be included before that one. + pub requires: Vec>, + /// Provided tags + /// + /// A list of tags this transaction provides. Successfully importing the transaction + /// will enable other transactions that depend on (require) those tags to be included as well. + /// Provided and required tags allow Substrate to build a dependency graph of transactions + /// and import them in the right (linear) order. + pub provides: Vec>, + /// Transaction longevity + /// + /// Longevity describes minimum number of blocks the validity is correct. + /// After this period transaction should be removed from the pool or revalidated. + pub longevity: u64, + /// A flag indicating if the transaction should be propagated to other peers. + /// + /// By setting `false` here the transaction will still be considered for + /// including in blocks that are authored on the current node, but will + /// never be sent to other peers. + pub propagate: bool, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for TransactionValid { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(TransactionValid { + priority: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::priority`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + requires: { + let __codec_res_edqy = , + > as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::requires`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + provides: { + let __codec_res_edqy = , + > as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::provides`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + longevity: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::longevity`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + propagate: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionValid::propagate`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for TransactionValid { + #[inline] + fn clone(&self) -> TransactionValid { + TransactionValid { + priority: ::core::clone::Clone::clone(&self.priority), + requires: ::core::clone::Clone::clone(&self.requires), + provides: ::core::clone::Clone::clone(&self.provides), + longevity: ::core::clone::Clone::clone(&self.longevity), + propagate: ::core::clone::Clone::clone(&self.propagate), + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionValid { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field5_finish( + f, + "TransactionValid", + "priority", + &self.priority, + "requires", + &self.requires, + "provides", + &self.provides, + "longevity", + &self.longevity, + "propagate", + &&self.propagate, + ) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionValid {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionValid { + #[inline] + fn eq(&self, other: &TransactionValid) -> bool { + self.priority == other.priority && self.requires == other.requires + && self.provides == other.provides + && self.longevity == other.longevity + && self.propagate == other.propagate + } + } + /// The runtime was unable to validate the transaction. + pub enum TransactionUnknown { + /// Could not lookup some information that is required to validate the transaction. + CannotLookup, + /// No validator found for the given unsigned transaction. + NoUnsignedValidator, + /// Any other custom unknown validity that is not covered by this enum. + Custom(u8), + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for TransactionUnknown { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `TransactionUnknown`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionUnknown::CannotLookup) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionUnknown::NoUnsignedValidator, + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionUnknown::Custom({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionUnknown::Custom.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `TransactionUnknown`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for TransactionUnknown { + #[inline] + fn clone(&self) -> TransactionUnknown { + match self { + TransactionUnknown::CannotLookup => TransactionUnknown::CannotLookup, + TransactionUnknown::NoUnsignedValidator => { + TransactionUnknown::NoUnsignedValidator + } + TransactionUnknown::Custom(__self_0) => { + TransactionUnknown::Custom(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionUnknown { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionUnknown::CannotLookup => { + ::core::fmt::Formatter::write_str(f, "CannotLookup") + } + TransactionUnknown::NoUnsignedValidator => { + ::core::fmt::Formatter::write_str(f, "NoUnsignedValidator") + } + TransactionUnknown::Custom(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Custom", + &__self_0, + ) + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionUnknown {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionUnknown { + #[inline] + fn eq(&self, other: &TransactionUnknown) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionUnknown::Custom(__self_0), + TransactionUnknown::Custom(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + /// The transaction is invalid. + pub enum TransactionInvalid { + /// The call of the transaction is not expected. + Call, + /// General error to do with the inability to pay some fees (e.g. account balance too low). + Payment, + /// General error to do with the transaction not yet being valid (e.g. nonce too high). + Future, + /// General error to do with the transaction being outdated (e.g. nonce too low). + Stale, + /// General error to do with the transaction's proofs (e.g. signature). + /// + /// # Possible causes + /// + /// When using a signed extension that provides additional data for signing, it is required + /// that the signing and the verifying side use the same additional data. Additional + /// data will only be used to generate the signature, but will not be part of the transaction + /// itself. As the verifying side does not know which additional data was used while signing + /// it will only be able to assume a bad signature and cannot express a more meaningful error. + BadProof, + /// The transaction birth block is ancient. + /// + /// # Possible causes + /// + /// For `FRAME`-based runtimes this would be caused by `current block number + /// - Era::birth block number > BlockHashCount`. (e.g. in Polkadot `BlockHashCount` = 2400, so + /// a + /// transaction with birth block number 1337 would be valid up until block number 1337 + 2400, + /// after which point the transaction would be considered to have an ancient birth block.) + AncientBirthBlock, + /// The transaction would exhaust the resources of current block. + /// + /// The transaction might be valid, but there are not enough resources + /// left in the current block. + ExhaustsResources, + /// Any other custom invalid validity that is not covered by this enum. + Custom(u8), + /// An extrinsic with a Mandatory dispatch resulted in Error. This is indicative of either a + /// malicious validator or a buggy `provide_inherent`. In any case, it can result in + /// dangerously overweight blocks and therefore if found, invalidates the block. + BadMandatory, + /// An extrinsic with a mandatory dispatch tried to be validated. + /// This is invalid; only inherent extrinsics are allowed to have mandatory dispatches. + MandatoryValidation, + /// The sending address is disabled or known to be invalid. + BadSigner, + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for TransactionInvalid { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `TransactionInvalid`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::Call) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::Payment) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::Future) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 3usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::Stale) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 4usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::BadProof) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 5usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionInvalid::AncientBirthBlock, + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 6usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionInvalid::ExhaustsResources, + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 7usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionInvalid::Custom({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `TransactionInvalid::Custom.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 8usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::BadMandatory) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 9usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + TransactionInvalid::MandatoryValidation, + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 10usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(TransactionInvalid::BadSigner) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `TransactionInvalid`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + #[automatically_derived] + impl ::core::clone::Clone for TransactionInvalid { + #[inline] + fn clone(&self) -> TransactionInvalid { + match self { + TransactionInvalid::Call => TransactionInvalid::Call, + TransactionInvalid::Payment => TransactionInvalid::Payment, + TransactionInvalid::Future => TransactionInvalid::Future, + TransactionInvalid::Stale => TransactionInvalid::Stale, + TransactionInvalid::BadProof => TransactionInvalid::BadProof, + TransactionInvalid::AncientBirthBlock => { + TransactionInvalid::AncientBirthBlock + } + TransactionInvalid::ExhaustsResources => { + TransactionInvalid::ExhaustsResources + } + TransactionInvalid::Custom(__self_0) => { + TransactionInvalid::Custom(::core::clone::Clone::clone(__self_0)) + } + TransactionInvalid::BadMandatory => TransactionInvalid::BadMandatory, + TransactionInvalid::MandatoryValidation => { + TransactionInvalid::MandatoryValidation + } + TransactionInvalid::BadSigner => TransactionInvalid::BadSigner, + } + } + } + #[automatically_derived] + impl ::core::fmt::Debug for TransactionInvalid { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + TransactionInvalid::Call => { + ::core::fmt::Formatter::write_str(f, "Call") + } + TransactionInvalid::Payment => { + ::core::fmt::Formatter::write_str(f, "Payment") + } + TransactionInvalid::Future => { + ::core::fmt::Formatter::write_str(f, "Future") + } + TransactionInvalid::Stale => { + ::core::fmt::Formatter::write_str(f, "Stale") + } + TransactionInvalid::BadProof => { + ::core::fmt::Formatter::write_str(f, "BadProof") + } + TransactionInvalid::AncientBirthBlock => { + ::core::fmt::Formatter::write_str(f, "AncientBirthBlock") + } + TransactionInvalid::ExhaustsResources => { + ::core::fmt::Formatter::write_str(f, "ExhaustsResources") + } + TransactionInvalid::Custom(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Custom", + &__self_0, + ) + } + TransactionInvalid::BadMandatory => { + ::core::fmt::Formatter::write_str(f, "BadMandatory") + } + TransactionInvalid::MandatoryValidation => { + ::core::fmt::Formatter::write_str(f, "MandatoryValidation") + } + TransactionInvalid::BadSigner => { + ::core::fmt::Formatter::write_str(f, "BadSigner") + } + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for TransactionInvalid {} + #[automatically_derived] + impl ::core::cmp::PartialEq for TransactionInvalid { + #[inline] + fn eq(&self, other: &TransactionInvalid) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + TransactionInvalid::Custom(__self_0), + TransactionInvalid::Custom(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => true, + } + } + } + } + mod tx_payload { + //! This module contains the trait and types used to represent + //! transactions that can be submitted. + use crate::{ + dynamic::Value, error::{Error, MetadataError}, + metadata::Metadata, + }; + use codec::Encode; + use derivative::Derivative; + use scale_encode::EncodeAsFields; + use scale_value::{Composite, ValueDef, Variant}; + use std::{borrow::Cow, sync::Arc}; + /// This represents a transaction payload that can be submitted + /// to a node. + pub trait TxPayload { + /// Encode call data to the provided output. + fn encode_call_data_to( + &self, + metadata: &Metadata, + out: &mut Vec, + ) -> Result<(), Error>; + /// Encode call data and return the output. This is a convenience + /// wrapper around [`TxPayload::encode_call_data_to`]. + fn encode_call_data(&self, metadata: &Metadata) -> Result, Error> { + let mut v = Vec::new(); + self.encode_call_data_to(metadata, &mut v)?; + Ok(v) + } + /// Returns the details needed to validate the call, which + /// include a statically generated hash, the pallet name, + /// and the call name. + fn validation_details(&self) -> Option> { + None + } + } + pub struct ValidationDetails<'a> { + /// The pallet name. + pub pallet_name: &'a str, + /// The call name. + pub call_name: &'a str, + /// A hash (this is generated at compile time in our codegen) + /// to compare against the runtime code. + pub hash: [u8; 32], + } + /// A transaction payload containing some generic `CallData`. + #[derivative( + Clone(bound = "CallData: Clone"), + Debug(bound = "CallData: std::fmt::Debug"), + Eq(bound = "CallData: std::cmp::Eq"), + Ord(bound = "CallData: std::cmp::Ord"), + PartialEq(bound = "CallData: std::cmp::PartialEq"), + PartialOrd(bound = "CallData: std::cmp::PartialOrd") + )] + pub struct Payload { + pallet_name: Cow<'static, str>, + call_name: Cow<'static, str>, + call_data: CallData, + validation_hash: Option<[u8; 32]>, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for Payload + where + CallData: Clone, + { + fn clone(&self) -> Self { + match *self { + Payload { + pallet_name: ref __arg_0, + call_name: ref __arg_1, + call_data: ref __arg_2, + validation_hash: ref __arg_3, + } => { + Payload { + pallet_name: (*__arg_0).clone(), + call_name: (*__arg_1).clone(), + call_data: (*__arg_2).clone(), + validation_hash: (*__arg_3).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for Payload + where + CallData: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Payload { + pallet_name: ref __arg_0, + call_name: ref __arg_1, + call_data: ref __arg_2, + validation_hash: ref __arg_3, + } => { + let mut __debug_trait_builder = __f.debug_struct("Payload"); + let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); + let _ = __debug_trait_builder.field("call_name", &&(*__arg_1)); + let _ = __debug_trait_builder.field("call_data", &&(*__arg_2)); + let _ = __debug_trait_builder + .field("validation_hash", &&(*__arg_3)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for Payload + where + CallData: std::cmp::Eq, + {} + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for Payload + where + CallData: std::cmp::PartialEq, + { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + Payload { + pallet_name: ref __self_0, + call_name: ref __self_1, + call_data: ref __self_2, + validation_hash: ref __self_3, + } => { + match *other { + Payload { + pallet_name: ref __other_0, + call_name: ref __other_1, + call_data: ref __other_2, + validation_hash: ref __other_3, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + && &(*__self_2) == &(*__other_2) + && &(*__self_3) == &(*__other_3) + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialOrd for Payload + where + CallData: std::cmp::PartialOrd, + { + fn partial_cmp( + &self, + other: &Self, + ) -> ::std::option::Option<::std::cmp::Ordering> { + match *self { + Payload { + pallet_name: ref __self_0, + call_name: ref __self_1, + call_data: ref __self_2, + validation_hash: ref __self_3, + } => { + match *other { + Payload { + pallet_name: ref __other_0, + call_name: ref __other_1, + call_data: ref __other_2, + validation_hash: ref __other_3, + } => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_0), + &(*__other_0), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_1), + &(*__other_1), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_2), + &(*__other_2), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + match ::std::cmp::PartialOrd::partial_cmp( + &(*__self_3), + &(*__other_3), + ) { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { + ::std::option::Option::Some(::std::cmp::Ordering::Equal) + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::Ord for Payload + where + CallData: std::cmp::Ord, + { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + match *self { + Payload { + pallet_name: ref __self_0, + call_name: ref __self_1, + call_data: ref __self_2, + validation_hash: ref __self_3, + } => { + match *other { + Payload { + pallet_name: ref __other_0, + call_name: ref __other_1, + call_data: ref __other_2, + validation_hash: ref __other_3, + } => { + match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { + ::std::cmp::Ordering::Equal => { + match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { + ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + __derive_ordering_other => __derive_ordering_other, + } + } + } + } + } + } + } + /// A boxed transaction payload. + pub type BoxedPayload = Payload>; + /// The type of a payload typically used for dynamic transaction payloads. + pub type DynamicPayload = Payload>; + impl Payload { + /// Create a new [`Payload`]. + pub fn new( + pallet_name: impl Into, + call_name: impl Into, + call_data: CallData, + ) -> Self { + Payload { + pallet_name: Cow::Owned(pallet_name.into()), + call_name: Cow::Owned(call_name.into()), + call_data, + validation_hash: None, + } + } + /// Create a new [`Payload`] using static strings for the pallet and call name. + /// This is only expected to be used from codegen. + #[doc(hidden)] + pub fn new_static( + pallet_name: &'static str, + call_name: &'static str, + call_data: CallData, + validation_hash: [u8; 32], + ) -> Self { + Payload { + pallet_name: Cow::Borrowed(pallet_name), + call_name: Cow::Borrowed(call_name), + call_data, + validation_hash: Some(validation_hash), + } + } + /// Box the payload. + pub fn boxed(self) -> BoxedPayload + where + CallData: EncodeAsFields + Send + Sync + 'static, + { + BoxedPayload { + pallet_name: self.pallet_name, + call_name: self.call_name, + call_data: Arc::new(self.call_data), + validation_hash: self.validation_hash, + } + } + /// Do not validate this call prior to submitting it. + pub fn unvalidated(self) -> Self { + Self { + validation_hash: None, + ..self + } + } + /// Returns the call data. + pub fn call_data(&self) -> &CallData { + &self.call_data + } + /// Returns the pallet name. + pub fn pallet_name(&self) -> &str { + &self.pallet_name + } + /// Returns the call name. + pub fn call_name(&self) -> &str { + &self.call_name + } + } + impl Payload> { + /// Convert the dynamic `Composite` payload into a [`Value`]. + /// This is useful if you want to use this as an argument for a + /// larger dynamic call that wants to use this as a nested call. + pub fn into_value(self) -> Value<()> { + let call = Value { + context: (), + value: ValueDef::Variant(Variant { + name: self.call_name.into_owned(), + values: self.call_data, + }), + }; + Value::unnamed_variant(self.pallet_name, [call]) + } + } + impl TxPayload for Payload { + fn encode_call_data_to( + &self, + metadata: &Metadata, + out: &mut Vec, + ) -> Result<(), Error> { + let pallet = metadata.pallet_by_name_err(&self.pallet_name)?; + let call = pallet + .call_variant_by_name(&self.call_name) + .ok_or_else(|| MetadataError::CallNameNotFound( + (*self.call_name).to_owned(), + ))?; + let pallet_index = pallet.index(); + let call_index = call.index; + pallet_index.encode_to(out); + call_index.encode_to(out); + let mut fields = call + .fields + .iter() + .map(|f| scale_encode::Field::new(f.ty.id, f.name.as_deref())); + self.call_data.encode_as_fields_to(&mut fields, metadata.types(), out)?; + Ok(()) + } + fn validation_details(&self) -> Option> { + self.validation_hash + .map(|hash| ValidationDetails { + pallet_name: &self.pallet_name, + call_name: &self.call_name, + hash, + }) + } + } + /// Construct a transaction at runtime; essentially an alias to [`Payload::new()`] + /// which provides a [`Composite`] value for the call data. + pub fn dynamic( + pallet_name: impl Into, + call_name: impl Into, + call_data: impl Into>, + ) -> DynamicPayload { + Payload::new(pallet_name, call_name, call_data.into()) + } + } + mod tx_progress { + //! Types representing extrinsics/transactions that have been submitted to a node. + use std::task::Poll; + use crate::utils::strip_compact_prefix; + use crate::{ + backend::{BlockRef, StreamOfResults, TransactionStatus as BackendTxStatus}, + client::OnlineClientT, + error::{DispatchError, Error, RpcError, TransactionError}, + events::EventsClient, Config, + }; + use derivative::Derivative; + use futures::{Stream, StreamExt}; + /// This struct represents a subscription to the progress of some transaction. + pub struct TxProgress { + sub: Option>>, + ext_hash: T::Hash, + client: C, + } + impl std::fmt::Debug for TxProgress { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TxProgress") + .field("sub", &"") + .field("ext_hash", &self.ext_hash) + .field("client", &"") + .finish() + } + } + impl Unpin for TxProgress {} + impl TxProgress { + /// Instantiate a new [`TxProgress`] from a custom subscription. + pub fn new( + sub: StreamOfResults>, + client: C, + ext_hash: T::Hash, + ) -> Self { + Self { + sub: Some(sub), + client, + ext_hash, + } + } + /// Return the hash of the extrinsic. + pub fn extrinsic_hash(&self) -> T::Hash { + self.ext_hash + } + } + impl TxProgress + where + T: Config, + C: OnlineClientT, + { + /// Return the next transaction status when it's emitted. This just delegates to the + /// [`futures::Stream`] implementation for [`TxProgress`], but allows you to + /// avoid importing that trait if you don't otherwise need it. + pub async fn next(&mut self) -> Option, Error>> { + StreamExt::next(self).await + } + /// Wait for the transaction to be finalized, and return a [`TxInBlock`] + /// instance when it is, or an error if there was a problem waiting for finalization. + /// + /// **Note:** consumes `self`. If you'd like to perform multiple actions as the state of the + /// transaction progresses, use [`TxProgress::next()`] instead. + /// + /// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some + /// probability that the transaction will not make it into a block but there is no guarantee + /// that this is true. In those cases the stream is closed however, so you currently have no way to find + /// out if they finally made it into a block or not. + pub async fn wait_for_finalized(mut self) -> Result, Error> { + while let Some(status) = self.next().await { + match status? { + TxStatus::InFinalizedBlock(s) => return Ok(s), + TxStatus::Error { message } => { + return Err(TransactionError::Error(message).into()); + } + TxStatus::Invalid { message } => { + return Err(TransactionError::Invalid(message).into()); + } + TxStatus::Dropped { message } => { + return Err(TransactionError::Dropped(message).into()); + } + _ => continue, + } + } + Err(RpcError::SubscriptionDropped.into()) + } + /// Wait for the transaction to be finalized, and for the transaction events to indicate + /// that the transaction was successful. Returns the events associated with the transaction, + /// as well as a couple of other details (block hash and extrinsic hash). + /// + /// **Note:** consumes self. If you'd like to perform multiple actions as progress is made, + /// use [`TxProgress::next()`] instead. + /// + /// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some + /// probability that the transaction will not make it into a block but there is no guarantee + /// that this is true. In those cases the stream is closed however, so you currently have no way to find + /// out if they finally made it into a block or not. + pub async fn wait_for_finalized_success( + self, + ) -> Result, Error> { + let evs = self.wait_for_finalized().await?.wait_for_success().await?; + Ok(evs) + } + } + impl Stream for TxProgress { + type Item = Result, Error>; + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + let sub = match self.sub.as_mut() { + Some(sub) => sub, + None => return Poll::Ready(None), + }; + sub.poll_next_unpin(cx) + .map_ok(|status| { + match status { + BackendTxStatus::Validated => TxStatus::Validated, + BackendTxStatus::Broadcasted { num_peers } => { + TxStatus::Broadcasted { num_peers } + } + BackendTxStatus::NoLongerInBestBlock => { + TxStatus::NoLongerInBestBlock + } + BackendTxStatus::InBestBlock { hash } => { + TxStatus::InBestBlock( + TxInBlock::new(hash, self.ext_hash, self.client.clone()), + ) + } + BackendTxStatus::InFinalizedBlock { hash } => { + self.sub = None; + TxStatus::InFinalizedBlock( + TxInBlock::new(hash, self.ext_hash, self.client.clone()), + ) + } + BackendTxStatus::Error { message } => { + self.sub = None; + TxStatus::Error { message } + } + BackendTxStatus::Invalid { message } => { + self.sub = None; + TxStatus::Invalid { message } + } + BackendTxStatus::Dropped { message } => { + self.sub = None; + TxStatus::Dropped { message } + } + } + }) + } + } + /// Possible transaction statuses returned from our [`TxProgress::next()`] call. + #[derivative(Debug(bound = "C: std::fmt::Debug"))] + pub enum TxStatus { + /// Transaction is part of the future queue. + Validated, + /// The transaction has been broadcast to other nodes. + Broadcasted { + /// Number of peers it's been broadcast to. + num_peers: u32, + }, + /// Transaction is no longer in a best block. + NoLongerInBestBlock, + /// Transaction has been included in block with given hash. + InBestBlock(TxInBlock), + /// Transaction has been finalized by a finality-gadget, e.g GRANDPA + InFinalizedBlock(TxInBlock), + /// Something went wrong in the node. + Error { + /// Human readable message; what went wrong. + message: String, + }, + /// Transaction is invalid (bad nonce, signature etc). + Invalid { + /// Human readable message; why was it invalid. + message: String, + }, + /// The transaction was dropped. + Dropped { + /// Human readable message; why was it dropped. + message: String, + }, + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for TxStatus + where + C: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + TxStatus::Validated => { + let mut __debug_trait_builder = __f.debug_tuple("Validated"); + __debug_trait_builder.finish() + } + TxStatus::Broadcasted { num_peers: ref __arg_0 } => { + let mut __debug_trait_builder = __f.debug_struct("Broadcasted"); + let _ = __debug_trait_builder.field("num_peers", &&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::NoLongerInBestBlock => { + let mut __debug_trait_builder = __f + .debug_tuple("NoLongerInBestBlock"); + __debug_trait_builder.finish() + } + TxStatus::InBestBlock(ref __arg_0) => { + let mut __debug_trait_builder = __f.debug_tuple("InBestBlock"); + let _ = __debug_trait_builder.field(&&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::InFinalizedBlock(ref __arg_0) => { + let mut __debug_trait_builder = __f + .debug_tuple("InFinalizedBlock"); + let _ = __debug_trait_builder.field(&&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::Error { message: ref __arg_0 } => { + let mut __debug_trait_builder = __f.debug_struct("Error"); + let _ = __debug_trait_builder.field("message", &&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::Invalid { message: ref __arg_0 } => { + let mut __debug_trait_builder = __f.debug_struct("Invalid"); + let _ = __debug_trait_builder.field("message", &&(*__arg_0)); + __debug_trait_builder.finish() + } + TxStatus::Dropped { message: ref __arg_0 } => { + let mut __debug_trait_builder = __f.debug_struct("Dropped"); + let _ = __debug_trait_builder.field("message", &&(*__arg_0)); + __debug_trait_builder.finish() + } + } + } + } + impl TxStatus { + /// A convenience method to return the finalized details. Returns + /// [`None`] if the enum variant is not [`TxStatus::InFinalizedBlock`]. + pub fn as_finalized(&self) -> Option<&TxInBlock> { + match self { + Self::InFinalizedBlock(val) => Some(val), + _ => None, + } + } + /// A convenience method to return the best block details. Returns + /// [`None`] if the enum variant is not [`TxStatus::InBestBlock`]. + pub fn as_in_block(&self) -> Option<&TxInBlock> { + match self { + Self::InBestBlock(val) => Some(val), + _ => None, + } + } + } + /// This struct represents a transaction that has made it into a block. + #[derivative(Debug(bound = "C: std::fmt::Debug"))] + pub struct TxInBlock { + block_ref: BlockRef, + ext_hash: T::Hash, + client: C, + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for TxInBlock + where + C: std::fmt::Debug, + { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + TxInBlock { + block_ref: ref __arg_0, + ext_hash: ref __arg_1, + client: ref __arg_2, + } => { + let mut __debug_trait_builder = __f.debug_struct("TxInBlock"); + let _ = __debug_trait_builder.field("block_ref", &&(*__arg_0)); + let _ = __debug_trait_builder.field("ext_hash", &&(*__arg_1)); + let _ = __debug_trait_builder.field("client", &&(*__arg_2)); + __debug_trait_builder.finish() + } + } + } + } + impl TxInBlock { + pub(crate) fn new( + block_ref: BlockRef, + ext_hash: T::Hash, + client: C, + ) -> Self { + Self { + block_ref, + ext_hash, + client, + } + } + /// Return the hash of the block that the transaction has made it into. + pub fn block_hash(&self) -> T::Hash { + self.block_ref.hash() + } + /// Return the hash of the extrinsic that was submitted. + pub fn extrinsic_hash(&self) -> T::Hash { + self.ext_hash + } + } + impl> TxInBlock { + /// Fetch the events associated with this transaction. If the transaction + /// was successful (ie no `ExtrinsicFailed`) events were found, then we return + /// the events associated with it. If the transaction was not successful, or + /// something else went wrong, we return an error. + /// + /// **Note:** If multiple `ExtrinsicFailed` errors are returned (for instance + /// because a pallet chooses to emit one as an event, which is considered + /// abnormal behaviour), it is not specified which of the errors is returned here. + /// You can use [`TxInBlock::fetch_events`] instead if you'd like to + /// work with multiple "error" events. + /// + /// **Note:** This has to download block details from the node and decode events + /// from them. + pub async fn wait_for_success( + &self, + ) -> Result, Error> { + let events = self.fetch_events().await?; + for ev in events.iter() { + let ev = ev?; + if ev.pallet_name() == "System" + && ev.variant_name() == "ExtrinsicFailed" + { + let dispatch_error = DispatchError::decode_from( + ev.field_bytes(), + self.client.metadata(), + )?; + return Err(dispatch_error.into()); + } + } + Ok(events) + } + /// Fetch all of the events associated with this transaction. This succeeds whether + /// the transaction was a success or not; it's up to you to handle the error and + /// success events however you prefer. + /// + /// **Note:** This has to download block details from the node and decode events + /// from them. + pub async fn fetch_events( + &self, + ) -> Result, Error> { + let block_body = self + .client + .backend() + .block_body(self.block_ref.hash()) + .await? + .ok_or(Error::Transaction(TransactionError::BlockNotFound))?; + let extrinsic_idx = block_body + .iter() + .position(|ext| { + use crate::config::Hasher; + let Ok((_, stripped)) = strip_compact_prefix(ext) else { + return false; + }; + let hash = T::Hasher::hash_of(&stripped); + hash == self.ext_hash + }) + .ok_or(Error::Transaction(TransactionError::BlockNotFound))?; + let events = EventsClient::new(self.client.clone()) + .at(self.block_ref.clone()) + .await?; + Ok( + crate::blocks::ExtrinsicEvents::new( + self.ext_hash, + extrinsic_idx as u32, + events, + ), + ) + } + } + } + pub use self::{ + signer::Signer, + tx_client::{ + PartialExtrinsic, SubmittableExtrinsic, TransactionInvalid, + TransactionUnknown, TxClient, ValidationResult, + }, + tx_payload::{dynamic, BoxedPayload, DynamicPayload, Payload, TxPayload}, + tx_progress::{TxInBlock, TxProgress, TxStatus}, + }; +} +pub mod utils { + //! Miscellaneous utility helpers. + mod account_id { + //! The "default" Substrate/Polkadot AccountId. This is used in codegen, as well as signing related bits. + //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_core::AccountId32` + //! for instance, to gain functionality without forcing a dependency on Substrate crates here. + use codec::{Decode, Encode}; + use serde::{Deserialize, Serialize}; + /// A 32-byte cryptographic identifier. This is a simplified version of Substrate's + /// `sp_core::crypto::AccountId32`. To obtain more functionality, convert this into + /// that type. + pub struct AccountId32(pub [u8; 32]); + #[automatically_derived] + impl ::core::clone::Clone for AccountId32 { + #[inline] + fn clone(&self) -> AccountId32 { + AccountId32(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::cmp::Eq for AccountId32 { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for AccountId32 {} + #[automatically_derived] + impl ::core::cmp::PartialEq for AccountId32 { + #[inline] + fn eq(&self, other: &AccountId32) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Ord for AccountId32 { + #[inline] + fn cmp(&self, other: &AccountId32) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for AccountId32 { + #[inline] + fn partial_cmp( + &self, + other: &AccountId32, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for AccountId32 { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.0) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.0) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.0, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike for AccountId32 {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for AccountId32 { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok( + AccountId32({ + let __codec_res_edqy = <[u8; 32] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `AccountId32.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for AccountId32 { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "AccountId32", + &&self.0, + ) + } + } + impl ::scale_encode::EncodeAsType for AccountId32 { + #[allow(unused_variables)] + fn encode_as_type_to( + &self, + __encode_as_type_type_id: u32, + __encode_as_type_types: &::scale_encode::PortableRegistry, + __encode_as_type_out: &mut ::scale_encode::Vec, + ) -> Result<(), ::scale_encode::Error> { + let AccountId32(_0) = self; + ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ) + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + } + impl ::scale_encode::EncodeAsFields for AccountId32 { + #[allow(unused_variables)] + fn encode_as_fields_to( + &self, + __encode_as_type_fields: &mut dyn ::scale_encode::FieldIter<'_>, + __encode_as_type_types: &::scale_encode::PortableRegistry, + __encode_as_type_out: &mut ::scale_encode::Vec, + ) -> Result<(), ::scale_encode::Error> { + let AccountId32(_0) = self; + ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ) + .encode_as_fields_to( + __encode_as_type_fields, + __encode_as_type_types, + __encode_as_type_out, + ) + } + } + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for AccountId32 { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = AccountId32; + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + self.visit_tuple(&mut value.as_tuple(), type_id) + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: value.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = value; + Ok( + AccountId32({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ) + } + } + impl ::scale_decode::DecodeAsFields for AccountId32 { + fn decode_as_fields<'info>( + input: &mut &[u8], + fields: &mut dyn ::scale_decode::FieldIter<'info>, + types: &'info ::scale_decode::PortableRegistry, + ) -> Result { + let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; + let mut composite = ::scale_decode::visitor::types::Composite::new( + input, + path, + fields, + types, + false, + ); + use ::scale_decode::{Visitor, IntoVisitor}; + let val = ::into_visitor() + .visit_composite( + &mut composite, + ::scale_decode::visitor::TypeId(0), + ); + composite.skip_decoding()?; + *input = composite.bytes_from_undecoded(); + val.map_err(From::from) + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for AccountId32 { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "AccountId32", + "subxt::utils::account_id", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .docs( + &[ + "A 32-byte cryptographic identifier. This is a simplified version of Substrate's", + "`sp_core::crypto::AccountId32`. To obtain more functionality, convert this into", + "that type.", + ], + ) + .composite( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 32]>().type_name("[u8; 32]")), + ) + } + } + }; + impl AsRef<[u8]> for AccountId32 { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } + } + impl AsRef<[u8; 32]> for AccountId32 { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } + } + impl From<[u8; 32]> for AccountId32 { + fn from(x: [u8; 32]) -> Self { + AccountId32(x) + } + } + impl AccountId32 { + fn to_ss58check(&self) -> String { + const SUBSTRATE_SS58_PREFIX: u8 = 42; + let mut v = <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([SUBSTRATE_SS58_PREFIX]), + ); + v.extend(self.0); + let r = ss58hash(&v); + v.extend(&r[0..2]); + use base58::ToBase58; + v.to_base58() + } + fn from_ss58check(s: &str) -> Result { + const CHECKSUM_LEN: usize = 2; + let body_len = 32; + use base58::FromBase58; + let data = s.from_base58().map_err(|_| FromSs58Error::BadBase58)?; + if data.len() < 2 { + return Err(FromSs58Error::BadLength); + } + let prefix_len = match data[0] { + 0..=63 => 1, + 64..=127 => 2, + _ => return Err(FromSs58Error::InvalidPrefix), + }; + if data.len() != prefix_len + body_len + CHECKSUM_LEN { + return Err(FromSs58Error::BadLength); + } + let hash = ss58hash(&data[0..body_len + prefix_len]); + let checksum = &hash[0..CHECKSUM_LEN]; + if data[body_len + prefix_len..body_len + prefix_len + CHECKSUM_LEN] + != *checksum + { + return Err(FromSs58Error::InvalidChecksum); + } + let result = data[prefix_len..body_len + prefix_len] + .try_into() + .map_err(|_| FromSs58Error::BadLength)?; + Ok(AccountId32(result)) + } + } + /// An error obtained from trying to interpret an SS58 encoded string into an AccountId32 + #[allow(missing_docs)] + pub enum FromSs58Error { + #[error("Base 58 requirement is violated")] + BadBase58, + #[error("Length is bad")] + BadLength, + #[error("Invalid checksum")] + InvalidChecksum, + #[error("Invalid SS58 prefix byte.")] + InvalidPrefix, + } + #[allow(unused_qualifications)] + impl std::error::Error for FromSs58Error {} + #[allow(unused_qualifications)] + impl ::core::fmt::Display for FromSs58Error { + fn fmt( + &self, + __formatter: &mut ::core::fmt::Formatter, + ) -> ::core::fmt::Result { + #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] + match self { + FromSs58Error::BadBase58 {} => { + __formatter.write_str("Base 58 requirement is violated") + } + FromSs58Error::BadLength {} => __formatter.write_str("Length is bad"), + FromSs58Error::InvalidChecksum {} => { + __formatter.write_str("Invalid checksum") + } + FromSs58Error::InvalidPrefix {} => { + __formatter.write_str("Invalid SS58 prefix byte.") + } + } + } + } + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::clone::Clone for FromSs58Error { + #[inline] + fn clone(&self) -> FromSs58Error { + *self + } + } + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::marker::Copy for FromSs58Error {} + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::cmp::Eq for FromSs58Error { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::marker::StructuralPartialEq for FromSs58Error {} + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::cmp::PartialEq for FromSs58Error { + #[inline] + fn eq(&self, other: &FromSs58Error) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } + } + #[automatically_derived] + #[allow(missing_docs)] + impl ::core::fmt::Debug for FromSs58Error { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + FromSs58Error::BadBase58 => "BadBase58", + FromSs58Error::BadLength => "BadLength", + FromSs58Error::InvalidChecksum => "InvalidChecksum", + FromSs58Error::InvalidPrefix => "InvalidPrefix", + }, + ) + } + } + fn ss58hash(data: &[u8]) -> Vec { + use blake2::{Blake2b512, Digest}; + const PREFIX: &[u8] = b"SS58PRE"; + let mut ctx = Blake2b512::new(); + ctx.update(PREFIX); + ctx.update(data); + ctx.finalize().to_vec() + } + impl Serialize for AccountId32 { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_ss58check()) + } + } + impl<'de> Deserialize<'de> for AccountId32 { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + AccountId32::from_ss58check(&String::deserialize(deserializer)?) + .map_err(|e| serde::de::Error::custom({ + let res = ::alloc::fmt::format(format_args!("{0:?}", e)); + res + })) + } + } + impl std::fmt::Display for AccountId32 { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.write_fmt(format_args!("{0}", self.to_ss58check())) + } + } + impl std::str::FromStr for AccountId32 { + type Err = FromSs58Error; + fn from_str(s: &str) -> Result { + AccountId32::from_ss58check(s) + } + } + } + pub mod bits { + //! Generic `scale_bits` over `bitvec`-like `BitOrder` and `BitFormat` types. + use codec::{Compact, Input}; + use scale_bits::{ + scale::format::{Format, OrderFormat, StoreFormat}, + Bits, + }; + use scale_decode::IntoVisitor; + use std::marker::PhantomData; + /// Associates `bitvec::store::BitStore` trait with corresponding, type-erased `scale_bits::StoreFormat` enum. + /// + /// Used to decode bit sequences by providing `scale_bits::StoreFormat` using + /// `bitvec`-like type type parameters. + pub trait BitStore { + /// Corresponding `scale_bits::StoreFormat` value. + const FORMAT: StoreFormat; + /// Number of bits that the backing store types holds. + const BITS: u32; + } + impl BitStore for u8 { + const FORMAT: StoreFormat = StoreFormat::U8; + const BITS: u32 = ::BITS; + } + impl BitStore for u16 { + const FORMAT: StoreFormat = StoreFormat::U16; + const BITS: u32 = ::BITS; + } + impl BitStore for u32 { + const FORMAT: StoreFormat = StoreFormat::U32; + const BITS: u32 = ::BITS; + } + impl BitStore for u64 { + const FORMAT: StoreFormat = StoreFormat::U64; + const BITS: u32 = ::BITS; + } + /// Associates `bitvec::order::BitOrder` trait with corresponding, type-erased `scale_bits::OrderFormat` enum. + /// + /// Used to decode bit sequences in runtime by providing `scale_bits::OrderFormat` using + /// `bitvec`-like type type parameters. + pub trait BitOrder { + /// Corresponding `scale_bits::OrderFormat` value. + const FORMAT: OrderFormat; + } + ///Type-level value that corresponds to `scale_bits::OrderFormat::Lsb0` at run-time + /// and `bitvec::order::BitOrder::Lsb0` at the type level. + pub enum Lsb0 {} + #[automatically_derived] + impl ::core::clone::Clone for Lsb0 { + #[inline] + fn clone(&self) -> Lsb0 { + match *self {} + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Lsb0 { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self {} + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Lsb0 {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Lsb0 { + #[inline] + fn eq(&self, other: &Lsb0) -> bool { + match *self {} + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Lsb0 { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + impl BitOrder for Lsb0 { + const FORMAT: OrderFormat = OrderFormat::Lsb0; + } + ///Type-level value that corresponds to `scale_bits::OrderFormat::Msb0` at run-time + /// and `bitvec::order::BitOrder::Msb0` at the type level. + pub enum Msb0 {} + #[automatically_derived] + impl ::core::clone::Clone for Msb0 { + #[inline] + fn clone(&self) -> Msb0 { + match *self {} + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Msb0 { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match *self {} + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Msb0 {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Msb0 { + #[inline] + fn eq(&self, other: &Msb0) -> bool { + match *self {} + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Msb0 { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} + } + impl BitOrder for Msb0 { + const FORMAT: OrderFormat = OrderFormat::Msb0; + } + /// Constructs a run-time format parameters based on the corresponding type-level parameters. + fn bit_format() -> Format { + Format { + order: Order::FORMAT, + store: Store::FORMAT, + } + } + /// `scale_bits::Bits` generic over the bit store (`u8`/`u16`/`u32`/`u64`) and bit order (LSB, MSB) + /// used for SCALE encoding/decoding. Uses `scale_bits::Bits`-default `u8` and LSB format underneath. + pub struct DecodedBits { + bits: Bits, + _marker: PhantomData<(Store, Order)>, + } + #[automatically_derived] + impl ::core::fmt::Debug + for DecodedBits { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "DecodedBits", + "bits", + &self.bits, + "_marker", + &&self._marker, + ) + } + } + #[automatically_derived] + impl< + Store: ::core::clone::Clone, + Order: ::core::clone::Clone, + > ::core::clone::Clone for DecodedBits { + #[inline] + fn clone(&self) -> DecodedBits { + DecodedBits { + bits: ::core::clone::Clone::clone(&self.bits), + _marker: ::core::clone::Clone::clone(&self._marker), + } + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for DecodedBits {} + #[automatically_derived] + impl< + Store: ::core::cmp::PartialEq, + Order: ::core::cmp::PartialEq, + > ::core::cmp::PartialEq for DecodedBits { + #[inline] + fn eq(&self, other: &DecodedBits) -> bool { + self.bits == other.bits && self._marker == other._marker + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for DecodedBits { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + } + } + impl DecodedBits { + /// Extracts the underlying `scale_bits::Bits` value. + pub fn into_bits(self) -> Bits { + self.bits + } + /// References the underlying `scale_bits::Bits` value. + pub fn as_bits(&self) -> &Bits { + &self.bits + } + } + impl core::iter::FromIterator for DecodedBits { + fn from_iter>(iter: T) -> Self { + DecodedBits { + bits: Bits::from_iter(iter), + _marker: PhantomData, + } + } + } + impl codec::Decode + for DecodedBits { + fn decode(input: &mut I) -> Result { + /// Equivalent of `BitSlice::MAX_BITS` on 32bit machine. + const ARCH32BIT_BITSLICE_MAX_BITS: u32 = 0x1fff_ffff; + let Compact(bits) = >::decode(input)?; + if bits > ARCH32BIT_BITSLICE_MAX_BITS { + return Err("Attempt to decode a BitVec with too many bits".into()); + } + let elements = (bits / Store::BITS) + u32::from(bits % Store::BITS != 0); + let bytes_in_elem = Store::BITS.saturating_div(u8::BITS); + let bytes_needed = (elements * bytes_in_elem) as usize; + let mut storage = codec::Encode::encode(&Compact(bits)); + let prefix_len = storage.len(); + storage.reserve_exact(bytes_needed); + storage.extend(::alloc::vec::from_elem(0, bytes_needed)); + input.read(&mut storage[prefix_len..])?; + let decoder = scale_bits::decode_using_format_from( + &storage, + bit_format::(), + )?; + let bits = decoder.collect::, _>>()?; + let bits = Bits::from_iter(bits); + Ok(DecodedBits { + bits, + _marker: PhantomData, + }) + } + } + impl codec::Encode + for DecodedBits { + fn size_hint(&self) -> usize { + self.bits.size_hint() + } + fn encoded_size(&self) -> usize { + self.bits.encoded_size() + } + fn encode(&self) -> Vec { + scale_bits::encode_using_format( + self.bits.iter(), + bit_format::(), + ) + } + } + #[doc(hidden)] + pub struct DecodedBitsVisitor(std::marker::PhantomData<(S, O)>); + impl scale_decode::Visitor for DecodedBitsVisitor { + type Value<'scale, 'info> = DecodedBits; + type Error = scale_decode::Error; + fn unchecked_decode_as_type<'scale, 'info>( + self, + input: &mut &'scale [u8], + type_id: scale_decode::visitor::TypeId, + types: &'info scale_info::PortableRegistry, + ) -> scale_decode::visitor::DecodeAsTypeResult< + Self, + Result, Self::Error>, + > { + let res = scale_decode::visitor::decode_with_visitor( + input, + type_id.0, + types, + Bits::into_visitor(), + ) + .map(|bits| DecodedBits { + bits, + _marker: PhantomData, + }); + scale_decode::visitor::DecodeAsTypeResult::Decoded(res) + } + } + impl scale_decode::IntoVisitor for DecodedBits { + type Visitor = DecodedBitsVisitor; + fn into_visitor() -> Self::Visitor { + DecodedBitsVisitor(PhantomData) + } + } + impl scale_encode::EncodeAsType for DecodedBits { + fn encode_as_type_to( + &self, + type_id: u32, + types: &scale_info::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + self.bits.encode_as_type_to(type_id, types, out) + } + } + } + mod era { + use scale_decode::DecodeAsType; + use scale_encode::EncodeAsType; + /// An era to describe the longevity of a transaction. + pub enum Era { + /// The transaction is valid forever. The genesis hash must be present in the signed content. + #[default] + Immortal, + /// The transaction will expire. Use [`Era::mortal`] to construct this with correct values. + /// + /// When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter + /// of `system` module. + Mortal { + /// The number of blocks that the tx will be valid for after the checkpoint block + /// hash found in the signer payload. + period: u64, + /// The phase in the period that this transaction's lifetime begins (and, importantly, + /// implies which block hash is included in the signature material). If the `period` is + /// greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that + /// `period` is. + phase: u64, + }, + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Era {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Era { + #[inline] + fn eq(&self, other: &Era) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + Era::Mortal { period: __self_0, phase: __self_1 }, + Era::Mortal { period: __arg1_0, phase: __arg1_1 }, + ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, + _ => true, + } + } + } + #[automatically_derived] + impl ::core::default::Default for Era { + #[inline] + fn default() -> Era { + Self::Immortal + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Era { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Era { + #[inline] + fn clone(&self) -> Era { + let _: ::core::clone::AssertParamIsClone; + *self + } + } + #[automatically_derived] + impl ::core::marker::Copy for Era {} + #[automatically_derived] + impl ::core::fmt::Debug for Era { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + Era::Immortal => ::core::fmt::Formatter::write_str(f, "Immortal"), + Era::Mortal { period: __self_0, phase: __self_1 } => { + ::core::fmt::Formatter::debug_struct_field2_finish( + f, + "Mortal", + "period", + __self_0, + "phase", + &__self_1, + ) + } + } + } + } + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl _serde::Serialize for Era { + fn serialize<__S>( + &self, + __serializer: __S, + ) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + match *self { + Era::Immortal => { + _serde::Serializer::serialize_unit_variant( + __serializer, + "Era", + 0u32, + "Immortal", + ) + } + Era::Mortal { ref period, ref phase } => { + let mut __serde_state = _serde::Serializer::serialize_struct_variant( + __serializer, + "Era", + 1u32, + "Mortal", + 0 + 1 + 1, + )?; + _serde::ser::SerializeStructVariant::serialize_field( + &mut __serde_state, + "period", + period, + )?; + _serde::ser::SerializeStructVariant::serialize_field( + &mut __serde_state, + "phase", + phase, + )?; + _serde::ser::SerializeStructVariant::end(__serde_state) + } + } + } + } + }; + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + #[automatically_derived] + impl<'de> _serde::Deserialize<'de> for Era { + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "variant identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &"variant index 0 <= i < 2", + ), + ) + } + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "Immortal" => _serde::__private::Ok(__Field::__field0), + "Mortal" => _serde::__private::Ok(__Field::__field1), + _ => { + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"Immortal" => _serde::__private::Ok(__Field::__field0), + b"Mortal" => _serde::__private::Ok(__Field::__field1), + _ => { + let __value = &_serde::__private::from_utf8_lossy(__value); + _serde::__private::Err( + _serde::de::Error::unknown_variant(__value, VARIANTS), + ) + } + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Era; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "enum Era", + ) + } + fn visit_enum<__A>( + self, + __data: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<'de>, + { + match _serde::de::EnumAccess::variant(__data)? { + (__Field::__field0, __variant) => { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(Era::Immortal) + } + (__Field::__field1, __variant) => { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field { + __field0, + __field1, + __ignore, + } + #[doc(hidden)] + struct __FieldVisitor; + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "field identifier", + ) + } + fn visit_u64<__E>( + self, + __value: u64, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + 0u64 => _serde::__private::Ok(__Field::__field0), + 1u64 => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_str<__E>( + self, + __value: &str, + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + "period" => _serde::__private::Ok(__Field::__field0), + "phase" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + fn visit_bytes<__E>( + self, + __value: &[u8], + ) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + b"period" => _serde::__private::Ok(__Field::__field0), + b"phase" => _serde::__private::Ok(__Field::__field1), + _ => _serde::__private::Ok(__Field::__ignore), + } + } + } + impl<'de> _serde::Deserialize<'de> for __Field { + #[inline] + fn deserialize<__D>( + __deserializer: __D, + ) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier( + __deserializer, + __FieldVisitor, + ) + } + } + #[doc(hidden)] + struct __Visitor<'de> { + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData<&'de ()>, + } + impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { + type Value = Era; + fn expecting( + &self, + __formatter: &mut _serde::__private::Formatter, + ) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str( + __formatter, + "struct variant Era::Mortal", + ) + } + #[inline] + fn visit_seq<__A>( + self, + mut __seq: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + let __field0 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 0usize, + &"struct variant Era::Mortal with 2 elements", + ), + ); + } + }; + let __field1 = match _serde::de::SeqAccess::next_element::< + u64, + >(&mut __seq)? { + _serde::__private::Some(__value) => __value, + _serde::__private::None => { + return _serde::__private::Err( + _serde::de::Error::invalid_length( + 1usize, + &"struct variant Era::Mortal with 2 elements", + ), + ); + } + }; + _serde::__private::Ok(Era::Mortal { + period: __field0, + phase: __field1, + }) + } + #[inline] + fn visit_map<__A>( + self, + mut __map: __A, + ) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + let mut __field0: _serde::__private::Option = _serde::__private::None; + let mut __field1: _serde::__private::Option = _serde::__private::None; + while let _serde::__private::Some(__key) + = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + __Field::__field0 => { + if _serde::__private::Option::is_some(&__field0) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("period"), + ); + } + __field0 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + __Field::__field1 => { + if _serde::__private::Option::is_some(&__field1) { + return _serde::__private::Err( + <__A::Error as _serde::de::Error>::duplicate_field("phase"), + ); + } + __field1 = _serde::__private::Some( + _serde::de::MapAccess::next_value::(&mut __map)?, + ); + } + _ => { + let _ = _serde::de::MapAccess::next_value::< + _serde::de::IgnoredAny, + >(&mut __map)?; + } + } + } + let __field0 = match __field0 { + _serde::__private::Some(__field0) => __field0, + _serde::__private::None => { + _serde::__private::de::missing_field("period")? + } + }; + let __field1 = match __field1 { + _serde::__private::Some(__field1) => __field1, + _serde::__private::None => { + _serde::__private::de::missing_field("phase")? + } + }; + _serde::__private::Ok(Era::Mortal { + period: __field0, + phase: __field1, + }) + } + } + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ + "period", + "phase", + ]; + _serde::de::VariantAccess::struct_variant( + __variant, + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + } + } + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &["Immortal", "Mortal"]; + _serde::Deserializer::deserialize_enum( + __deserializer, + "Era", + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::, + lifetime: _serde::__private::PhantomData, + }, + ) + } + } + }; + const _: () = { + pub struct Visitor(::core::marker::PhantomData<()>); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor for Era { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor for Visitor { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = Era; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "Immortal" { + return Ok(Era::Immortal); + } + if value.name() == "Mortal" { + let fields = value.fields(); + return if fields.has_unnamed_fields() { + if fields.remaining() != 2usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 2usize, + }), + ); + } + let vals = fields; + Ok(Era::Mortal { + period: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("period"))? + }, + phase: { + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_field("phase"))? + }, + }) + } else { + let vals: ::scale_decode::BTreeMap, _> = fields + .map(|res| res.map(|item| (item.name(), item))) + .collect::>()?; + Ok(Era::Mortal { + period: { + let val = *vals + .get(&Some("period")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "period".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("period"))? + }, + phase: { + let val = *vals + .get(&Some("phase")) + .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { + name: "phase".to_string(), + }))?; + val.decode_as_type().map_err(|e| e.at_field("phase"))? + }, + }) + }; + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new(["Immortal", "Mortal"]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + impl ::scale_encode::EncodeAsType for Era { + #[allow(unused_variables)] + fn encode_as_type_to( + &self, + __encode_as_type_type_id: u32, + __encode_as_type_types: &::scale_encode::PortableRegistry, + __encode_as_type_out: &mut ::scale_encode::Vec, + ) -> Result<(), ::scale_encode::Error> { + match self { + Self::Immortal => { + ::scale_encode::Variant { + name: "Immortal", + fields: ::scale_encode::Composite( + ([] + as [( + Option<&'static str>, + &dyn ::scale_encode::EncodeAsType, + ); 0]) + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Mortal { period, phase } => { + ::scale_encode::Variant { + name: "Mortal", + fields: ::scale_encode::Composite( + [ + ( + Some("period"), + period as &dyn ::scale_encode::EncodeAsType, + ), + (Some("phase"), phase as &dyn ::scale_encode::EncodeAsType), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + _ => { + ::core::panicking::panic( + "internal error: entered unreachable code", + ) + } + } + } + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for Era { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "Era", + "subxt::utils::era", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .docs(&["An era to describe the longevity of a transaction."]) + .variant( + ::scale_info::build::Variants::new() + .variant( + "Immortal", + |v| { + v + .index(0usize as ::core::primitive::u8) + .docs( + &[ + "The transaction is valid forever. The genesis hash must be present in the signed content.", + ], + ) + }, + ) + .variant( + "Mortal", + |v| { + v + .index(1usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::named() + .field(|f| { + f + .ty::() + .name("period") + .type_name("u64") + .docs( + &[ + "The number of blocks that the tx will be valid for after the checkpoint block", + "hash found in the signer payload.", + ], + ) + }) + .field(|f| { + f + .ty::() + .name("phase") + .type_name("u64") + .docs( + &[ + "The phase in the period that this transaction's lifetime begins (and, importantly,", + "implies which block hash is included in the signature material). If the `period` is", + "greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that", + "`period` is.", + ], + ) + }), + ) + .docs( + &[ + "The transaction will expire. Use [`Era::mortal`] to construct this with correct values.", + "", + "When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter", + "of `system` module.", + ], + ) + }, + ), + ) + } + } + }; + impl Era { + /// Create a new era based on a period (which should be a power of two between 4 and 65536 + /// inclusive) and a block number on which it should start (or, for long periods, be shortly + /// after the start). + /// + /// If using `Era` in the context of `FRAME` runtime, make sure that `period` + /// does not exceed `BlockHashCount` parameter passed to `system` module, since that + /// prunes old blocks and renders transactions immediately invalid. + pub fn mortal(period: u64, current: u64) -> Self { + let period = period + .checked_next_power_of_two() + .unwrap_or(1 << 16) + .clamp(4, 1 << 16); + let phase = current % period; + let quantize_factor = (period >> 12).max(1); + let quantized_phase = phase / quantize_factor * quantize_factor; + Self::Mortal { + period, + phase: quantized_phase, + } + } + } + impl codec::Encode for Era { + fn encode_to(&self, output: &mut T) { + match self { + Self::Immortal => output.push_byte(0), + Self::Mortal { period, phase } => { + let quantize_factor = (*period >> 12).max(1); + let encoded = (period.trailing_zeros() - 1).clamp(1, 15) as u16 + | ((phase / quantize_factor) << 4) as u16; + encoded.encode_to(output); + } + } + } + } + impl codec::Decode for Era { + fn decode(input: &mut I) -> Result { + let first = input.read_byte()?; + if first == 0 { + Ok(Self::Immortal) + } else { + let encoded = first as u64 + ((input.read_byte()? as u64) << 8); + let period = 2 << (encoded % (1 << 4)); + let quantize_factor = (period >> 12).max(1); + let phase = (encoded >> 4) * quantize_factor; + if period >= 4 && phase < period { + Ok(Self::Mortal { period, phase }) + } else { + Err("Invalid period and phase".into()) + } + } + } + } + } + mod multi_address { + //! The "default" Substrate/Polkadot Address type. This is used in codegen, as well as signing related bits. + //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_runtime::MultiAddress` + //! for instance, to gain functionality without forcing a dependency on Substrate crates here. + use codec::{Decode, Encode}; + /// A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's + /// `sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion + /// functionality is provided via `From` impls if the `substrate-compat` feature is enabled). + pub enum MultiAddress { + /// It's an account ID (pubkey). + Id(AccountId), + /// It's an account index. + Index(#[codec(compact)] AccountIndex), + /// It's some arbitrary raw bytes. + Raw(Vec), + /// It's a 32 byte representation. + Address32([u8; 32]), + /// Its a 20 byte representation. + Address20([u8; 20]), + } + #[automatically_derived] + impl< + AccountId: ::core::clone::Clone, + AccountIndex: ::core::clone::Clone, + > ::core::clone::Clone for MultiAddress { + #[inline] + fn clone(&self) -> MultiAddress { + match self { + MultiAddress::Id(__self_0) => { + MultiAddress::Id(::core::clone::Clone::clone(__self_0)) + } + MultiAddress::Index(__self_0) => { + MultiAddress::Index(::core::clone::Clone::clone(__self_0)) + } + MultiAddress::Raw(__self_0) => { + MultiAddress::Raw(::core::clone::Clone::clone(__self_0)) + } + MultiAddress::Address32(__self_0) => { + MultiAddress::Address32(::core::clone::Clone::clone(__self_0)) + } + MultiAddress::Address20(__self_0) => { + MultiAddress::Address20(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq + for MultiAddress { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq; + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; + let _: ::core::cmp::AssertParamIsEq<[u8; 20]>; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for MultiAddress {} + #[automatically_derived] + impl< + AccountId: ::core::cmp::PartialEq, + AccountIndex: ::core::cmp::PartialEq, + > ::core::cmp::PartialEq for MultiAddress { + #[inline] + fn eq(&self, other: &MultiAddress) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + ( + MultiAddress::Index(__self_0), + MultiAddress::Index(__arg1_0), + ) => *__self_0 == *__arg1_0, + (MultiAddress::Raw(__self_0), MultiAddress::Raw(__arg1_0)) => { + *__self_0 == *__arg1_0 + } + ( + MultiAddress::Address32(__self_0), + MultiAddress::Address32(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MultiAddress::Address20(__self_0), + MultiAddress::Address20(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl< + AccountId: ::core::cmp::Ord, + AccountIndex: ::core::cmp::Ord, + > ::core::cmp::Ord for MultiAddress { + #[inline] + fn cmp( + &self, + other: &MultiAddress, + ) -> ::core::cmp::Ordering { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) { + ::core::cmp::Ordering::Equal => { + match (self, other) { + (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { + ::core::cmp::Ord::cmp(__self_0, __arg1_0) + } + ( + MultiAddress::Index(__self_0), + MultiAddress::Index(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiAddress::Raw(__self_0), + MultiAddress::Raw(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiAddress::Address32(__self_0), + MultiAddress::Address32(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiAddress::Address20(__self_0), + MultiAddress::Address20(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl< + AccountId: ::core::cmp::PartialOrd, + AccountIndex: ::core::cmp::PartialOrd, + > ::core::cmp::PartialOrd for MultiAddress { + #[inline] + fn partial_cmp( + &self, + other: &MultiAddress, + ) -> ::core::option::Option<::core::cmp::Ordering> { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + match (self, other) { + (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) + } + (MultiAddress::Index(__self_0), MultiAddress::Index(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) + } + (MultiAddress::Raw(__self_0), MultiAddress::Raw(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) + } + ( + MultiAddress::Address32(__self_0), + MultiAddress::Address32(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + ( + MultiAddress::Address20(__self_0), + MultiAddress::Address20(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode + for MultiAddress + where + AccountId: ::codec::Encode, + AccountId: ::codec::Encode, + AccountIndex: ::codec::HasCompact, + { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + MultiAddress::Id(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiAddress::Index(ref aa) => { + 0_usize + .saturating_add( + ::codec::Encode::size_hint( + &<::Type as ::codec::EncodeAsRef< + '_, + AccountIndex, + >>::RefType::from(aa), + ), + ) + } + MultiAddress::Raw(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiAddress::Address32(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiAddress::Address20(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + _ => 0_usize, + } + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + match *self { + MultiAddress::Id(ref aa) => { + __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiAddress::Index(ref aa) => { + __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); + { + ::codec::Encode::encode_to( + &<::Type as ::codec::EncodeAsRef< + '_, + AccountIndex, + >>::RefType::from(aa), + __codec_dest_edqy, + ); + } + } + MultiAddress::Raw(ref aa) => { + __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiAddress::Address32(ref aa) => { + __codec_dest_edqy.push_byte(3usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiAddress::Address20(ref aa) => { + __codec_dest_edqy.push_byte(4usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::codec::EncodeLike + for MultiAddress + where + AccountId: ::codec::Encode, + AccountId: ::codec::Encode, + AccountIndex: ::codec::HasCompact, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode + for MultiAddress + where + AccountId: ::codec::Decode, + AccountId: ::codec::Decode, + AccountIndex: ::codec::HasCompact, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `MultiAddress`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Id({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Id.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Index({ + let __codec_res_edqy = <::Type as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Index.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy.into() + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Raw({ + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Raw.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 3usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Address32({ + let __codec_res_edqy = <[u8; 32] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Address32.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 4usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiAddress::< + AccountId, + AccountIndex, + >::Address20({ + let __codec_res_edqy = <[u8; 20] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiAddress::Address20.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `MultiAddress`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + #[automatically_derived] + impl< + AccountId: ::core::fmt::Debug, + AccountIndex: ::core::fmt::Debug, + > ::core::fmt::Debug for MultiAddress { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + MultiAddress::Id(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Id", + &__self_0, + ) + } + MultiAddress::Index(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Index", + &__self_0, + ) + } + MultiAddress::Raw(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Raw", + &__self_0, + ) + } + MultiAddress::Address32(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Address32", + &__self_0, + ) + } + MultiAddress::Address20(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Address20", + &__self_0, + ) + } + } + } + } + impl ::scale_encode::EncodeAsType + for MultiAddress + where + AccountId: ::scale_encode::EncodeAsType, + AccountIndex: ::scale_encode::EncodeAsType, + { + #[allow(unused_variables)] + fn encode_as_type_to( + &self, + __encode_as_type_type_id: u32, + __encode_as_type_types: &::scale_encode::PortableRegistry, + __encode_as_type_out: &mut ::scale_encode::Vec, + ) -> Result<(), ::scale_encode::Error> { + match self { + Self::Id(_0) => { + ::scale_encode::Variant { + name: "Id", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Index(_0) => { + ::scale_encode::Variant { + name: "Index", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Raw(_0) => { + ::scale_encode::Variant { + name: "Raw", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Address32(_0) => { + ::scale_encode::Variant { + name: "Address32", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + Self::Address20(_0) => { + ::scale_encode::Variant { + name: "Address20", + fields: ::scale_encode::Composite( + [ + ( + None as Option<&'static str>, + _0 as &dyn ::scale_encode::EncodeAsType, + ), + ] + .into_iter(), + ), + } + .encode_as_type_to( + __encode_as_type_type_id, + __encode_as_type_types, + __encode_as_type_out, + ) + } + _ => { + ::core::panicking::panic( + "internal error: entered unreachable code", + ) + } + } + } + } + const _: () = { + pub struct Visitor( + ::core::marker::PhantomData<(AccountId, AccountIndex)>, + ); + use ::scale_decode::vec; + use ::scale_decode::ToString; + impl ::scale_decode::IntoVisitor + for MultiAddress + where + AccountId: ::scale_decode::IntoVisitor, + ::scale_decode::Error: From< + <::Visitor as ::scale_decode::Visitor>::Error, + >, + AccountIndex: ::scale_decode::IntoVisitor, + ::scale_decode::Error: From< + <::Visitor as ::scale_decode::Visitor>::Error, + >, + { + type Visitor = Visitor; + fn into_visitor() -> Self::Visitor { + Visitor(::core::marker::PhantomData) + } + } + impl ::scale_decode::Visitor + for Visitor + where + AccountId: ::scale_decode::IntoVisitor, + ::scale_decode::Error: From< + <::Visitor as ::scale_decode::Visitor>::Error, + >, + AccountIndex: ::scale_decode::IntoVisitor, + ::scale_decode::Error: From< + <::Visitor as ::scale_decode::Visitor>::Error, + >, + { + type Error = ::scale_decode::Error; + type Value<'scale, 'info> = MultiAddress; + fn visit_variant<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, + type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.name() == "Id" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Id({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Index" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Index({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Raw" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Raw({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Address32" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Address32({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + if value.name() == "Address20" { + let fields = value.fields(); + if fields.remaining() != 1usize { + return Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { + actual_len: fields.remaining(), + expected_len: 1usize, + }), + ); + } + let vals = fields; + return Ok( + MultiAddress::Address20({ + let val = vals + .next() + .expect( + "field count should have been checked already on tuple type; please file a bug report", + )?; + val.decode_as_type().map_err(|e| e.at_idx(0usize))? + }), + ); + } + Err( + ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { + got: value.name().to_string(), + expected: <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + "Id", + "Index", + "Raw", + "Address32", + "Address20", + ]), + ), + }), + ) + } + fn visit_composite<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Composite, + ); + } + value.decode_item(self).unwrap() + } + fn visit_tuple<'scale, 'info>( + self, + value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, + _type_id: ::scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + if value.remaining() != 1 { + return self + .visit_unexpected( + ::scale_decode::visitor::Unexpected::Tuple, + ); + } + value.decode_item(self).unwrap() + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo + for MultiAddress + where + AccountId: ::scale_info::TypeInfo + 'static, + AccountIndex: ::scale_info::scale::HasCompact, + AccountId: ::scale_info::TypeInfo + 'static, + AccountIndex: ::scale_info::TypeInfo + 'static, + { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "MultiAddress", + "subxt::utils::multi_address", + &[], + ), + ) + .type_params( + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + ::scale_info::TypeParameter::new( + "AccountId", + ::core::option::Option::Some( + ::scale_info::meta_type::(), + ), + ), + ::scale_info::TypeParameter::new( + "AccountIndex", + ::core::option::Option::Some( + ::scale_info::meta_type::(), + ), + ), + ]), + ), + ) + .docs( + &[ + "A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's", + "`sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion", + "functionality is provided via `From` impls if the `substrate-compat` feature is enabled).", + ], + ) + .variant( + ::scale_info::build::Variants::new() + .variant( + "Id", + |v| { + v + .index(0usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::().type_name("AccountId")), + ) + .docs(&["It's an account ID (pubkey)."]) + }, + ) + .variant( + "Index", + |v| { + v + .index(1usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| { + f.compact::().type_name("AccountIndex") + }), + ) + .docs(&["It's an account index."]) + }, + ) + .variant( + "Raw", + |v| { + v + .index(2usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::>().type_name("Vec")), + ) + .docs(&["It's some arbitrary raw bytes."]) + }, + ) + .variant( + "Address32", + |v| { + v + .index(3usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 32]>().type_name("[u8; 32]")), + ) + .docs(&["It's a 32 byte representation."]) + }, + ) + .variant( + "Address20", + |v| { + v + .index(4usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 20]>().type_name("[u8; 20]")), + ) + .docs(&["Its a 20 byte representation."]) + }, + ), + ) + } + } + }; + impl From + for MultiAddress { + fn from(a: AccountId) -> Self { + Self::Id(a) + } + } + } + mod multi_signature { + //! The "default" Substrate/Polkadot Signature type. This is used in codegen, as well as signing related bits. + //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_runtime::MultiSignature` + //! for instance, to gain functionality without forcing a dependency on Substrate crates here. + use codec::{Decode, Encode}; + /// Signature container that can store known signature types. This is a simplified version of + /// `sp_runtime::MultiSignature`. To obtain more functionality, convert this into that type. + pub enum MultiSignature { + /// An Ed25519 signature. + Ed25519([u8; 64]), + /// An Sr25519 signature. + Sr25519([u8; 64]), + /// An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID). + Ecdsa([u8; 65]), + } + #[automatically_derived] + impl ::core::clone::Clone for MultiSignature { + #[inline] + fn clone(&self) -> MultiSignature { + match self { + MultiSignature::Ed25519(__self_0) => { + MultiSignature::Ed25519(::core::clone::Clone::clone(__self_0)) + } + MultiSignature::Sr25519(__self_0) => { + MultiSignature::Sr25519(::core::clone::Clone::clone(__self_0)) + } + MultiSignature::Ecdsa(__self_0) => { + MultiSignature::Ecdsa(::core::clone::Clone::clone(__self_0)) + } + } + } + } + #[automatically_derived] + impl ::core::cmp::Eq for MultiSignature { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; + let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; + let _: ::core::cmp::AssertParamIsEq<[u8; 65]>; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for MultiSignature {} + #[automatically_derived] + impl ::core::cmp::PartialEq for MultiSignature { + #[inline] + fn eq(&self, other: &MultiSignature) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + && match (self, other) { + ( + MultiSignature::Ed25519(__self_0), + MultiSignature::Ed25519(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MultiSignature::Sr25519(__self_0), + MultiSignature::Sr25519(__arg1_0), + ) => *__self_0 == *__arg1_0, + ( + MultiSignature::Ecdsa(__self_0), + MultiSignature::Ecdsa(__arg1_0), + ) => *__self_0 == *__arg1_0, + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + } + #[automatically_derived] + impl ::core::cmp::Ord for MultiSignature { + #[inline] + fn cmp(&self, other: &MultiSignature) -> ::core::cmp::Ordering { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) { + ::core::cmp::Ordering::Equal => { + match (self, other) { + ( + MultiSignature::Ed25519(__self_0), + MultiSignature::Ed25519(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiSignature::Sr25519(__self_0), + MultiSignature::Sr25519(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + ( + MultiSignature::Ecdsa(__self_0), + MultiSignature::Ecdsa(__arg1_0), + ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), + _ => unsafe { ::core::intrinsics::unreachable() } + } + } + cmp => cmp, + } + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for MultiSignature { + #[inline] + fn partial_cmp( + &self, + other: &MultiSignature, + ) -> ::core::option::Option<::core::cmp::Ordering> { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + match (self, other) { + ( + MultiSignature::Ed25519(__self_0), + MultiSignature::Ed25519(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + ( + MultiSignature::Sr25519(__self_0), + MultiSignature::Sr25519(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + ( + MultiSignature::Ecdsa(__self_0), + MultiSignature::Ecdsa(__arg1_0), + ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), + _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for MultiSignature { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + MultiSignature::Ed25519(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiSignature::Sr25519(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + MultiSignature::Ecdsa(ref aa) => { + 0_usize.saturating_add(::codec::Encode::size_hint(aa)) + } + _ => 0_usize, + } + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + match *self { + MultiSignature::Ed25519(ref aa) => { + __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiSignature::Sr25519(ref aa) => { + __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + MultiSignature::Ecdsa(ref aa) => { + __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); + ::codec::Encode::encode_to(aa, __codec_dest_edqy); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::codec::EncodeLike for MultiSignature {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for MultiSignature { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `MultiSignature`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiSignature::Ed25519({ + let __codec_res_edqy = <[u8; 64] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiSignature::Ed25519.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiSignature::Sr25519({ + let __codec_res_edqy = <[u8; 64] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiSignature::Sr25519.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy + == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok( + MultiSignature::Ecdsa({ + let __codec_res_edqy = <[u8; 65] as ::codec::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `MultiSignature::Ecdsa.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `MultiSignature`, variant doesn't exist", + ), + ) + })(); + } + } + } + } + }; + #[automatically_derived] + impl ::core::fmt::Debug for MultiSignature { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match self { + MultiSignature::Ed25519(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Ed25519", + &__self_0, + ) + } + MultiSignature::Sr25519(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Sr25519", + &__self_0, + ) + } + MultiSignature::Ecdsa(__self_0) => { + ::core::fmt::Formatter::debug_tuple_field1_finish( + f, + "Ecdsa", + &__self_0, + ) + } + } + } + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for MultiSignature { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "MultiSignature", + "subxt::utils::multi_signature", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .docs( + &[ + "Signature container that can store known signature types. This is a simplified version of", + "`sp_runtime::MultiSignature`. To obtain more functionality, convert this into that type.", + ], + ) + .variant( + ::scale_info::build::Variants::new() + .variant( + "Ed25519", + |v| { + v + .index(0usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 64]>().type_name("[u8; 64]")), + ) + .docs(&["An Ed25519 signature."]) + }, + ) + .variant( + "Sr25519", + |v| { + v + .index(1usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 64]>().type_name("[u8; 64]")), + ) + .docs(&["An Sr25519 signature."]) + }, + ) + .variant( + "Ecdsa", + |v| { + v + .index(2usize as ::core::primitive::u8) + .fields( + ::scale_info::build::Fields::unnamed() + .field(|f| f.ty::<[u8; 65]>().type_name("[u8; 65]")), + ) + .docs( + &[ + "An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID).", + ], + ) + }, + ), + ) + } + } + }; + } + mod static_type { + use codec::{Decode, Encode}; + use scale_decode::{visitor::DecodeAsTypeResult, IntoVisitor, Visitor}; + use scale_encode::EncodeAsType; + /// If the type inside this implements [`Encode`], this will implement [`scale_encode::EncodeAsType`]. + /// If the type inside this implements [`Decode`], this will implement [`scale_decode::DecodeAsType`]. + /// + /// In either direction, we ignore any type information and just attempt to encode/decode statically + /// via the [`Encode`] and [`Decode`] implementations. This can be useful as an adapter for types which + /// do not implement [`scale_encode::EncodeAsType`] and [`scale_decode::DecodeAsType`] themselves, but + /// it's best to avoid using it where possible as it will not take into account any type information, + /// and is thus more likely to encode or decode incorrectly. + pub struct Static(pub T); + #[automatically_derived] + impl ::core::fmt::Debug for Static { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Static", &&self.0) + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for Static + where + T: ::codec::Encode, + T: ::codec::Encode, + { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.0) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.0) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.0, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike for Static + where + T: ::codec::Encode, + T: ::codec::Encode, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for Static + where + T: ::codec::Decode, + T: ::codec::Decode, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok( + Static::< + T, + >({ + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `Static.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + } + } + }; + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Static {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Static { + #[inline] + fn eq(&self, other: &Static) -> bool { + self.0 == other.0 + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Static { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for Static { + #[inline] + fn clone(&self) -> Static { + Static(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::cmp::PartialOrd for Static { + #[inline] + fn partial_cmp( + &self, + other: &Static, + ) -> ::core::option::Option<::core::cmp::Ordering> { + ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::cmp::Ord for Static { + #[inline] + fn cmp(&self, other: &Static) -> ::core::cmp::Ordering { + ::core::cmp::Ord::cmp(&self.0, &other.0) + } + } + #[automatically_derived] + impl ::core::hash::Hash for Static { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.0, state) + } + } + impl EncodeAsType for Static { + fn encode_as_type_to( + &self, + _type_id: u32, + _types: &scale_decode::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + self.0.encode_to(out); + Ok(()) + } + } + pub struct StaticDecodeAsTypeVisitor(std::marker::PhantomData); + impl Visitor for StaticDecodeAsTypeVisitor { + type Value<'scale, 'info> = Static; + type Error = scale_decode::Error; + fn unchecked_decode_as_type<'scale, 'info>( + self, + input: &mut &'scale [u8], + _type_id: scale_decode::visitor::TypeId, + _types: &'info scale_info::PortableRegistry, + ) -> DecodeAsTypeResult< + Self, + Result, Self::Error>, + > { + use scale_decode::{visitor::DecodeError, Error}; + let decoded = T::decode(input) + .map(Static) + .map_err(|e| Error::new(DecodeError::CodecError(e).into())); + DecodeAsTypeResult::Decoded(decoded) + } + } + impl IntoVisitor for Static { + type Visitor = StaticDecodeAsTypeVisitor; + fn into_visitor() -> Self::Visitor { + StaticDecodeAsTypeVisitor(std::marker::PhantomData) + } + } + impl From for Static { + fn from(value: T) -> Self { + Static(value) + } + } + impl std::ops::Deref for Static { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl std::ops::DerefMut for Static { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + } + mod unchecked_extrinsic { + //! The "default" Substrate/Polkadot UncheckedExtrinsic. + //! This is used in codegen for runtime API calls. + //! + //! The inner bytes represent the encoded extrinsic expected by the + //! runtime APIs. Deriving `EncodeAsType` would lead to the inner + //! bytes to be re-encoded (length prefixed). + use std::marker::PhantomData; + use codec::{Decode, Encode}; + use scale_decode::{ + visitor::DecodeAsTypeResult, DecodeAsType, IntoVisitor, Visitor, + }; + use super::{Encoded, Static}; + /// The unchecked extrinsic from substrate. + pub struct UncheckedExtrinsic( + Static, + #[codec(skip)] + PhantomData<(Address, Call, Signature, Extra)>, + ); + #[automatically_derived] + impl< + Address: ::core::clone::Clone, + Call: ::core::clone::Clone, + Signature: ::core::clone::Clone, + Extra: ::core::clone::Clone, + > ::core::clone::Clone for UncheckedExtrinsic { + #[inline] + fn clone(&self) -> UncheckedExtrinsic { + UncheckedExtrinsic( + ::core::clone::Clone::clone(&self.0), + ::core::clone::Clone::clone(&self.1), + ) + } + } + #[automatically_derived] + impl< + Address: ::core::fmt::Debug, + Call: ::core::fmt::Debug, + Signature: ::core::fmt::Debug, + Extra: ::core::fmt::Debug, + > ::core::fmt::Debug for UncheckedExtrinsic { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field2_finish( + f, + "UncheckedExtrinsic", + &self.0, + &&self.1, + ) + } + } + #[automatically_derived] + impl< + Address: ::core::cmp::Eq, + Call: ::core::cmp::Eq, + Signature: ::core::cmp::Eq, + Extra: ::core::cmp::Eq, + > ::core::cmp::Eq for UncheckedExtrinsic { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq< + PhantomData<(Address, Call, Signature, Extra)>, + >; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq + for UncheckedExtrinsic {} + #[automatically_derived] + impl< + Address: ::core::cmp::PartialEq, + Call: ::core::cmp::PartialEq, + Signature: ::core::cmp::PartialEq, + Extra: ::core::cmp::PartialEq, + > ::core::cmp::PartialEq + for UncheckedExtrinsic { + #[inline] + fn eq( + &self, + other: &UncheckedExtrinsic, + ) -> bool { + self.0 == other.0 && self.1 == other.1 + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode + for UncheckedExtrinsic { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.0) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.0) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.0, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike + for UncheckedExtrinsic {} + }; + impl< + Address, + Call, + Signature, + Extra, + > UncheckedExtrinsic { + /// Construct a new [`UncheckedExtrinsic`]. + pub fn new(bytes: Vec) -> Self { + Self(Static(Encoded(bytes)), PhantomData) + } + /// Get the bytes of the encoded extrinsic. + pub fn bytes(&self) -> &[u8] { + self.0.0.0.as_slice() + } + } + impl Decode + for UncheckedExtrinsic { + fn decode(input: &mut I) -> Result { + let xt_vec: Vec = Decode::decode(input)?; + Ok(UncheckedExtrinsic::new(xt_vec)) + } + } + impl scale_encode::EncodeAsType + for UncheckedExtrinsic { + fn encode_as_type_to( + &self, + type_id: u32, + types: &scale_info::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + self.0.encode_as_type_to(type_id, types, out) + } + } + impl From> + for UncheckedExtrinsic { + fn from(bytes: Vec) -> Self { + UncheckedExtrinsic::new(bytes) + } + } + impl< + Address, + Call, + Signature, + Extra, + > From> for Vec { + fn from(bytes: UncheckedExtrinsic) -> Self { + bytes.0.0.0 + } + } + pub struct UncheckedExtrinsicDecodeAsTypeVisitor< + Address, + Call, + Signature, + Extra, + >( + PhantomData<(Address, Call, Signature, Extra)>, + ); + impl Visitor + for UncheckedExtrinsicDecodeAsTypeVisitor { + type Value<'scale, 'info> = UncheckedExtrinsic< + Address, + Call, + Signature, + Extra, + >; + type Error = scale_decode::Error; + fn unchecked_decode_as_type<'scale, 'info>( + self, + input: &mut &'scale [u8], + type_id: scale_decode::visitor::TypeId, + types: &'info scale_info::PortableRegistry, + ) -> DecodeAsTypeResult< + Self, + Result, Self::Error>, + > { + DecodeAsTypeResult::Decoded( + Self::Value::decode_as_type(input, type_id.0, types), + ) + } + } + impl IntoVisitor + for UncheckedExtrinsic { + type Visitor = UncheckedExtrinsicDecodeAsTypeVisitor< + Address, + Call, + Signature, + Extra, + >; + fn into_visitor() -> Self::Visitor { + UncheckedExtrinsicDecodeAsTypeVisitor(PhantomData) + } + } + } + mod wrapper_opaque { + use super::PhantomDataSendSync; + use codec::{Compact, Decode, DecodeAll, Encode}; + use derivative::Derivative; + use scale_decode::{IntoVisitor, Visitor}; + use scale_encode::EncodeAsType; + /// A wrapper for any type `T` which implement encode/decode in a way compatible with `Vec`. + /// [`WrapperKeepOpaque`] stores the type only in its opaque format, aka as a `Vec`. To + /// access the real type `T` [`Self::try_decode`] needs to be used. + #[derivative( + Debug(bound = ""), + Clone(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Default(bound = ""), + Hash(bound = "") + )] + pub struct WrapperKeepOpaque { + data: Vec, + _phantom: PhantomDataSendSync, + } + #[allow(unused_qualifications)] + impl ::std::clone::Clone for WrapperKeepOpaque { + fn clone(&self) -> Self { + match *self { + WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { + WrapperKeepOpaque { + data: (*__arg_0).clone(), + _phantom: (*__arg_1).clone(), + } + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for WrapperKeepOpaque { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { + let mut __debug_trait_builder = __f + .debug_struct("WrapperKeepOpaque"); + let _ = __debug_trait_builder.field("data", &&(*__arg_0)); + let _ = __debug_trait_builder.field("_phantom", &&(*__arg_1)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::default::Default for WrapperKeepOpaque { + fn default() -> Self { + WrapperKeepOpaque { + data: ::std::default::Default::default(), + _phantom: ::std::default::Default::default(), + } + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for WrapperKeepOpaque {} + #[allow(unused_qualifications)] + impl ::std::hash::Hash for WrapperKeepOpaque { + fn hash<__HT>(&self, __state: &mut __HT) + where + __HT: ::std::hash::Hasher, + { + match *self { + WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { + ::std::hash::Hash::hash(&(*__arg_0), __state); + ::std::hash::Hash::hash(&(*__arg_1), __state); + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for WrapperKeepOpaque { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + WrapperKeepOpaque { + data: ref __self_0, + _phantom: ref __self_1, + } => { + match *other { + WrapperKeepOpaque { + data: ref __other_0, + _phantom: ref __other_1, + } => { + true && &(*__self_0) == &(*__other_0) + && &(*__self_1) == &(*__other_1) + } + } + } + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for WrapperKeepOpaque + where + PhantomDataSendSync: ::codec::Encode, + PhantomDataSendSync: ::codec::Encode, + { + fn size_hint(&self) -> usize { + 0_usize + .saturating_add(::codec::Encode::size_hint(&self.data)) + .saturating_add(::codec::Encode::size_hint(&self._phantom)) + } + fn encode_to< + __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::codec::Encode::encode_to(&self.data, __codec_dest_edqy); + ::codec::Encode::encode_to(&self._phantom, __codec_dest_edqy); + } + } + #[automatically_derived] + impl ::codec::EncodeLike for WrapperKeepOpaque + where + PhantomDataSendSync: ::codec::Encode, + PhantomDataSendSync: ::codec::Encode, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for WrapperKeepOpaque + where + PhantomDataSendSync: ::codec::Decode, + PhantomDataSendSync: ::codec::Decode, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(WrapperKeepOpaque:: { + data: { + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `WrapperKeepOpaque::data`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + _phantom: { + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `WrapperKeepOpaque::_phantom`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + impl WrapperKeepOpaque { + /// Try to decode the wrapped type from the inner `data`. + /// + /// Returns `None` if the decoding failed. + pub fn try_decode(&self) -> Option + where + T: Decode, + { + T::decode_all(&mut &self.data[..]).ok() + } + /// Returns the length of the encoded `T`. + pub fn encoded_len(&self) -> usize { + self.data.len() + } + /// Returns the encoded data. + pub fn encoded(&self) -> &[u8] { + &self.data + } + /// Create from the given encoded `data`. + pub fn from_encoded(data: Vec) -> Self { + Self { + data, + _phantom: PhantomDataSendSync::new(), + } + } + /// Create from some raw value by encoding it. + pub fn from_value(value: T) -> Self + where + T: Encode, + { + Self { + data: value.encode(), + _phantom: PhantomDataSendSync::new(), + } + } + } + impl EncodeAsType for WrapperKeepOpaque { + fn encode_as_type_to( + &self, + type_id: u32, + types: &scale_info::PortableRegistry, + out: &mut Vec, + ) -> Result<(), scale_encode::Error> { + use scale_encode::error::{Error, ErrorKind, Kind}; + let Some(ty) = types.resolve(type_id) else { + return Err(Error::new(ErrorKind::TypeNotFound(type_id))); + }; + let scale_info::TypeDef::Composite(_) = &ty.type_def else { + return Err( + Error::new(ErrorKind::WrongShape { + actual: Kind::Struct, + expected: type_id, + }), + ); + }; + if ty.path.ident().as_deref() != Some("WrapperKeepOpaque") { + return Err( + Error::new(ErrorKind::WrongShape { + actual: Kind::Struct, + expected: type_id, + }), + ); + } + self.data.encode_to(out); + Ok(()) + } + } + pub struct WrapperKeepOpaqueVisitor(std::marker::PhantomData); + impl Visitor for WrapperKeepOpaqueVisitor { + type Value<'scale, 'info> = WrapperKeepOpaque; + type Error = scale_decode::Error; + fn visit_composite<'scale, 'info>( + self, + value: &mut scale_decode::visitor::types::Composite<'scale, 'info>, + _type_id: scale_decode::visitor::TypeId, + ) -> Result, Self::Error> { + use scale_decode::error::{Error, ErrorKind}; + if value.path().ident().as_deref() != Some("WrapperKeepOpaque") { + return Err( + Error::custom_str( + "Type to decode is not 'WrapperTypeKeepOpaque'", + ), + ); + } + if value.remaining() != 2 { + return Err( + Error::new(ErrorKind::WrongLength { + actual_len: value.remaining(), + expected_len: 2, + }), + ); + } + let Compact(len) = value + .decode_item(Compact::::into_visitor()) + .expect("length checked")?; + let field = value.next().expect("length checked")?; + if field.bytes().len() != len as usize { + return Err( + Error::custom_str( + "WrapperTypeKeepOpaque compact encoded length doesn't line up with encoded byte len", + ), + ); + } + Ok(WrapperKeepOpaque { + data: field.bytes().to_vec(), + _phantom: PhantomDataSendSync::new(), + }) + } + } + impl IntoVisitor for WrapperKeepOpaque { + type Visitor = WrapperKeepOpaqueVisitor; + fn into_visitor() -> Self::Visitor { + WrapperKeepOpaqueVisitor(std::marker::PhantomData) + } + } + } + use crate::error::RpcError; + use crate::Error; + use codec::{Compact, Decode, Encode}; + use derivative::Derivative; + use url::Url; + pub use account_id::AccountId32; + pub use era::Era; + pub use multi_address::MultiAddress; + pub use multi_signature::MultiSignature; + pub use static_type::Static; + pub use unchecked_extrinsic::UncheckedExtrinsic; + pub use wrapper_opaque::WrapperKeepOpaque; + #[doc(hidden)] + pub use primitive_types::{H160, H256, H512}; + /// Wraps an already encoded byte vector, prevents being encoded as a raw byte vector as part of + /// the transaction payload + pub struct Encoded(pub Vec); + #[automatically_derived] + impl ::core::clone::Clone for Encoded { + #[inline] + fn clone(&self) -> Encoded { + Encoded(::core::clone::Clone::clone(&self.0)) + } + } + #[automatically_derived] + impl ::core::fmt::Debug for Encoded { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Encoded", &&self.0) + } + } + #[automatically_derived] + impl ::core::cmp::Eq for Encoded { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq>; + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for Encoded {} + #[automatically_derived] + impl ::core::cmp::PartialEq for Encoded { + #[inline] + fn eq(&self, other: &Encoded) -> bool { + self.0 == other.0 + } + } + impl codec::Encode for Encoded { + fn encode(&self) -> Vec { + self.0.to_owned() + } + } + /// Decodes a compact encoded value from the beginning of the provided bytes, + /// returning the value and any remaining bytes. + pub(crate) fn strip_compact_prefix( + bytes: &[u8], + ) -> Result<(u64, &[u8]), codec::Error> { + let cursor = &mut &*bytes; + let val = >::decode(cursor)?; + Ok((val.0, *cursor)) + } + /// A URL is considered secure if it uses a secure scheme ("https" or "wss") or is referring to localhost. + /// + /// Returns an error if the the string could not be parsed into a URL. + pub fn url_is_secure(url: &str) -> Result { + let url = Url::parse(url) + .map_err(|e| Error::Rpc(RpcError::ClientError(Box::new(e))))?; + let secure_scheme = url.scheme() == "https" || url.scheme() == "wss"; + let is_localhost = url + .host() + .is_some_and(|e| match e { + url::Host::Domain(e) => e == "localhost", + url::Host::Ipv4(e) => e.is_loopback(), + url::Host::Ipv6(e) => e.is_loopback(), + }); + Ok(secure_scheme || is_localhost) + } + /// Validates, that the given Url is secure ("https" or "wss" scheme) or is referring to localhost. + pub fn validate_url_is_secure(url: &str) -> Result<(), Error> { + if !url_is_secure(url)? { + Err(Error::Rpc(crate::error::RpcError::InsecureUrl(url.into()))) + } else { + Ok(()) + } + } + /// A version of [`std::marker::PhantomData`] that is also Send and Sync (which is fine + /// because regardless of the generic param, it is always possible to Send + Sync this + /// 0 size type). + #[derivative( + Clone(bound = ""), + PartialEq(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + Default(bound = ""), + Hash(bound = "") + )] + #[scale_info(skip_type_params(T))] + #[doc(hidden)] + pub struct PhantomDataSendSync(core::marker::PhantomData); + #[allow(unused_qualifications)] + impl ::std::clone::Clone for PhantomDataSendSync { + fn clone(&self) -> Self { + match *self { + PhantomDataSendSync(ref __arg_0) => { + PhantomDataSendSync((*__arg_0).clone()) + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::fmt::Debug for PhantomDataSendSync { + fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + PhantomDataSendSync(ref __arg_0) => { + let mut __debug_trait_builder = __f + .debug_tuple("PhantomDataSendSync"); + let _ = __debug_trait_builder.field(&&(*__arg_0)); + __debug_trait_builder.finish() + } + } + } + } + #[allow(unused_qualifications)] + impl ::std::default::Default for PhantomDataSendSync { + fn default() -> Self { + PhantomDataSendSync(::std::default::Default::default()) + } + } + #[allow(unused_qualifications)] + impl ::std::cmp::Eq for PhantomDataSendSync {} + #[allow(unused_qualifications)] + impl ::std::hash::Hash for PhantomDataSendSync { + fn hash<__HT>(&self, __state: &mut __HT) + where + __HT: ::std::hash::Hasher, + { + match *self { + PhantomDataSendSync(ref __arg_0) => { + ::std::hash::Hash::hash(&(*__arg_0), __state); + } + } + } + } + #[allow(unused_qualifications)] + #[allow(clippy::unneeded_field_pattern)] + impl ::std::cmp::PartialEq for PhantomDataSendSync { + fn eq(&self, other: &Self) -> bool { + true + && match *self { + PhantomDataSendSync(ref __self_0) => { + match *other { + PhantomDataSendSync(ref __other_0) => { + true && &(*__self_0) == &(*__other_0) + } + } + } + } + } + } + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Encode for PhantomDataSendSync + where + core::marker::PhantomData: ::codec::Encode, + core::marker::PhantomData: ::codec::Encode, + { + fn size_hint(&self) -> usize { + ::codec::Encode::size_hint(&&self.0) + } + fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>( + &self, + __codec_dest_edqy: &mut __CodecOutputEdqy, + ) { + ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) + } + fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { + ::codec::Encode::encode(&&self.0) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::codec::Encode::using_encoded(&&self.0, f) + } + } + #[automatically_derived] + impl ::codec::EncodeLike for PhantomDataSendSync + where + core::marker::PhantomData: ::codec::Encode, + core::marker::PhantomData: ::codec::Encode, + {} + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::codec::Decode for PhantomDataSendSync + where + core::marker::PhantomData: ::codec::Decode, + core::marker::PhantomData: ::codec::Decode, + { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok( + PhantomDataSendSync::< + T, + >({ + let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `PhantomDataSendSync.0`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }), + ) + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for PhantomDataSendSync + where + core::marker::PhantomData: ::scale_info::TypeInfo + 'static, + T: 'static, + { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "PhantomDataSendSync", + "subxt::utils", + &[], + ), + ) + .type_params( + <[_]>::into_vec( + #[rustc_box] + ::alloc::boxed::Box::new([ + ::scale_info::TypeParameter::new( + "T", + ::core::option::Option::None, + ), + ]), + ), + ) + .docs( + &[ + "A version of [`std::marker::PhantomData`] that is also Send and Sync (which is fine", + "because regardless of the generic param, it is always possible to Send + Sync this", + "0 size type).", + ], + ) + .composite( + ::scale_info::build::Fields::unnamed() + .field(|f| { + f + .ty::>() + .type_name("core::marker::PhantomData") + }), + ) + } + } + }; + impl PhantomDataSendSync { + pub(crate) fn new() -> Self { + Self(core::marker::PhantomData) + } + } + unsafe impl Send for PhantomDataSendSync {} + unsafe impl Sync for PhantomDataSendSync {} + /// This represents a key-value collection and is SCALE compatible + /// with collections like BTreeMap. This has the same type params + /// as `BTreeMap` which allows us to easily swap the two during codegen. + pub type KeyedVec = Vec<(K, V)>; +} +#[macro_use] +mod macros { + pub(crate) use { + cfg_feature, cfg_jsonrpsee, cfg_reconnecting_rpc_client, cfg_substrate_compat, + cfg_unstable_light_client, + }; + #[allow(unused)] + pub(crate) use {cfg_jsonrpsee_native, cfg_jsonrpsee_web}; +} +pub use crate::{ + client::{OfflineClient, OnlineClient}, + config::{Config, PolkadotConfig, SubstrateConfig}, + error::Error, metadata::Metadata, +}; +/// Re-export external crates that are made use of in the subxt API. +pub mod ext { + pub use codec; + pub use frame_metadata; + pub use futures; + pub use scale_bits; + pub use scale_decode; + pub use scale_encode; + pub use scale_value; +} +/// Generate a strongly typed API for interacting with a Substrate runtime from its metadata. +/// +/// # Metadata +/// +/// First, you'll need to get hold of some metadata for the node you'd like to interact with. One +/// way to do this is by using the `subxt` CLI tool: +/// +/// ```bash +/// # Install the CLI tool: +/// cargo install subxt-cli +/// # Use it to download metadata (in this case, from a node running locally) +/// subxt metadata > polkadot_metadata.scale +/// ``` +/// +/// Run `subxt metadata --help` for more options. +/// +/// # Basic usage +/// +/// Annotate a Rust module with the `subxt` attribute referencing the aforementioned metadata file. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// )] +/// mod polkadot {} +/// ``` +/// +/// The `subxt` macro will populate the annotated module with all of the methods and types required +/// for interacting with the runtime that the metadata is in via Subxt. +/// +/// # Configuration +/// +/// This macro supports a number of attributes to configure what is generated: +/// +/// ## `crate = "..."` +/// +/// Use this attribute to specify a custom path to the `subxt` crate: +/// +/// ```rust +/// # pub extern crate subxt; +/// # pub mod path { pub mod to { pub use subxt; } } +/// # fn main() {} +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// crate = "crate::path::to::subxt" +/// )] +/// mod polkadot {} +/// ``` +/// +/// This is useful if you write a library which uses this macro, but don't want to force users to depend on `subxt` +/// at the top level too. By default the path `::subxt` is used. +/// +/// ## `substitute_type(path = "...", with = "...")` +/// +/// This attribute replaces any reference to the generated type at the path given by `path` with a +/// reference to the path given by `with`. +/// +/// ```rust +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// substitute_type(path = "sp_arithmetic::per_things::Perbill", with = "crate::Foo") +/// )] +/// mod polkadot {} +/// +/// # #[derive( +/// # scale_encode::EncodeAsType, +/// # scale_decode::DecodeAsType, +/// # codec::Encode, +/// # codec::Decode, +/// # Clone, +/// # Debug, +/// # )] +/// // In reality this needs some traits implementing on +/// // it to allow it to be used in place of Perbill: +/// pub struct Foo(u32); +/// # impl codec::CompactAs for Foo { +/// # type As = u32; +/// # fn encode_as(&self) -> &Self::As { +/// # &self.0 +/// # } +/// # fn decode_from(x: Self::As) -> Result { +/// # Ok(Foo(x)) +/// # } +/// # } +/// # impl From> for Foo { +/// # fn from(v: codec::Compact) -> Foo { +/// # v.0 +/// # } +/// # } +/// # fn main() {} +/// ``` +/// +/// If the type you're substituting contains generic parameters, you can "pattern match" on those, and +/// make use of them in the substituted type, like so: +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// substitute_type( +/// path = "sp_runtime::multiaddress::MultiAddress", +/// with = "::subxt::utils::Static<::sp_runtime::MultiAddress>" +/// ) +/// )] +/// mod polkadot {} +/// ``` +/// +/// The above is also an example of using the [`crate::utils::Static`] type to wrap some type which doesn't +/// on it's own implement [`scale_encode::EncodeAsType`] or [`scale_decode::DecodeAsType`], which are required traits +/// for any substitute type to implement by default. +/// +/// ## `derive_for_all_types = "..."` +/// +/// By default, all generated types derive a small set of traits. This attribute allows you to derive additional +/// traits on all generated types: +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// derive_for_all_types = "Eq, PartialEq" +/// )] +/// mod polkadot {} +/// ``` +/// +/// Any substituted types (including the default substitutes) must also implement these traits in order to avoid errors +/// here. +/// +/// ## `derive_for_type(path = "...", derive = "...")` +/// +/// Unlike the above, which derives some trait on every generated type, this attribute allows you to derive traits only +/// for specific types. Note that any types which are used inside the specified type may also need to derive the same traits. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// derive_for_all_types = "Eq, PartialEq", +/// derive_for_type(path = "frame_support::PalletId", derive = "Ord, PartialOrd"), +/// derive_for_type(path = "sp_runtime::ModuleError", derive = "Hash"), +/// )] +/// mod polkadot {} +/// ``` +/// +/// ## `runtime_metadata_insecure_url = "..."` +/// +/// This attribute can be used instead of `runtime_metadata_path` and will tell the macro to download metadata from a node running +/// at the provided URL, rather than a node running locally. This can be useful in CI, but is **not recommended** in production code, +/// since it runs at compile time and will cause compilation to fail if the node at the given address is unavailable or unresponsive. +/// +/// ```rust,ignore +/// #[subxt::subxt( +/// runtime_metadata_insecure_url = "wss://rpc.polkadot.io:443" +/// )] +/// mod polkadot {} +/// ``` +/// +/// ## `generate_docs` +/// +/// By default, documentation is not generated via the macro, since IDEs do not typically make use of it. This attribute +/// forces documentation to be generated, too. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// generate_docs +/// )] +/// mod polkadot {} +/// ``` +/// +/// ## `runtime_types_only` +/// +/// By default, the macro will generate various interfaces to make using Subxt simpler in addition with any types that need +/// generating to make this possible. This attribute makes the codegen only generate the types and not the Subxt interface. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// runtime_types_only +/// )] +/// mod polkadot {} +/// ``` +/// +/// ## `no_default_derives` +/// +/// By default, the macro will add all derives necessary for the generated code to play nicely with Subxt. Adding this attribute +/// removes all default derives. +/// +/// ```rust,no_run +/// #[subxt::subxt( +/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", +/// runtime_types_only, +/// no_default_derives, +/// derive_for_all_types="codec::Encode, codec::Decode" +/// )] +/// mod polkadot {} +/// ``` +/// +/// **Note**: At the moment, you must derive at least one of `codec::Encode` or `codec::Decode` or `scale_encode::EncodeAsType` or +/// `scale_decode::DecodeAsType` (because we add `#[codec(..)]` attributes on some fields/types during codegen), and you must use this +/// feature in conjunction with `runtime_types_only` (or manually specify a bunch of defaults to make codegen work properly when +/// generating the subxt interfaces). +/// +/// ## `unstable_metadata` +/// +/// This attribute works only in combination with `runtime_metadata_insecure_url`. By default, the macro will fetch the latest stable +/// version of the metadata from the target node. This attribute makes the codegen attempt to fetch the unstable version of +/// the metadata first. This is **not recommended** in production code, since the unstable metadata a node is providing is likely +/// to be incompatible with Subxt. +/// +/// ```rust,ignore +/// #[subxt::subxt( +/// runtime_metadata_insecure_url = "wss://rpc.polkadot.io:443", +/// unstable_metadata +/// )] +/// mod polkadot {} +/// ``` +pub use subxt_macro::subxt; diff --git a/subxt/src/error/mod.rs b/subxt/src/error/mod.rs index a0bafaff8a..65b8ffaa57 100644 --- a/subxt/src/error/mod.rs +++ b/subxt/src/error/mod.rs @@ -14,6 +14,7 @@ crate::macros::cfg_unstable_light_client! { pub use dispatch_error::{ ArithmeticError, DispatchError, ModuleError, TokenError, TransactionalError, }; +use subxt_metadata::StorageHasher; // Re-expose the errors we use from other crates here: pub use crate::config::ExtrinsicParamsError; @@ -209,6 +210,16 @@ pub enum StorageAddressError { /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. #[error("Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata.")] UnexpectedAddressBytes, + /// An invalid hasher was used to reconstruct a value from a chunk of bytes that is part of a storage address. Hashers where the hash does not contain the original value are invalid for this purpose. + #[error("An invalid hasher was used to reconstruct a value of type {ty_name} (id={ty_id}) from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher")] + HasherCannotReconstructKey { + /// Type id of the key's type. + ty_id: u32, + /// Type name of the key's type. + ty_name: String, + /// The invalid hasher that caused this error. + hasher: StorageHasher, + }, } /// Something went wrong trying to access details in the metadata. diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 6a924dc2d7..20e9cab325 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -192,7 +192,7 @@ where .ok_or_else(|| MetadataError::StorageEntryNotFound(self.entry_name().to_owned()))?; let keys_iter = self.keys.keys_iter(); - let keys_len = keys_iter.len(); + let keys_len = self.keys.keys_len(); if keys_len == 0 { return Ok(()); diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 3eed4c1d57..ef656073a5 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -1,6 +1,8 @@ use super::{ storage_address::StaticStorageKey, - utils::{strip_concat_hash_bytes, strip_storage_addess_root_bytes}, + utils::{ + hash_contains_unhashed_value, strip_storage_hash_bytes, + }, }; use crate::{ dynamic::DecodedValueThunk, @@ -15,148 +17,167 @@ use subxt_metadata::StorageHasher; pub trait StorageKey { /// Iterator over the storage keys, each key implements EncodeAsType to /// give the corresponding bytes to a `StorageHasher`. - fn keys_iter(&self) -> impl ExactSizeIterator; + fn keys_iter(&self) -> impl Iterator; - /// Attempts to decode the StorageKey from a whole storage address. - /// The key/keys can only be recovered if all hashers are concat-style hashers. + /// How many keys are there in total? Each key is an element that needs to be individually hashed. + // Note: Ideally we would use `impl ExactSizeIterator` for `keys_iter` above, + // But that plays poorly with the `Flatten` and `Chain` structs. + fn keys_len(&self) -> usize; + + /// Attempts to decode the StorageKey from a storage address that has been stripped of its root bytes. + /// /// Example: Imagine The `StorageKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. - /// Then the memory layout of the storage key is: + /// Then the memory layout of the storage address is: /// ```txt /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | /// ``` - /// Returns None, if any of the hashers is not a concat-style hasher. - fn decode_from_address_bytes( - address_bytes: &[u8], - hashers_and_ty_ids: &[(StorageHasher, u32)], + /// `cursor` should point into a region after those first 16 bytes, at the start of a new hash. + /// `hashers_and_ty_ids` should consume all the hashers that have been used for decoding, such that there are less hashers coming to the next key. + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], metadata: &Metadata, - ) -> Option> + ) -> Result where Self: Sized + 'static; } -/// Implement `StorageKey` for `()` which can be used for keyless storage entries +/// Implement `StorageKey` for `()` which can be used for keyless storage entries. impl StorageKey for () { - fn keys_iter(&self) -> impl ExactSizeIterator { - // Note: this returns the storage root address of the storage entry. - // It gives the same result as if you were to use `vec![]` as a `StorageKey`. + fn keys_iter(&self) -> impl Iterator { std::iter::empty() } - fn decode_from_address_bytes( - address_bytes: &[u8], - _hashers_and_ty_ids: &[(StorageHasher, u32)], + fn keys_len(&self) -> usize { + 0 + } + + fn decode_from_bytes( + _cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], _metadata: &Metadata, - ) -> Option> { - // We need at least 16 bytes, becauase there are 8 bytes for the pallet hash and - // another 8 bytes for the entry hash at the beginning of each storage address. - if address_bytes.len() < 16 { - return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); + ) -> Result { + if hashers_and_ty_ids.is_empty() { + return Err(StorageAddressError::WrongNumberOfHashers { + hashers: 0, + fields: 1, + } + .into()); } - Some(Ok(())) + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; // Advance cursor by 1 + Ok(()) } } // Note: The ?Sized bound is necessary to support e.g. `StorageKey<[u8]>`. impl StorageKey for StaticStorageKey { - fn keys_iter(&self) -> impl ExactSizeIterator { - // Note: this returns the storage root address of the storage entry. - // It gives the same result as if you were to use `vec![]` as a `StorageKey`. + fn keys_iter(&self) -> impl Iterator { std::iter::once(&self.bytes as &dyn EncodeAsType) } - fn decode_from_address_bytes( - address_bytes: &[u8], - hashers_and_ty_ids: &[(StorageHasher, u32)], + fn keys_len(&self) -> usize { + 1 + } + + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], metadata: &Metadata, - ) -> Option> + ) -> Result where Self: Sized + 'static, { - let cursor = &mut &*address_bytes; - if let Err(err) = strip_storage_addess_root_bytes(cursor) { - return Some(Err(err.into())); - } - let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { - return Some(Err(StorageAddressError::WrongNumberOfHashers { + return Err(StorageAddressError::WrongNumberOfHashers { hashers: 0, fields: 1, } - .into())); + .into()); }; - decode_storage_key_from_hash(address_bytes, cursor, hasher, *ty_id, metadata) + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; // Advance cursor by 1 + decode_storage_key_from_hash(cursor, hasher, *ty_id, metadata) } } pub fn decode_storage_key_from_hash( - address_bytes: &[u8], cursor: &mut &[u8], hasher: &StorageHasher, ty_id: u32, metadata: &Metadata, -) -> Option, Error>> { - if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { - return Some(Err(err.into())); - } - let start_idx = address_bytes.len() - cursor.len(); +) -> Result, Error> { + strip_storage_hash_bytes(cursor, hasher)?; + + let bytes = *cursor; if let Err(err) = scale_decode::visitor::decode_with_visitor( cursor, ty_id, metadata.types(), scale_decode::visitor::IgnoreVisitor, ) { - return Some(Err(scale_decode::Error::from(err).into())); + return Err(scale_decode::Error::from(err).into()); } - let end_idx = address_bytes.len() - cursor.len(); - let key_bytes = address_bytes[start_idx..end_idx].to_vec(); + let bytes_decoded = bytes.len() - cursor.len(); + + // Note: This validation check makes sure, only zero-sized types can be decoded from + // hashers that do not support reconstruction of a value + if !hash_contains_unhashed_value(hasher) && bytes_decoded > 0 { + let ty_name = metadata + .types() + .resolve(ty_id) + .expect("ty_id is in metadata, because decode_with_visitor did not fail above; qed") + .path + .to_string(); + return Err(StorageAddressError::HasherCannotReconstructKey { + ty_id, + ty_name, + hasher: *hasher, + } + .into()); + }; + + let key_bytes = bytes[..bytes_decoded].to_vec(); let key = StaticStorageKey { bytes: Static(Encoded(key_bytes)), _marker: std::marker::PhantomData::, }; - Some(Ok(key)) + Ok(key) } impl StorageKey for Vec { - fn keys_iter(&self) -> impl ExactSizeIterator { + fn keys_iter(&self) -> impl Iterator { // Note: this returns the storage root address of the storage entry. // It gives the same result as if you were to use `vec![]` as a `StorageKey`. self.iter().map(|e| e as &dyn EncodeAsType) } - fn decode_from_address_bytes( - address_bytes: &[u8], - hashers_and_ty_ids: &[(StorageHasher, u32)], + fn keys_len(&self) -> usize { + self.len() + } + + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], metadata: &Metadata, - ) -> Option> + ) -> Result where Self: Sized + 'static, { - let cursor = &mut &*address_bytes; - if let Err(err) = strip_storage_addess_root_bytes(cursor) { - return Some(Err(err.into())); - } let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); - let mut result: Vec = vec![]; + let mut n = 0; while !cursor.is_empty() { let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { // Still bytes left, but no hashers and type ids anymore to pull from: this is an unexpected error. - return Some(Err(StorageAddressError::UnexpectedAddressBytes.into())); + return Err(StorageAddressError::UnexpectedAddressBytes.into()); }; - if let Err(err) = strip_concat_hash_bytes(cursor, hasher)? { - return Some(Err(err.into())); - } - match DecodedValueThunk::decode_with_metadata(cursor, *ty_id, metadata) { - Ok(decoded) => { - match decoded.to_value() { - Ok(value) => result.push(value.remove_context()), - Err(err) => return Some(Err(err)), - }; - } - Err(err) => return Some(Err(err)), - } + strip_storage_hash_bytes(cursor, hasher)?; + let decoded = DecodedValueThunk::decode_with_metadata(cursor, *ty_id, metadata)?; + let value = decoded.to_value()?; + result.push(value.remove_context()); + n += 1; } - Some(Ok(result)) + *hashers_and_ty_ids = &hashers_and_ty_ids[n..]; // Advance cursor by n + Ok(result) } } @@ -170,51 +191,54 @@ impl StorageKey for Vec { /// } /// ``` macro_rules! impl_tuples { - ($($ty:ident $n:tt),+) => {{ - impl<$($ty: EncodeAsType + ?Sized),+> StorageKey for ($( StaticStorageKey<$ty >),+) { - fn keys_iter(&self) -> impl ExactSizeIterator { - let arr = [$( - &self.$n.bytes as &dyn EncodeAsType - ),+]; - arr.into_iter() + ($($ty:ident $iter:ident $n:tt),+) => {{ + impl<$($ty: StorageKey),+> StorageKey for ($( $ty ),+) { + fn keys_iter(&self) -> impl Iterator { + + $( + let mut $iter = self.$n.keys_iter(); + )+ + + std::iter::from_fn(move || { + let mut i = 0; + loop { + match i { + $( + $n => { + let el = $iter.next(); + if el.is_some(){ + return el; + } + }, + )+ + _ => return None, + }; + i+=1; + } + }) + } + + fn keys_len(&self) -> usize { + $((self.$n.keys_len())+)+0 } - fn decode_from_address_bytes( - address_bytes: &[u8], - hashers_and_ty_ids: &[(StorageHasher, u32)], + fn decode_from_bytes( + cursor: &mut &[u8], + hashers_and_ty_ids: &mut &[(StorageHasher, u32)], metadata: &Metadata, - ) -> Option> + ) -> Result where Self: Sized + 'static, { - let cursor = &mut &*address_bytes; - if let Err(err) = strip_storage_addess_root_bytes(cursor) { - return Some(Err(err.into())); - } - - // The number of elements in this tuple. - const LEN: usize = $((0*$n + 1)+)+0; - - // It is an error to not provide a hasher and type id for each element in this tuple. - if hashers_and_ty_ids.len() < LEN { - return Some(Err(StorageAddressError::WrongNumberOfKeys{actual: hashers_and_ty_ids.len(), expected: LEN}.into())) - } - // Construct the tuple as a series of expressions. let tuple : Self = ( $( { - // index is available, because of bounds check above; qed - let (hasher, ty_id) = &hashers_and_ty_ids[$n]; - let key = match decode_storage_key_from_hash::<$ty>(address_bytes, cursor, hasher, *ty_id, metadata)? { - Ok(key) => key, - Err(err) => { - return Some(Err(err)); - } - }; + let key = + $ty::decode_from_bytes(cursor, hashers_and_ty_ids, metadata)?; key }, )+); - return Some(Ok(tuple)) + return Ok(tuple) } } }}; @@ -222,11 +246,11 @@ macro_rules! impl_tuples { #[rustfmt::skip] const _: () = { - impl_tuples!(A 0, B 1); - impl_tuples!(A 0, B 1, C 2); - impl_tuples!(A 0, B 1, C 2, D 3); - impl_tuples!(A 0, B 1, C 2, D 3, E 4); - impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5); - impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6); - impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7); + impl_tuples!(A iter_a 0, B iter_ab 1); + impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2); + impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3); + impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3, E iter_e 4); + impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5); + impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6); + impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6, H iter_h 7); }; diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index eeed7e4d34..20650a817e 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -3,6 +3,7 @@ // see LICENSE for license details. use super::storage_address::{StorageAddress, Yes}; +use super::utils::strip_storage_addess_root_bytes; use super::StorageKey; use crate::{ @@ -254,12 +255,13 @@ where )?; let key_bytes = kv.key; - let keys = ::decode_from_address_bytes( - &key_bytes, - &hasher_type_id_pairs, + let cursor = &mut &key_bytes[..]; + strip_storage_addess_root_bytes(cursor)?; + let keys = ::decode_from_bytes( + cursor, + &mut &hasher_type_id_pairs[..], &metadata, - ) - .transpose()?; + )?; Ok(StorageKeyValuePair::
{ keys, key_bytes, @@ -362,7 +364,7 @@ pub struct StorageKeyValuePair { /// The bytes that make up the address of the storage entry. pub key_bytes: Vec, /// The keys that can be used to construct the address of this storage entry. - pub keys: Option, + pub keys: T::Keys, /// The value of the storage entry. pub value: T::Target, } diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index faa2e30efa..332713e477 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -55,35 +55,39 @@ pub(crate) fn strip_storage_addess_root_bytes( } } -/// Strips the first few bytes off a hash produced by a concat hasher. -/// Returns None(..) if the hasher provided is not a concat hasher. -/// Returns Some(Err(..)) if there are not enough bytes. -/// Returns Some(Ok(..)) if the stripping was successful. -pub fn strip_concat_hash_bytes( +/// Strips the first few bytes off a hash to possibly skip to the plan key value, +/// if [`hash_contains_unhashed_value()`] for this StorageHasher. +/// +/// Returns `Err(..)` if there are not enough bytes. +/// Returns `Ok(())` otherwise +pub fn strip_storage_hash_bytes( hash: &mut &[u8], hasher: &StorageHasher, -) -> Option> { - match hasher { - StorageHasher::Blake2_128Concat => { - if hash.len() >= 16 { - *hash = &hash[16..]; - Some(Ok(())) - } else { - Some(Err(StorageAddressError::UnexpectedAddressBytes)) - } - } - StorageHasher::Twox64Concat => { - if hash.len() >= 8 { - *hash = &hash[8..]; - Some(Ok(())) - } else { - Some(Err(StorageAddressError::UnexpectedAddressBytes)) - } - } - StorageHasher::Blake2_128 - | StorageHasher::Blake2_256 - | StorageHasher::Twox128 - | StorageHasher::Twox256 - | StorageHasher::Identity => None, +) -> Result<(), StorageAddressError> { + let bytes_to_strip = match hasher { + StorageHasher::Blake2_128Concat => 16, + StorageHasher::Twox64Concat => 8, + StorageHasher::Blake2_128 => 16, + StorageHasher::Blake2_256 => 32, + StorageHasher::Twox128 => 16, + StorageHasher::Twox256 => 32, + StorageHasher::Identity => 0, + }; + + if hash.len() < bytes_to_strip { + return Err(StorageAddressError::UnexpectedAddressBytes); } + + *hash = &hash[bytes_to_strip..]; + Ok(()) +} + +/// This value is contained within the hash for concat-stle hashers +/// ([`StorageHasher::Identity`] or [`StorageHasher::Identity`]) and the +/// identity hash function ([`StorageHasher::Identity`]). +pub fn hash_contains_unhashed_value(hasher: &StorageHasher) -> bool { + matches!( + hasher, + StorageHasher::Blake2_128Concat | StorageHasher::Twox64Concat | StorageHasher::Identity + ) } From e87eb3c1e6ce62f99c13cab9fd1fc352552d9a5d Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Mon, 26 Feb 2024 10:55:04 +0100 Subject: [PATCH 22/39] refactor codegen --- codegen/src/api/storage.rs | 88 +- codegen/src/error.rs | 10 + metadata/src/lib.rs | 31 + subxt/expand.rs | 44181 ----------------------------- subxt/expand.txt | 44181 ----------------------------- subxt/src/storage/storage_key.rs | 5 +- subxt/src/storage/utils.rs | 12 +- 7 files changed, 110 insertions(+), 88398 deletions(-) delete mode 100644 subxt/expand.rs delete mode 100644 subxt/expand.txt diff --git a/codegen/src/api/storage.rs b/codegen/src/api/storage.rs index 60860a8cb8..1329b46928 100644 --- a/codegen/src/api/storage.rs +++ b/codegen/src/api/storage.rs @@ -8,7 +8,7 @@ use quote::{format_ident, quote}; use scale_info::TypeDef; use scale_typegen::{typegen::type_path::TypePath, TypeGenerator}; use subxt_metadata::{ - PalletMetadata, StorageEntryMetadata, StorageEntryModifier, StorageEntryType, + PalletMetadata, StorageEntryMetadata, StorageEntryModifier, StorageEntryType, StorageHasher, }; use super::CodegenError; @@ -75,8 +75,15 @@ fn generate_storage_entry_fns( let alias_module_name = format_ident!("{snake_case_name}"); let alias_storage_path = quote!( types::#alias_module_name::#alias_name ); - let storage_entry_map = |idx, id| { - let ident: Ident = format_ident!("_{}", idx); + struct MapEntryKey { + arg_name: Ident, + alias_type_def: TokenStream, + alias_type_path: TokenStream, + hasher: StorageHasher, + } + + let map_entry_key = |idx, id, hasher| -> MapEntryKey { + let arg_name: Ident = format_ident!("_{}", idx); let ty_path = type_gen .resolve_type_path(id) .expect("type is in metadata; qed"); @@ -84,34 +91,67 @@ fn generate_storage_entry_fns( let alias_name = format_ident!("Param{}", idx); let alias_type = primitive_type_alias(&ty_path); - let alias_type = quote!( pub type #alias_name = #alias_type; ); - let path_to_alias = quote!( types::#alias_module_name::#alias_name ); + let alias_type_def = quote!( pub type #alias_name = #alias_type; ); + let alias_type_path = quote!( types::#alias_module_name::#alias_name ); - (ident, alias_type, path_to_alias) + MapEntryKey { + arg_name, + alias_type_def, + alias_type_path, + hasher, + } }; - let keys: Vec<(Ident, TokenStream, TokenStream)> = match storage_entry.entry_type() { + let keys: Vec = match storage_entry.entry_type() { StorageEntryType::Plain(_) => vec![], - StorageEntryType::Map { key_ty, .. } => { + StorageEntryType::Map { + key_ty, hashers, .. + } => { match &type_gen .resolve_type(*key_ty) .expect("key type should be present") .type_def { // An N-map; return each of the keys separately. - TypeDef::Tuple(tuple) => tuple - .fields - .iter() - .enumerate() - .map(|(idx, f)| storage_entry_map(idx, f.id)) - .collect::>(), + TypeDef::Tuple(tuple) => { + let key_count = tuple.fields.len(); + let hasher_count = hashers.len(); + if hasher_count != 1 && hasher_count != key_count { + return Err(CodegenError::InvalidStorageHasherCount { + storage_entry_name: storage_entry.name().to_owned(), + key_count, + hasher_count, + }); + } + + let mut map_entry_keys: Vec = vec![]; + for (idx, field) in tuple.fields.iter().enumerate() { + // Note: these are in bounds because of the checks above, qed; + let hasher = if idx >= hasher_count { + hashers[0] + } else { + hashers[idx] + }; + map_entry_keys.push(map_entry_key(idx, field.id, hasher)); + } + map_entry_keys + } // A map with a single key; return the single key. _ => { - vec![storage_entry_map(0, *key_ty)] + let Some(hasher) = hashers.first() else { + return Err(CodegenError::InvalidStorageHasherCount { + storage_entry_name: storage_entry.name().to_owned(), + key_count: 1, + hasher_count: 0, + }); + }; + + vec![map_entry_key(0, *key_ty, *hasher)] } } } }; + let pallet_name = pallet.name(); let storage_name = storage_entry.name(); let Some(storage_hash) = pallet.storage_hash(storage_name) else { @@ -151,23 +191,23 @@ fn generate_storage_entry_fns( let (keys, keys_type) = match keys_slice.len(){ 0 => (quote!( () ), quote!( () )), 1 => { - let field_name = &keys_slice[0].0; - let keys = quote!( #crate_path::storage::address::StaticStorageKey::new(#field_name.borrow()) ); - let path = &keys_slice[0].2; + let arg_name = &keys_slice[0].arg_name; + let keys = quote!( #crate_path::storage::address::StaticStorageKey::new(#arg_name.borrow()) ); + let path = &keys_slice[0].alias_type_path; let path = quote!( #crate_path::storage::address::StaticStorageKey<#path> ); (keys, path) } _ => { - let keys_iter = keys_slice.iter().map(|(field_name, _, _)| quote!( #crate_path::storage::address::StaticStorageKey::new(#field_name.borrow()) )); + let keys_iter = keys_slice.iter().map(|MapEntryKey{arg_name, ..}| quote!( #crate_path::storage::address::StaticStorageKey::new(#arg_name.borrow()) )); let keys = quote!( (#(#keys_iter,)*) ); - let paths_iter = keys_slice.iter().map(|(_, _, path_to_alias)| quote!( #crate_path::storage::address::StaticStorageKey<#path_to_alias> ) ); + let paths_iter = keys_slice.iter().map(|MapEntryKey{alias_type_path, ..}| quote!( #crate_path::storage::address::StaticStorageKey<#alias_type_path> ) ); let paths = quote!( (#(#paths_iter,)*) ); (keys, paths) } }; - let key_args = keys_slice.iter().map(|(field_name, _, path_to_alias )| { - quote!( #field_name: impl ::std::borrow::Borrow<#path_to_alias> ) + let key_args = keys_slice.iter().map(|MapEntryKey{arg_name, alias_type_path, ..}| { + quote!( #arg_name: impl ::std::borrow::Borrow<#alias_type_path> ) }); quote!( @@ -192,7 +232,9 @@ fn generate_storage_entry_fns( ) }); - let alias_types = keys.iter().map(|(_, alias_type, _)| alias_type); + let alias_types = keys + .iter() + .map(|MapEntryKey { alias_type_def, .. }| alias_type_def); let types_mod_ident = type_gen.types_mod_ident(); // Generate type alias for the return type only, since diff --git a/codegen/src/error.rs b/codegen/src/error.rs index cb95354a20..1414961cf6 100644 --- a/codegen/src/error.rs +++ b/codegen/src/error.rs @@ -48,6 +48,16 @@ pub enum CodegenError { "Extrinsic call type could not be found. Make sure you are providing a valid substrate-based metadata" )] MissingCallType, + /// There are too many or too few hashers. + #[error("Could not Generate functions for storage entry {storage_entry_name}. There are {key_count} keys, but only {hasher_count} hashers. The number of hashers must equal the number of keys or be exactly 1.")] + InvalidStorageHasherCount { + /// The name of the storage entry + storage_entry_name: String, + /// Number of keys + key_count: usize, + /// Number of hashers + hasher_count: usize, + }, /// Cannot generate types. #[error("Type Generation failed: {0}")] TypeGeneration(#[from] TypegenError), diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 59a3ba484b..0b5db7277c 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -475,6 +475,37 @@ pub enum StorageHasher { Identity, } +impl StorageHasher { + /// The hash produced by a [`StorageHasher`] has 1 or 2 of the following components: + /// 1. A fixed size hash. (not present for [`StorageHasher::Identity`]) + /// 2. The key that was used as an input to the hasher. (only present for + /// [`StorageHasher::Twox64Concat`], [`StorageHasher::Blake2_128Concat`] or [`StorageHasher::Identity`]). + /// + /// This function returns the number of hash bytes that must be skipped to get to the 2. component, the unhashed key. + /// To check whether or not an unhashed key is contained, see [`StorageHasher::hash_bytes_before_unhashed_key`]. + pub fn hash_bytes_before_unhashed_key(&self) -> usize { + match self { + StorageHasher::Blake2_128Concat => 16, + StorageHasher::Twox64Concat => 8, + StorageHasher::Blake2_128 => 16, + StorageHasher::Blake2_256 => 32, + StorageHasher::Twox128 => 16, + StorageHasher::Twox256 => 32, + StorageHasher::Identity => 0, + } + } + + /// Returns if the key a hash was produces for, is contained in the hash itself. + /// If this is `true`, [`StorageHasher::hash_bytes_before_unhashed_key`] can be used, + /// to find the offset of the start byte of the key from the start of the hash bytes. + pub fn hash_contains_unhashed_key(&self) -> bool { + matches!( + self, + StorageHasher::Blake2_128Concat | StorageHasher::Twox64Concat | StorageHasher::Identity + ) + } +} + /// Is the storage entry optional, or does it have a default value. #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum StorageEntryModifier { diff --git a/subxt/expand.rs b/subxt/expand.rs deleted file mode 100644 index e3eef50a0a..0000000000 --- a/subxt/expand.rs +++ /dev/null @@ -1,44181 +0,0 @@ -#![feature(prelude_import)] -//! Subxt is a library for interacting with Substrate based nodes. Using it looks something like this: -//! -//! ```rust,ignore -/*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let from = dev::alice(); - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} -*/ -//! ``` -//! -//! Take a look at [the Subxt guide](book) to learn more about how to use Subxt. -#[prelude_import] -use std::prelude::rust_2021::*; -#[macro_use] -extern crate std; -pub mod book { - //! # The Subxt Guide - //! - //! Subxt is a library for interacting with Substrate based nodes. It has a focus on **sub**mitting - //! e**xt**rinsics, hence the name, however it's also capable of reading blocks, storage, events and - //! constants from a node. The aim of this guide is to explain key concepts and get you started with - //! using Subxt. - //! - //! 1. [Features](#features-at-a-glance) - //! 2. [Limitations](#limitations) - //! 3. [Quick start](#quick-start) - //! 4. [Usage](#usage) - //! - //! ## Features at a glance - //! - //! Here's a quick overview of the features that Subxt has to offer: - //! - //! - Subxt allows you to generate a static, type safe interface to a node given some metadata; this - //! allows you to catch many errors at compile time rather than runtime. - //! - Subxt also makes heavy use of node metadata to encode/decode the data sent to/from it. This - //! allows it to target almost any node which can output the correct metadata, and allows it some - //! flexibility in encoding and decoding things to account for cross-node differences. - //! - Subxt has a pallet-oriented interface, meaning that code you write to talk to some pallet on - //! one node will often "Just Work" when pointed at different nodes that use the same pallet. - //! - Subxt can work offline; you can generate and sign transactions, access constants from node - //! metadata and more, without a network connection. This is all checked at compile time, so you - //! can be certain it won't try to establish a network connection if you don't want it to. - //! - Subxt can forego the statically generated interface and build transactions, storage queries - //! and constant queries using data provided at runtime, rather than queries constructed - //! statically. - //! - Subxt can be compiled to WASM to run in the browser, allowing it to back Rust based browser - //! apps, or even bind to JS apps. - //! - //! ## Limitations - //! - //! In various places, you can provide a block hash to access data at a particular block, for - //! instance: - //! - //! - [`crate::storage::StorageClient::at`] - //! - [`crate::events::EventsClient::at`] - //! - [`crate::blocks::BlocksClient::at`] - //! - [`crate::runtime_api::RuntimeApiClient::at`] - //! - //! However, Subxt is (by default) only capable of properly working with blocks that were produced - //! after the most recent runtime update. This is because it uses the most recent metadata given - //! back by a node to encode and decode things. It's possible to decode older blocks produced by a - //! runtime that emits compatible (currently, V14) metadata by manually setting the metadata used by - //! the client using [`crate::client::OnlineClient::set_metadata()`]. - //! - //! Subxt does not support working with blocks produced prior to the runtime update that introduces - //! V14 metadata. It may have some success decoding older blocks using newer metadata, but may also - //! completely fail to do so. - //! - //! ## Quick start - //! - //! Here is a simple but complete example of using Subxt to transfer some tokens from the example - //! accounts, Alice to Bob: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let from = dev::alice(); - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} -*/ - //! ``` - //! - //! This example assumes that a Polkadot node is running locally (Subxt endeavors to support all - //! recent releases). Typically, to use Subxt to talk to some custom Substrate node (for example a - //! parachain node), you'll want to: - //! - //! 1. [Generate an interface](setup::codegen) - //! 2. [Create a config](setup::config) - //! 3. [Use the config to instantiate the client](setup::client) - //! - //! Follow the above links to learn more about each step. - //! - //! ## Usage - //! - //! Once Subxt is configured, the next step is interacting with a node. Follow the links - //! below to learn more about how to use Subxt for each of the following things: - //! - //! - [Transactions](usage::transactions): Subxt can build and submit transactions, wait until they are in - //! blocks, and retrieve the associated events. - //! - [Storage](usage::storage): Subxt can query the node storage. - //! - [Events](usage::events): Subxt can read the events emitted for recent blocks. - //! - [Constants](usage::constants): Subxt can access the constant values stored in a node, which - //! remain the same for a given runtime version. - //! - [Blocks](usage::blocks): Subxt can load recent blocks or subscribe to new/finalized blocks, - //! reading the extrinsics, events and storage at these blocks. - //! - [Runtime APIs](usage::runtime_apis): Subxt can make calls into pallet runtime APIs to retrieve - //! data. - //! - [Custom values](usage::custom_values): Subxt can access "custom values" stored in the metadata. - //! - [Raw RPC calls](usage::rpc): Subxt can be used to make raw RPC requests to compatible nodes. - //! - //! ## Examples - //! - //! Some complete, self contained examples which are not a part of this guide: - //! - //! - [`parachain-example`](https://github.com/paritytech/subxt/tree/master/examples/parachain-example) is an example - //! which uses Zombienet to spawn a parachain locally, and then connects to it using Subxt. - //! - [`wasm-example`](https://github.com/paritytech/subxt/tree/master/examples/wasm-example) is an example of writing - //! a Rust app that contains a Yew based UI, uses Subxt to interact with a chain, and compiles to WASM in order to - //! run entirely in the browser. - pub mod setup { - //! This modules contains details on setting up Subxt: - //! - //! - [Codegen](codegen) - //! - [Client](client) - //! - //! Alternately, [go back](super). - pub mod client { - //! # The Subxt client. - //! - //! The client forms the entry point to all of the Subxt APIs. Every client implements one or - //! both of [`crate::client::OfflineClientT`] and [`crate::client::OnlineClientT`]. - //! - //! Subxt ships with three clients which implement one or both of traits: - //! - An [online client](crate::client::OnlineClient). - //! - An [offline client](crate::client::OfflineClient). - //! - A light client (which is currently still unstable). - //! - //! In theory it's possible for users to implement their own clients, although this isn't generally - //! expected. - //! - //! The provided clients are all generic over the [`crate::config::Config`] that they accept, which - //! determines how they will interact with the chain. - //! - //! In the case of the [`crate::OnlineClient`], we have various ways to instantiate it: - //! - //! - [`crate::OnlineClient::new()`] to connect to a node running locally. This uses the default Subxt - //! backend, and the default RPC client. - //! - [`crate::OnlineClient::from_url()`] to connect to a node at a specific URL. This uses the default Subxt - //! backend, and the default RPC client. - //! - [`crate::OnlineClient::from_rpc_client()`] to instantiate the client with a [`crate::backend::rpc::RpcClient`]. - //! - [`crate::OnlineClient::from_backend()`] to instantiate Subxt using a custom backend. Currently there - //! is just one backend, [`crate::backend::legacy::LegacyBackend`]. This backend can be instantiated from - //! a [`crate::backend::rpc::RpcClient`]. - //! - //! [`crate::backend::rpc::RpcClient`] can itself be instantiated from anything that implements the low level - //! [`crate::backend::rpc::RpcClientT`] trait; this allows you to decide how Subxt will attempt to talk to a node - //! if you'd prefer something other default client. We use this approach under the hood to implement the light client. - //! - //! ## Examples - //! - //! Most of the other examples will instantiate a client. Here are a couple of examples for less common - //! cases. - //! - //! ### Writing a custom [`crate::backend::rpc::RpcClientT`] implementation: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use std::{ - fmt::Write, - pin::Pin, - sync::{Arc, Mutex}, -}; -use subxt::{ - backend::rpc::{RawRpcFuture, RawRpcSubscription, RawValue, RpcClient, RpcClientT}, - OnlineClient, PolkadotConfig, -}; - -// A dummy RPC client that doesn't actually handle requests properly -// at all, but instead just logs what requests to it were made. -struct MyLoggingClient { - log: Arc>, -} - -// We have to implement this fairly low level trait to turn [`MyLoggingClient`] -// into an RPC client that we can make use of in Subxt. Here we just log the requests -// made but don't forward them to any real node, and instead just return nonsense. -impl RpcClientT for MyLoggingClient { - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box> { - writeln!( - self.log.lock().unwrap(), - "{method}({})", - params.as_ref().map(|p| p.get()).unwrap_or("[]") - ) - .unwrap(); - - // We've logged the request; just return garbage. Because a boxed future is returned, - // you're able to run whatever async code you'd need to actually talk to a node. - let res = RawValue::from_string("[]".to_string()).unwrap(); - Box::pin(std::future::ready(Ok(res))) - } - - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription> { - writeln!( - self.log.lock().unwrap(), - "{sub}({}) (unsub: {unsub})", - params.as_ref().map(|p| p.get()).unwrap_or("[]") - ) - .unwrap(); - - // We've logged the request; just return garbage. Because a boxed future is returned, - // and that will return a boxed Stream impl, you have a bunch of flexibility to build - // and return whatever type of Stream you see fit. - let res = RawValue::from_string("[]".to_string()).unwrap(); - let stream = futures::stream::once(async move { Ok(res) }); - let stream: Pin + Send>> = Box::pin(stream); - // This subscription does not provide an ID. - Box::pin(std::future::ready(Ok(RawRpcSubscription { - stream, - id: None, - }))) - } -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Instantiate our replacement RPC client. - let log = Arc::default(); - let rpc_client = { - let inner = MyLoggingClient { - log: Arc::clone(&log), - }; - RpcClient::new(inner) - }; - - // Pass this into our OnlineClient to instantiate it. This will lead to some - // RPC calls being made to fetch chain details/metadata, which will immediately - // fail.. - let _ = OnlineClient::::from_rpc_client(rpc_client).await; - - // But, we can see that the calls were made via our custom RPC client: - println!("Log of calls made:\n\n{}", log.lock().unwrap().as_str()); - Ok(()) -} -*/ - //! ``` - //! - //! ### Creating an [`crate::OfflineClient`]: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::ext::codec::Decode; -use subxt::metadata::Metadata; -use subxt::utils::H256; -use subxt::{config::PolkadotConfig, OfflineClient}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // We need to obtain the following details for an OfflineClient to be instantiated: - - // 1. Genesis hash (RPC call: chain_getBlockHash(0)): - let genesis_hash = { - let h = "91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3"; - let bytes = hex::decode(h).unwrap(); - H256::from_slice(&bytes) - }; - - // 2. A runtime version (system_version constant on a Substrate node has these): - let runtime_version = subxt::backend::RuntimeVersion { - spec_version: 9370, - transaction_version: 20, - }; - - // 3. Metadata (I'll load it from the downloaded metadata, but you can use - // `subxt metadata > file.scale` to download it): - let metadata = { - let bytes = std::fs::read("./artifacts/polkadot_metadata_small.scale").unwrap(); - Metadata::decode(&mut &*bytes).unwrap() - }; - - // Create an offline client using the details obtained above: - let _api = OfflineClient::::new(genesis_hash, runtime_version, metadata); - - Ok(()) -} -*/ - //! ``` - //! - } - pub mod codegen { - //! # Generating an interface - //! - //! The simplest way to use Subxt is to generate an interface to a chain that you'd like to interact - //! with. This generated interface allows you to build transactions and construct queries to access - //! data while leveraging the full type safety of the Rust compiler. - //! - //! ## The `#[subxt]` macro - //! - //! The most common way to generate the interface is to use the [`#[subxt]`](crate::subxt) macro. - //! Using this macro looks something like: - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_tiny.scale")] - //! pub mod polkadot {} - //! ``` - //! - //! The macro takes a path to some node metadata, and uses that to generate the interface you'll use - //! to talk to it. [Go here](crate::subxt) to learn more about the options available to the macro. - //! - //! To obtain this metadata you'll need for the above, you can use the `subxt` CLI tool to download it - //! from a node. The tool can be installed via `cargo`: - //! - //! ```shell - //! cargo install subxt-cli - //! ``` - //! - //! And then it can be used to fetch metadata and save it to a file: - //! - //! ```shell - //! # Download and save all of the metadata: - //! subxt metadata > metadata.scale - //! # Download and save only the pallets you want to generate an interface for: - //! subxt metadata --pallets Balances,System > metadata.scale - //! ``` - //! - //! Explicitly specifying pallets will cause the tool to strip out all unnecessary metadata and type - //! information, making the bundle much smaller in the event that you only need to generate an - //! interface for a subset of the available pallets on the node. - //! - //! ## The CLI tool - //! - //! Using the [`#[subxt]`](crate::subxt) macro carries some downsides: - //! - //! - Using it to generate an interface will have a small impact on compile times (though much less of - //! one if you only need a few pallets). - //! - IDE support for autocompletion and documentation when using the macro interface can be poor. - //! - It's impossible to manually look at the generated code to understand and debug things. - //! - //! If these are an issue, you can manually generate the same code that the macro generates under the hood - //! by using the `subxt codegen` command: - //! - //! ```shell - //! # Install the CLI tool if you haven't already: - //! cargo install subxt-cli - //! # Generate and format rust code, saving it to `interface.rs`: - //! subxt codegen | rustfmt > interface.rs - //! ``` - //! - //! Use `subxt codegen --help` for more options; many of the options available via the macro are - //! also available via the CLI tool, such as the ability to substitute generated types for others, - //! or strip out docs from the generated code. - //! - } - pub mod config { - //! # Creating a Config - //! - //! Subxt requires you to provide a type implementing [`crate::config::Config`] in order to connect to a node. - //! The [`crate::config::Config`] trait for the most part mimics the `frame_system::Config` trait. - //! For most use cases, you can just use one of the following Configs shipped with Subxt: - //! - //! - [`PolkadotConfig`](crate::config::PolkadotConfig) for talking to Polkadot nodes, and - //! - [`SubstrateConfig`](crate::config::SubstrateConfig) for talking to generic nodes built with Substrate. - //! - //! # How to create a Config for a custom chain? - //! - //! Some chains may use config that is not compatible with our [`PolkadotConfig`](crate::config::PolkadotConfig) or - //! [`SubstrateConfig`](crate::config::SubstrateConfig). - //! - //! We now walk through creating a custom [`crate::config::Config`] for a parachain, using the - //! ["Statemint"](https://parachains.info/details/statemint) parachain, also known as "Asset Hub", as an example. It - //! is currently (as of 2023-06-26) deployed on Polkadot and [Kusama (as "Statemine")](https://parachains.info/details/statemine). - //! - //! To construct a valid [`crate::config::Config`] implementation, we need to find out which types to use for `AccountId`, `Hasher`, etc. - //! For this, we need to take a look at the source code of Statemint, which is currently a part of the [Cumulus Github repository](https://github.com/paritytech/cumulus). - //! The crate defining the asset hub runtime can be found [here](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/assets/asset-hub-polkadot). - //! - //! ## `AccountId`, `Hash`, `Hasher` and `Header` - //! - //! For these config types, we need to find out where the parachain runtime implements the `frame_system::Config` trait. - //! Look for a code fragment like `impl frame_system::Config for Runtime { ... }` In the source code. - //! For Statemint it looks like [this](https://github.com/paritytech/cumulus/blob/e2b7ad2061824f490c08df27a922c64f50accd6b/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs#L179) - //! at the time of writing. The `AccountId`, `Hash` and `Header` types of the [frame_system::pallet::Config](https://docs.rs/frame-system/latest/frame_system/pallet/trait.Config.html) - //! correspond to the ones we want to use in our Subxt [crate::Config]. In the Case of Statemint (Asset Hub) they are: - //! - //! - AccountId: `sp_core::crypto::AccountId32` - //! - Hash: `sp_core::H256` - //! - Hasher (type `Hashing` in [frame_system::pallet::Config](https://docs.rs/frame-system/latest/frame_system/pallet/trait.Config.html)): `sp_runtime::traits::BlakeTwo256` - //! - Header: `sp_runtime::generic::Header` - //! - //! Subxt has its own versions of some of these types in order to avoid needing to pull in Substrate dependencies: - //! - //! - `sp_core::crypto::AccountId32` can be swapped with [`crate::utils::AccountId32`]. - //! - `sp_core::H256` is a re-export which subxt also provides as [`crate::config::substrate::H256`]. - //! - `sp_runtime::traits::BlakeTwo256` can be swapped with [`crate::config::substrate::BlakeTwo256`]. - //! - `sp_runtime::generic::Header` can be swapped with [`crate::config::substrate::SubstrateHeader`]. - //! - //! Having a look at how those types are implemented can give some clues as to how to implement other custom types that - //! you may need to use as part of your config. - //! - //! ## `Address`, `Signature` - //! - //! A Substrate runtime is typically constructed by using the [frame_support::construct_runtime](https://docs.rs/frame-support/latest/frame_support/macro.construct_runtime.html) macro. - //! In this macro, we need to specify the type of an `UncheckedExtrinsic`. Most of the time, the `UncheckedExtrinsic` will be of the type - //! `sp_runtime::generic::UncheckedExtrinsic`. - //! The generic parameters `Address` and `Signature` specified when declaring the `UncheckedExtrinsic` type - //! are the types for `Address` and `Signature` we should use with our [crate::Config] implementation. This information can - //! also be obtained from the metadata (see [`frame_metadata::v15::ExtrinsicMetadata`]). In case of Statemint (Polkadot Asset Hub) - //! we see the following types being used in `UncheckedExtrinsic`: - //! - //! - Address: `sp_runtime::MultiAddress` - //! - Signature: `sp_runtime::MultiSignature` - //! - //! As above, Subxt has its own versions of these types that can be used instead to avoid pulling in Substrate dependencies. - //! Using the Subxt versions also makes interacting with generated code (which uses them in some places) a little nicer: - //! - //! - `sp_runtime::MultiAddress` can be swapped with [`crate::utils::MultiAddress`]. - //! - `sp_runtime::MultiSignature` can be swapped with [`crate::utils::MultiSignature`]. - //! - //! ## ExtrinsicParams - //! - //! Chains each have a set of "signed extensions" configured. Signed extensions provide a means to extend how transactions - //! work. Each signed extension can potentially encode some "extra" data which is sent along with a transaction, as well as some - //! "additional" data which is included in the transaction signer payload, but not transmitted along with the transaction. On - //! a node, signed extensions can then perform additional checks on the submitted transactions to ensure their validity. - //! - //! The `ExtrinsicParams` config type expects to be given an implementation of the [`crate::config::ExtrinsicParams`] trait. - //! Implementations of the [`crate::config::ExtrinsicParams`] trait are handed some parameters from Subxt itself, and can - //! accept arbitrary `OtherParams` from users, and are then expected to provide this "extra" and "additional" data when asked - //! via the required [`crate::config::ExtrinsicParamsEncoder`] impl. - //! - //! **In most cases, the default [crate::config::DefaultExtrinsicParams] type will work**: it understands the "standard" - //! signed extensions that are in use, and allows the user to provide things like a tip, and set the extrinsic mortality via - //! [`crate::config::DefaultExtrinsicParamsBuilder`]. It will use the chain metadata to decide which signed extensions to use - //! and in which order. It will return an error if the chain uses a signed extension which it doesn't know how to handle. - //! - //! If the chain uses novel signed extensions (or if you just wish to provide a different interface for users to configure - //! transactions), you can either: - //! - //! 1. Implement a new signed extension and add it to the list. - //! 2. Implement [`crate::config::DefaultExtrinsicParams`] from scratch. - //! - //! See below for examples of each. - //! - //! ### Finding out which signed extensions a chain is using. - //! - //! In either case, you'll want to find out which signed extensions a chain is using. This information can be obtained from - //! the `SignedExtra` parameter of the `UncheckedExtrinsic` of your parachain, which will be a tuple of signed extensions. - //! It can also be obtained from the metadata (see [`frame_metadata::v15::SignedExtensionMetadata`]). - //! - //! For statemint, the signed extensions look like - //! [this](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs#L779): - //! - //! ```rs - //! pub type SignedExtra = ( - //! frame_system::CheckNonZeroSender, - //! frame_system::CheckSpecVersion, - //! frame_system::CheckTxVersion, - //! frame_system::CheckGenesis, - //! frame_system::CheckEra, - //! frame_system::CheckNonce, - //! frame_system::CheckWeight, - //! pallet_asset_tx_payment::ChargeAssetTxPayment, - //! ); - //! ``` - //! - //! Each element of the `SignedExtra` tuple implements [codec::Encode] and `sp_runtime::traits::SignedExtension` - //! which has an associated type `AdditionalSigned` that also implements [codec::Encode]. Let's look at the underlying types - //! for each tuple element. All zero-sized types have been replaced by `()` for simplicity. - //! - //! | tuple element | struct type | `AdditionalSigned` type | - //! | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | - //! | [`frame_system::CheckNonZeroSender`](https://docs.rs/frame-system/latest/frame_system/struct.CheckNonZeroSender.html) | () | () | - //! | [`frame_system::CheckSpecVersion`](https://docs.rs/frame-system/latest/frame_system/struct.CheckSpecVersion.html) | () | [u32] | - //! | [`frame_system::CheckTxVersion`](https://docs.rs/frame-system/latest/frame_system/struct.CheckTxVersion.html) | () | [u32] | - //! | [`frame_system::CheckGenesis`](https://docs.rs/frame-system/latest/frame_system/struct.CheckGenesis.html) | () | `Config::Hash` = `sp_core::H256` | - //! | [`frame_system::CheckMortality`](https://docs.rs/frame-system/latest/frame_system/struct.CheckMortality.html) | `sp_runtime::generic::Era` | `Config::Hash` = `sp_core::H256` | - //! | [`frame_system::CheckNonce`](https://docs.rs/frame-system/latest/frame_system/struct.CheckNonce.html) | `frame_system::pallet::Config::Index` = u32 | () | - //! | [`frame_system::CheckWeight`](https://docs.rs/frame-system/latest/frame_system/struct.CheckWeight.html) | () | () | - //! | [`frame_system::ChargeAssetTxPayment`](https://docs.rs/frame-system/latest/frame_system/struct.ChargeAssetTxPayment.html) | [pallet_asset_tx_payment::ChargeAssetTxPayment](https://docs.rs/pallet-asset-tx-payment/latest/pallet_asset_tx_payment/struct.ChargeAssetTxPayment.html) | () | - //! - //! All types in the `struct type` column make up the "extra" data that we're expected to provide. All types in the - //! `AdditionalSigned` column make up the "additional" data that we're expected to provide. This information will be useful - //! whether we want to implement [`crate::config::SignedExtension`] for a signed extension, or implement - //! [`crate::config::ExtrinsicParams`] from scratch. - //! - //! As it happens, all of the signed extensions in the table are either already exported in [`crate::config::signed_extensions`], - //! or they hand back no "additional" or "extra" data. In both of these cases, the default `ExtrinsicParams` configuration will - //! work out of the box. - //! - //! ### Implementing and adding new signed extensions to the config - //! - //! If you do need to implement a novel signed extension, then you can implement [`crate::config::signed_extensions::SignedExtension`] - //! on a custom type and place it into a new set of signed extensions, like so: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use codec::Encode; -use scale_encode::EncodeAsType; -use scale_info::PortableRegistry; -use subxt::client::OfflineClientT; -use subxt::config::signed_extensions; -use subxt::config::{ - Config, DefaultExtrinsicParamsBuilder, ExtrinsicParams, ExtrinsicParamsEncoder, - ExtrinsicParamsError, -}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod runtime {} - -// We don't need to construct this at runtime, -// so an empty enum is appropriate: -#[derive(EncodeAsType)] -pub enum CustomConfig {} - -impl Config for CustomConfig { - type Hash = subxt::utils::H256; - type AccountId = subxt::utils::AccountId32; - type Address = subxt::utils::MultiAddress; - type Signature = subxt::utils::MultiSignature; - type Hasher = subxt::config::substrate::BlakeTwo256; - type Header = subxt::config::substrate::SubstrateHeader; - type ExtrinsicParams = signed_extensions::AnyOf< - Self, - ( - // Load in the existing signed extensions we're interested in - // (if the extension isn't actually needed it'll just be ignored): - signed_extensions::CheckSpecVersion, - signed_extensions::CheckTxVersion, - signed_extensions::CheckNonce, - signed_extensions::CheckGenesis, - signed_extensions::CheckMortality, - signed_extensions::ChargeAssetTxPayment, - signed_extensions::ChargeTransactionPayment, - // And add a new one of our own: - CustomSignedExtension, - ), - >; - type AssetId = u32; -} - -// Our custom signed extension doesn't do much: -pub struct CustomSignedExtension; - -// Give the extension a name; this allows `AnyOf` to look it -// up in the chain metadata in order to know when and if to use it. -impl signed_extensions::SignedExtension for CustomSignedExtension { - type Decoded = (); - fn matches(identifier: &str, _type_id: u32, _types: &PortableRegistry) -> bool { - identifier == "CustomSignedExtension" - } -} - -// Gather together any params we need for our signed extension, here none. -impl ExtrinsicParams for CustomSignedExtension { - type OtherParams = (); - - fn new>( - _nonce: u64, - _client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CustomSignedExtension) - } -} - -// Encode whatever the extension needs to provide when asked: -impl ExtrinsicParamsEncoder for CustomSignedExtension { - fn encode_extra_to(&self, v: &mut Vec) { - "Hello".encode_to(v); - } - fn encode_additional_to(&self, v: &mut Vec) { - true.encode_to(v) - } -} - -// When composing a tuple of signed extensions, the user parameters we need must -// be able to convert `Into` a tuple of corresponding `OtherParams`. Here, we just -// "hijack" the default param builder, but add the `OtherParams` (`()`) for our -// new signed extension at the end, to make the types line up. IN reality you may wish -// to construct an entirely new interface to provide the relevant `OtherParams`. -pub fn custom( - params: DefaultExtrinsicParamsBuilder, -) -> <::ExtrinsicParams as ExtrinsicParams>::OtherParams { - let (a, b, c, d, e, f, g) = params.build(); - (a, b, c, d, e, f, g, ()) -} - -#[tokio::main] -async fn main() { - // With the config defined, it can be handed to Subxt as follows: - let client = subxt::OnlineClient::::new().await.unwrap(); - - let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); - - // Configure the tx params: - let tx_config = DefaultExtrinsicParamsBuilder::new().tip(1234); - - // And provide them when submitting a transaction: - let _ = client - .tx() - .sign_and_submit_then_watch(&tx_payload, &dev::alice(), custom(tx_config)) - .await; -} -*/ - //! ``` - //! - //! ### Implementing [`crate::config::ExtrinsicParams`] from scratch - //! - //! Alternately, you are free to implement [`crate::config::ExtrinsicParams`] entirely from scratch if you know exactly what "extra" and` - //! "additional" data your node needs and would prefer to craft your own interface. - //! - //! Let's see what this looks like (this config won't work on any real node): - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use codec::Encode; -use subxt::client::OfflineClientT; -use subxt::config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] -pub mod runtime {} - -// We don't need to construct this at runtime, -// so an empty enum is appropriate: -pub enum CustomConfig {} - -impl Config for CustomConfig { - type Hash = subxt::utils::H256; - type AccountId = subxt::utils::AccountId32; - type Address = subxt::utils::MultiAddress; - type Signature = subxt::utils::MultiSignature; - type Hasher = subxt::config::substrate::BlakeTwo256; - type Header = subxt::config::substrate::SubstrateHeader; - type ExtrinsicParams = CustomExtrinsicParams; - type AssetId = u32; -} - -// This represents some arbitrary (and nonsensical) custom parameters that -// will be attached to transaction extra and additional payloads: -pub struct CustomExtrinsicParams { - genesis_hash: T::Hash, - tip: u128, - foo: bool, -} - -// We can provide a "pretty" interface to allow users to provide these: -#[derive(Default)] -pub struct CustomExtrinsicParamsBuilder { - tip: u128, - foo: bool, -} - -impl CustomExtrinsicParamsBuilder { - pub fn new() -> Self { - Default::default() - } - pub fn tip(mut self, value: u128) -> Self { - self.tip = value; - self - } - pub fn enable_foo(mut self) -> Self { - self.foo = true; - self - } -} - -// Describe how to fetch and then encode the params: -impl ExtrinsicParams for CustomExtrinsicParams { - type OtherParams = CustomExtrinsicParamsBuilder; - - // Gather together all of the params we will need to encode: - fn new>( - _nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - Ok(Self { - genesis_hash: client.genesis_hash(), - tip: other_params.tip, - foo: other_params.foo, - }) - } -} - -// Encode the relevant params when asked: -impl ExtrinsicParamsEncoder for CustomExtrinsicParams { - fn encode_extra_to(&self, v: &mut Vec) { - (self.tip, self.foo).encode_to(v); - } - fn encode_additional_to(&self, v: &mut Vec) { - self.genesis_hash.encode_to(v) - } -} - -#[tokio::main] -async fn main() { - // With the config defined, it can be handed to Subxt as follows: - let client = subxt::OnlineClient::::new().await.unwrap(); - - let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); - - // Build your custom "OtherParams": - let tx_config = CustomExtrinsicParamsBuilder::new().tip(1234).enable_foo(); - - // And provide them when submitting a transaction: - let _ = client - .tx() - .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) - .await; -} -*/ - //! ``` - //! - //! ### Using a type from the metadata as a config parameter - //! - //! You can also use types that are generated from chain metadata as type parameters of the Config trait. - //! Just make sure all trait bounds are satisfied. This can often be achieved by using custom derives with the subxt macro. - //! For example, the AssetHub Parachain expects tips to include a `MultiLocation`, which is a type we can draw from the metadata. - //! - //! This example shows what using the `MultiLocation` struct as part of your config would look like in subxt: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::config::{ - Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, PolkadotConfig, SubstrateConfig, -}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt( - runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", - derive_for_type( - path = "xcm::v2::multilocation::MultiLocation", - derive = "Clone", - recursive - ) -)] -pub mod runtime {} -use runtime::runtime_types::xcm::v2::multilocation::{Junctions, MultiLocation}; - -// We don't need to construct this at runtime, so an empty enum is appropriate. -pub enum AssetHubConfig {} - -impl Config for AssetHubConfig { - type Hash = ::Hash; - type AccountId = ::AccountId; - type Address = ::Address; - type Signature = ::Signature; - type Hasher = ::Hasher; - type Header = ::Header; - type ExtrinsicParams = DefaultExtrinsicParams; - // Here we use the MultiLocation from the metadata as a part of the config: - // The `ChargeAssetTxPayment` signed extension that is part of the ExtrinsicParams above, now uses the type: - type AssetId = MultiLocation; -} - -#[tokio::main] -async fn main() { - // With the config defined, we can create an extrinsic with subxt: - let client = subxt::OnlineClient::::new().await.unwrap(); - let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); - - // Build extrinsic params using an asset at this location as a tip: - let location: MultiLocation = MultiLocation { - parents: 3, - interior: Junctions::Here, - }; - let tx_config = DefaultExtrinsicParamsBuilder::::new() - .tip_of(1234, location) - .build(); - - // And provide the extrinsic params including the tip when submitting a transaction: - let _ = client - .tx() - .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) - .await; -} -*/ - //! ``` - } - } - pub mod usage { - //! This modules contains examples of using Subxt; follow the links for more: - //! - //! - [Transactions](transactions) - //! - [Storage](storage) - //! - [Events](events) - //! - [Constants](constants) - //! - [Blocks](blocks) - //! - [Runtime APIs](runtime_apis) - //! - [Unstable Light Client](light_client) - //! - [Custom Values](custom_values) - //! - [RPC calls](rpc) - //! - //! Alternately, [go back](super). - pub mod blocks { - //! # Blocks - //! - //! The [blocks API](crate::blocks::BlocksClient) in Subxt unifies many of the other interfaces, and - //! allows you to: - //! - //! - Access information about specific blocks (see [`crate::blocks::BlocksClient::at()`] and - //! [`crate::blocks::BlocksClient::at_latest()`]). - //! - Subscribe to [all](crate::blocks::BlocksClient::subscribe_all()), - //! [best](crate::blocks::BlocksClient::subscribe_best()) or - //! [finalized](crate::blocks::BlocksClient::subscribe_finalized()) blocks as they are produced. - //! Prefer to subscribe to finalized blocks unless you know what you're doing. - //! - //! In either case, you'll end up with [`crate::blocks::Block`]'s, from which you can access various - //! information about the block, such a the [header](crate::blocks::Block::header()), [block - //! number](crate::blocks::Block::number()) and [body (the extrinsics)](crate::blocks::Block::extrinsics()). - //! [`crate::blocks::Block`]'s also provide shortcuts to other Subxt APIs that will operate at the - //! given block: - //! - //! - [storage](crate::blocks::Block::storage()), - //! - [events](crate::blocks::Block::events()) - //! - [runtime APIs](crate::blocks::Block::runtime_api()) - //! - //! Aside from these links to other Subxt APIs, the main thing that we can do here is iterate over and - //! decode the extrinsics in a block body. - //! - //! ## Decoding Extrinsics - //! - //! Given a block, you can [download the block body](crate::blocks::Block::extrinsics()) and [iterate over - //! the extrinsics](crate::blocks::Extrinsics::iter()) stored within it. The extrinsics yielded are of type - //! [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), which is just a blob of bytes that also stores which - //! pallet and call in that pallet it belongs to. It also contains information about signed extensions that - //! have been used for submitting this extrinsic. - //! - //! To use the extrinsic, you probably want to decode it into a concrete Rust type. These Rust types representing - //! extrinsics from different pallets can be generated from metadata using the subxt macro or the CLI tool. - //! - //! When decoding the extrinsic into a static type you have two options: - //! - //! ### Statically decode the extrinsics into [the root extrinsic type](crate::blocks::ExtrinsicDetails::as_root_extrinsic()) - //! - //! The root extrinsic type generated by subxt is a Rust enum with one variant for each pallet. Each of these - //! variants has a field that is another enum whose variants cover all calls of the respective pallet. - //! If the extrinsic bytes are valid and your metadata matches the chain's metadata, decoding the bytes of an extrinsic into - //! this root extrinsic type should always succeed. - //! - //! This example shows how to subscribe to blocks and decode the extrinsics in each block into the root extrinsic type. - //! Once we get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), we can decode it statically or dynamically. - //! We can also access details about the extrinsic, including the associated events and signed extensions. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Subscribe to all finalized blocks: - let mut blocks_sub = api.blocks().subscribe_finalized().await?; - - // For each block, print a bunch of information about it: - while let Some(block) = blocks_sub.next().await { - let block = block?; - - let block_number = block.header().number; - let block_hash = block.hash(); - - println!("Block #{block_number}:"); - println!(" Hash: {block_hash}"); - println!(" Extrinsics:"); - - // Log each of the extrinsic with it's associated events: - let extrinsics = block.extrinsics().await?; - for ext in extrinsics.iter() { - let ext = ext?; - let idx = ext.index(); - let events = ext.events().await?; - let bytes_hex = format!("0x{}", hex::encode(ext.bytes())); - - // See the API docs for more ways to decode extrinsics: - let decoded_ext = ext.as_root_extrinsic::(); - - println!(" Extrinsic #{idx}:"); - println!(" Bytes: {bytes_hex}"); - println!(" Decoded: {decoded_ext:?}"); - - println!(" Events:"); - for evt in events.iter() { - let evt = evt?; - let pallet_name = evt.pallet_name(); - let event_name = evt.variant_name(); - let event_values = evt.field_values()?; - - println!(" {pallet_name}_{event_name}"); - println!(" {}", event_values); - } - - println!(" Signed Extensions:"); - if let Some(signed_extensions) = ext.signed_extensions() { - for signed_extension in signed_extensions.iter() { - let signed_extension = signed_extension?; - let name = signed_extension.name(); - let value = signed_extension.value()?.to_string(); - println!(" {name}: {value}"); - } - } - } - } - - Ok(()) -} -*/ - //! ``` - //! - //! ### Statically decode the extrinsic into [a specific pallet call](crate::blocks::ExtrinsicDetails::as_extrinsic()) - //! - //! This is useful if you are expecting a specific extrinsic to be part of some block. If the extrinsic you try to decode - //! is a different extrinsic, an `Ok(None)` value is returned from [`as_extrinsic::()`](crate::blocks::ExtrinsicDetails::as_extrinsic()); - //! - //! If you are only interested in finding specific extrinsics in a block, you can also [iterate over all of them](crate::blocks::Extrinsics::find), - //! get only [the first one](crate::blocks::Extrinsics::find_first), or [the last one](crate::blocks::Extrinsics::find_last). - //! - //! The following example monitors `TransferKeepAlive` extrinsics on the Polkadot network. - //! We statically decode them and access the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and [account nonce](crate::blocks::ExtrinsicSignedExtensions::nonce()) signed extensions. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{ - utils::{AccountId32, MultiAddress}, - OnlineClient, PolkadotConfig, -}; - -use codec::Decode; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -use polkadot::balances::calls::types::TransferKeepAlive; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client that subscribes to blocks of the Polkadot network. - let api = OnlineClient::::from_url("wss://rpc.polkadot.io:443").await?; - - // Subscribe to all finalized blocks: - let mut blocks_sub = api.blocks().subscribe_finalized().await?; - - // For each block, print details about the `TransferKeepAlive` transactions we are interested in. - while let Some(block) = blocks_sub.next().await { - let block = block?; - let block_number = block.header().number; - let block_hash = block.hash(); - println!("Block #{block_number} ({block_hash}):"); - - let extrinsics = block.extrinsics().await?; - for transfer in extrinsics.find::() { - let transfer = transfer?; - - let Some(extensions) = transfer.details.signed_extensions() else { - panic!("TransferKeepAlive should be signed") - }; - - let addr_bytes = transfer - .details - .address_bytes() - .expect("TransferKeepAlive should be signed"); - let sender = MultiAddress::::decode(&mut &addr_bytes[..]) - .expect("Decoding should work"); - let sender = display_address(&sender); - let receiver = display_address(&transfer.value.dest); - let value = transfer.value.value; - let tip = extensions.tip().expect("Should have tip"); - let nonce = extensions.nonce().expect("Should have nonce"); - - println!( - " Transfer of {value} DOT:\n {sender} (Tip: {tip}, Nonce: {nonce}) ---> {receiver}", - ); - } - } - - Ok(()) -} - -fn display_address(addr: &MultiAddress) -> String { - if let MultiAddress::Id(id32) = addr { - format!("{id32}") - } else { - "MultiAddress::...".into() - } -} -*/ - //! ``` - //! - //! ### Dynamically decode the extrinsic - //! - //! Sometimes you might use subxt with metadata that is not known at compile time. In this case, you do not have access to a statically generated - //! interface module that contains the relevant Rust types. You can [decode ExtrinsicDetails dynamically](crate::blocks::ExtrinsicDetails::field_values()), - //! which gives you access to it's fields as a [scale value composite](scale_value::Composite). - //! The following example looks for signed extrinsics on the Polkadot network and retrieves their pallet name, variant name, data fields and signed extensions dynamically. - //! Notice how we do not need to use code generation via the subxt macro. The only fixed component we provide is the [PolkadotConfig](crate::config::PolkadotConfig). - //! Other than that it works in a chain-agnostic way: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client that subscribes to blocks of the Polkadot network. - let api = OnlineClient::::from_url("wss://rpc.polkadot.io:443").await?; - - // Subscribe to all finalized blocks: - let mut blocks_sub = api.blocks().subscribe_finalized().await?; - while let Some(block) = blocks_sub.next().await { - let block = block?; - let block_number = block.header().number; - let block_hash = block.hash(); - println!("Block #{block_number} ({block_hash})"); - - // Decode each signed extrinsic in the block dynamically - let extrinsics = block.extrinsics().await?; - for ext in extrinsics.iter() { - let ext = ext?; - - let Some(signed_extensions) = ext.signed_extensions() else { - continue; // we do not look at inherents in this example - }; - - let meta = ext.extrinsic_metadata()?; - let fields = ext.field_values()?; - - println!(" {}/{}", meta.pallet.name(), meta.variant.name); - println!(" Signed Extensions:"); - for signed_ext in signed_extensions.iter() { - let signed_ext = signed_ext?; - // We only want to take a look at these 3 signed extensions, because the others all just have unit fields. - if ["CheckMortality", "CheckNonce", "ChargeTransactionPayment"] - .contains(&signed_ext.name()) - { - println!(" {}: {}", signed_ext.name(), signed_ext.value()?); - } - } - println!(" Fields:"); - println!(" {}\n", fields); - } - } - - Ok(()) -} -*/ - //! ``` - //! - //! ## Decoding signed extensions - //! - //! Extrinsics can contain signed extensions. The signed extensions can be different across chains. - //! The [Config](crate::Config) implementation for your chain defines which signed extensions you expect. - //! Once you get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails) for an extrinsic you are interested in, - //! you can try to [get its signed extensions](crate::blocks::ExtrinsicDetails::signed_extensions()). - //! These are only available on signed extrinsics. You can try to [find a specific signed extension](crate::blocks::ExtrinsicSignedExtensions::find), - //! in the returned [signed extensions](crate::blocks::ExtrinsicSignedExtensions). - //! - //! Subxt also provides utility functions to get the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and the - //! [account nonce](crate::blocks::ExtrinsicSignedExtensions::tip()) associated with an extrinsic, given its signed extensions. - //! If you prefer to do things dynamically you can get the data of the signed extension as a [scale value](crate::blocks::ExtrinsicSignedExtension::value()). - //! - } - pub mod constants { - //! # Constants - //! - //! There are various constants stored in a node; the types and values of these are defined in a - //! runtime, and can only change when the runtime is updated. Much like [`super::storage`], we can - //! query these using Subxt by taking the following steps: - //! - //! 1. [Constructing a constant query](#constructing-a-query). - //! 2. [Submitting the query to get back the associated value](#submitting-it). - //! - //! ## Constructing a constant query - //! - //! We can use the statically generated interface to build constant queries: - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] - //! pub mod polkadot {} - //! - //! let constant_query = polkadot::constants().system().block_length(); - //! ``` - //! - //! Alternately, we can dynamically construct a constant query: - //! - //! ```rust,no_run - //! use subxt::dynamic::Value; - //! - //! let storage_query = subxt::dynamic::constant("System", "BlockLength"); - //! ``` - //! - //! Static queries also have a static return type, so the constant is decoded appropriately. In - //! addition, they are validated at runtime to ensure that they align with the current node state. - //! Dynamic queries must be decoded into some static type manually, or into the dynamic - //! [`crate::dynamic::Value`] type. - //! - //! ## Submitting it - //! - //! Constant queries are handed to Subxt via [`crate::constants::ConstantsClient::at()`]. It's worth - //! noting that constant values are pulled directly out of the node metadata which Subxt has - //! already acquired, and so this function requires no network access and is available from a - //! [`crate::OfflineClient`]. - //! - //! Here's an example using a static query: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // A query to obtain some contant: - let constant_query = polkadot::constants().system().block_length(); - - // Obtain the value: - let value = api.constants().at(&constant_query)?; - - println!("Block length: {value:?}"); - Ok(()) -} -*/ - //! ``` - //! - //! And here's one using a dynamic query: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // A dynamic query to obtain some contant: - let constant_query = subxt::dynamic::constant("System", "BlockLength"); - - // Obtain the value: - let value = api.constants().at(&constant_query)?; - - println!("Constant bytes: {:?}", value.encoded()); - println!("Constant value: {}", value.to_value()?); - Ok(()) -} -*/ - //! ``` - //! - } - pub mod custom_values { - //! # Custom Values - //! - //! Substrate-based chains can expose custom values in their metadata. - //! Each of these values: - //! - //! - can be accessed by a unique __name__. - //! - refers to a concrete __type__ stored in the metadata. - //! - contains a scale encoded __value__ of that type. - //! - //! ## Getting a custom value - //! - //! Custom values can be accessed via a [`CustomValuesClient`](crate::custom_values::CustomValuesClient). - //! The client exposes an `at` function by which a custom value can be fetched, given an address to this custom value. - //! An address can be as simple as the aforementioned __name__ as a [str]. This will return a dynamic value, that you can manually decode into the type you want. - //! Suppose, the custom types contain a value of type `Foo` under the name `"foo"` you can access it like in this example: - //! - //! ```rust,ignore - //! use subxt::{OnlineClient, PolkadotConfig, ext::{codec::Decode, scale_decode::DecodeAsType}}; - //! - //! #[derive(Decode, DecodeAsType, Debug)] - //! struct Foo { - //! n: u8, - //! b: bool, - //! } - //! - //! let api = OnlineClient::::new().await?; - //! let custom_value_client = api.custom_values(); - //! let foo_dynamic = custom_value_client.at("foo")?; - //! let foo: Foo = foo_dynamic.as_type()?; - //! - //! ``` - //! - //! Alternatively we also provide a statically generated api for custom values: - //! - //! ```rust,ignore - //! #[subxt::subxt(runtime_metadata_path = "some_metadata.scale")] - //! pub mod interface {} - //! - //! let static_address = interface::custom().foo(); - //! - //! let api = OnlineClient::::new().await?; - //! let custom_value_client = api.custom_values(); - //! - //! // Now the `at()` function already decodes the value into the Foo type: - //! let foo = custom_value_client.at(&static_address)?; - //! ``` - //! - //! Note: Names of custom values are converted to __snake_case__ to produce a valid function name during code generation. - //! If there are multiple values where the names would be equal when converted to __snake_case__, functions might not be statically generated for some of them, because of naming conflicts. - //! Make sure names in the custom values of your metadata differ significantly. - } - pub mod events { - //! # Events - //! - //! In the process of adding extrinsics to a block, they are executed. When extrinsics are executed, - //! they normally produce events describing what's happening (at the very least, an event dictating whether - //! the extrinsic has succeeded or failed). The node may also emit some events of its own as the block is - //! processed. - //! - //! Events live in a single location in node storage which is overwritten at each block. Normal nodes tend to - //! keep a snapshot of the state at a small number of previous blocks, so you can sometimes access - //! older events by using [`crate::events::EventsClient::at()`] and providing an older block hash. - //! - //! When we submit transactions using Subxt, methods like [`crate::tx::TxProgress::wait_for_finalized_success()`] - //! return [`crate::blocks::ExtrinsicEvents`], which can be used to iterate and inspect the events produced - //! by that transaction being executed. We can also access _all_ of the events produced in a single block using one - //! of these two interfaces: - //! - //! ```rust,no_run - //! # #[tokio::main] - //! # async fn main() -> Result<(), Box> { - //! use subxt::client::OnlineClient; - //! use subxt::config::PolkadotConfig; - //! - //! // Create client: - //! let client = OnlineClient::::new().await?; - //! - //! // Get events from the latest block (use .at() to specify a block hash): - //! let events = client.blocks().at_latest().await?.events().await?; - //! // We can use this shorthand too: - //! let events = client.events().at_latest().await?; - //! # Ok(()) - //! # } - //! ``` - //! - //! Once we've loaded our events, we can iterate all events or search for specific events via - //! methods like [`crate::events::Events::iter()`] and [`crate::events::Events::find()`]. See - //! [`crate::events::Events`] and [`crate::events::EventDetails`] for more information. - //! - //! ## Example - //! - //! Here's an example which puts this all together: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Get events for the latest block: - let events = api.events().at_latest().await?; - - // We can dynamically decode events: - println!("Dynamic event details:"); - for event in events.iter() { - let event = event?; - - let pallet = event.pallet_name(); - let variant = event.variant_name(); - let field_values = event.field_values()?; - - println!("{pallet}::{variant}: {field_values}"); - } - - // Or we can attempt to statically decode them into the root Event type: - println!("Static event details:"); - for event in events.iter() { - let event = event?; - - if let Ok(ev) = event.as_root_event::() { - println!("{ev:?}"); - } else { - println!(""); - } - } - - // Or we can look for specific events which match our statically defined ones: - let transfer_event = events.find_first::()?; - if let Some(ev) = transfer_event { - println!(" - Balance transfer success: value: {:?}", ev.amount); - } else { - println!(" - No balance transfer event found in this block"); - } - - Ok(()) -} -*/ - //! ``` - //! - } - pub mod light_client { - //! # Light Client - //! - //! The light client based interface uses _Smoldot_ to connect to a _chain_, rather than an individual - //! node. This means that you don't have to trust a specific node when interacting with some chain. - //! - //! This feature is currently unstable. Use the `unstable-light-client` feature flag to enable it. - //! To use this in WASM environments, also enable the `web` feature flag. - //! - //! To connect to a blockchain network, the Light Client requires a trusted sync state of the network, - //! known as a _chain spec_. One way to obtain this is by making a `sync_state_genSyncSpec` RPC call to a - //! trusted node belonging to the chain that you wish to interact with. - //! - //! The following is an example of fetching the chain spec from a local running node on port 9933: - //! - //! ```bash - //! curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "sync_state_genSyncSpec", "params":[true]}' http://localhost:9933/ | jq .result > chain_spec.json - //! ``` - //! - //! Alternately, you can have the `LightClient` download the chain spec from a trusted node when it - //! initializes, which is not recommended in production but is useful for examples and testing, as below. - //! - //! ## Examples - //! - //! ### Basic Example - //! - //! This example connects to a local chain and submits a transaction. To run this, you first need - //! to have a local polkadot node running using the following command: - //! - //! ```text - //! polkadot --dev --node-key 0000000000000000000000000000000000000000000000000000000000000001 - //! ``` - //! - //! Leave that running for a minute, and then you can run the example using the following command - //! in the `subxt` crate: - //! - //! ```bash - //! cargo run --example light_client_tx_basic --features=unstable-light-client - //! ``` - //! - //! This is the code that will be executed: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{client::LightClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // The smoldot logs are informative: - tracing_subscriber::fmt::init(); - - // Create a light client by fetching the chain spec of a local running node. - // In this case, because we start one single node, the bootnodes must be overwritten - // for the light client to connect to the local node. - // - // The `12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp` is the P2P address - // from a local polkadot node starting with - // `--node-key 0000000000000000000000000000000000000000000000000000000000000001` - let api = LightClient::::builder() - .bootnodes([ - "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp", - ]) - .build_from_url("ws://127.0.0.1:9944") - .await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let from = dev::alice(); - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} -*/ - //! ``` - //! - //! ### Connecting to a parachain - //! - //! This example connects to a parachain using the light client. Currently, it's quite verbose to do this. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use futures::StreamExt; -use std::{iter, num::NonZeroU32}; -use subxt::{ - client::{LightClient, RawLightClient}, - PolkadotConfig, -}; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -const POLKADOT_SPEC: &str = include_str!("../../artifacts/demo_chain_specs/polkadot.json"); -const ASSET_HUB_SPEC: &str = - include_str!("../../artifacts/demo_chain_specs/polkadot_asset_hub.json"); - -#[tokio::main] -async fn main() -> Result<(), Box> { - // The smoldot logs are informative: - tracing_subscriber::fmt::init(); - - // Connecting to a parachain is a multi step process. - - // Step 1. Construct a new smoldot client. - let mut client = - subxt_lightclient::smoldot::Client::new(subxt_lightclient::smoldot::DefaultPlatform::new( - "subxt-example-light-client".into(), - "version-0".into(), - )); - - // Step 2. Connect to the relay chain of the parachain. For this example, the Polkadot relay chain. - let polkadot_connection = client - .add_chain(subxt_lightclient::smoldot::AddChainConfig { - specification: POLKADOT_SPEC, - json_rpc: subxt_lightclient::smoldot::AddChainConfigJsonRpc::Enabled { - max_pending_requests: NonZeroU32::new(128).unwrap(), - max_subscriptions: 1024, - }, - potential_relay_chains: iter::empty(), - database_content: "", - user_data: (), - }) - .expect("Light client chain added with valid spec; qed"); - let polkadot_json_rpc_responses = polkadot_connection - .json_rpc_responses - .expect("Light client configured with json rpc enabled; qed"); - let polkadot_chain_id = polkadot_connection.chain_id; - - // Step 3. Connect to the parachain. For this example, the Asset hub parachain. - let assethub_connection = client - .add_chain(subxt_lightclient::smoldot::AddChainConfig { - specification: ASSET_HUB_SPEC, - json_rpc: subxt_lightclient::smoldot::AddChainConfigJsonRpc::Enabled { - max_pending_requests: NonZeroU32::new(128).unwrap(), - max_subscriptions: 1024, - }, - // The chain specification of the asset hub parachain mentions that the identifier - // of its relay chain is `polkadot`. - potential_relay_chains: [polkadot_chain_id].into_iter(), - database_content: "", - user_data: (), - }) - .expect("Light client chain added with valid spec; qed"); - let parachain_json_rpc_responses = assethub_connection - .json_rpc_responses - .expect("Light client configured with json rpc enabled; qed"); - let parachain_chain_id = assethub_connection.chain_id; - - // Step 4. Turn the smoldot client into a raw client. - let raw_light_client = RawLightClient::builder() - .add_chain(polkadot_chain_id, polkadot_json_rpc_responses) - .add_chain(parachain_chain_id, parachain_json_rpc_responses) - .build(client) - .await?; - - // Step 5. Obtain a client to target the relay chain and the parachain. - let polkadot_api: LightClient = - raw_light_client.for_chain(polkadot_chain_id).await?; - let parachain_api: LightClient = - raw_light_client.for_chain(parachain_chain_id).await?; - - // Step 6. Subscribe to the finalized blocks of the chains. - let polkadot_sub = polkadot_api - .blocks() - .subscribe_finalized() - .await? - .map(|block| ("Polkadot", block)); - let parachain_sub = parachain_api - .blocks() - .subscribe_finalized() - .await? - .map(|block| ("AssetHub", block)); - let mut stream_combinator = futures::stream::select(polkadot_sub, parachain_sub); - - while let Some((chain, block)) = stream_combinator.next().await { - let block = block?; - - println!(" Chain {:?} hash={:?}", chain, block.hash()); - } - - Ok(()) -} -*/ - //! ``` - } - pub mod rpc { - //! # RPC calls - //! - //! Subxt exposes low level interfaces that can be used to make RPC requests; [`crate::backend::legacy::rpc_methods`] - //! and [`crate::backend::unstable::rpc_methods`]. - //! - //! These interfaces cannot be accessed directly through an [`crate::OnlineClient`]; this is so that the high level - //! Subxt APIs can target either the "legacy" or the more modern "unstable" sets of RPC methods by selecting an appropriate - //! [`crate::backend::Backend`]. It also means that there could exist a backend in the future that doesn't use JSON-RPC at all. - //! - //! # Example - //! - //! Here's an example which calls some legacy JSON-RPC methods, and reuses the same connection to run a full Subxt client - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::backend::{legacy::LegacyRpcMethods, rpc::RpcClient}; -use subxt::config::DefaultExtrinsicParamsBuilder as Params; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // First, create a raw RPC client: - let rpc_client = RpcClient::from_url("ws://127.0.0.1:9944").await?; - - // Use this to construct our RPC methods: - let rpc = LegacyRpcMethods::::new(rpc_client.clone()); - - // We can use the same client to drive our full Subxt interface too: - let api = OnlineClient::::from_rpc_client(rpc_client.clone()).await?; - - // Now, we can make some RPC calls using some legacy RPC methods. - println!( - "📛 System Name: {:?}\n🩺 Health: {:?}\n🖫 Properties: {:?}\n🔗 Chain: {:?}\n", - rpc.system_name().await?, - rpc.system_health().await?, - rpc.system_properties().await?, - rpc.system_chain().await? - ); - - // We can also interleave RPC calls and using the full Subxt client, here to submit multiple - // transactions using the legacy `system_account_next_index` RPC call, which returns a nonce - // that is adjusted for any transactions already in the pool: - - let alice = dev::alice(); - let bob = dev::bob(); - - loop { - let current_nonce = rpc - .system_account_next_index(&alice.public_key().into()) - .await?; - let current_header = rpc.chain_get_header(None).await?.unwrap(); - - let ext_params = Params::new().mortal(¤t_header, 8).build(); - - let balance_transfer = polkadot::tx() - .balances() - .transfer_allow_death(bob.public_key().into(), 1_000_000); - - let ext_hash = api - .tx() - .create_signed_with_nonce(&balance_transfer, &alice, current_nonce, ext_params)? - .submit() - .await?; - - println!("Submitted ext {ext_hash} with nonce {current_nonce}"); - - // Sleep less than block time, but long enough to ensure - // not all transactions end up in the same block. - tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - } -} -*/ - //! ``` - } - pub mod runtime_apis { - //! # Runtime API interface - //! - //! The Runtime API interface allows Subxt to call runtime APIs exposed by certain pallets in order - //! to obtain information. Much like [`super::storage`] and [`super::transactions`], Making a runtime - //! call to a node and getting the response back takes the following steps: - //! - //! 1. [Constructing a runtime call](#constructing-a-runtime-call) - //! 2. [Submitting it to get back the response](#submitting-it) - //! - //! **Note:** Runtime APIs are only available when using V15 metadata, which is currently unstable. - //! You'll need to use `subxt metadata --version unstable` command to download the unstable V15 metadata, - //! and activate the `unstable-metadata` feature in Subxt for it to also use this metadata from a node. The - //! metadata format is unstable because it may change and break compatibility with Subxt at any moment, so - //! use at your own risk. - //! - //! ## Constructing a runtime call - //! - //! We can use the statically generated interface to build runtime calls: - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] - //! pub mod polkadot {} - //! - //! let runtime_call = polkadot::apis().metadata().metadata_versions(); - //! ``` - //! - //! Alternately, we can dynamically construct a runtime call: - //! - //! ```rust,no_run - //! use subxt::dynamic::Value; - //! - //! let runtime_call = subxt::dynamic::runtime_api_call( - //! "Metadata", - //! "metadata_versions", - //! Vec::>::new() - //! ); - //! ``` - //! - //! All valid runtime calls implement [`crate::runtime_api::RuntimeApiPayload`], a trait which - //! describes how to encode the runtime call arguments and what return type to decode from the - //! response. - //! - //! ## Submitting it - //! - //! Runtime calls can be handed to [`crate::runtime_api::RuntimeApi::call()`], which will submit - //! them and hand back the associated response. - //! - //! ### Making a static Runtime API call - //! - //! The easiest way to make a runtime API call is to use the statically generated interface. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{config::PolkadotConfig, OnlineClient}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Create a runtime API payload that calls into - // `AccountNonceApi_account_nonce` function. - let account = dev::alice().public_key().into(); - let runtime_api_call = polkadot::apis().account_nonce_api().account_nonce(account); - - // Submit the call and get back a result. - let nonce = api - .runtime_api() - .at_latest() - .await? - .call(runtime_api_call) - .await; - - println!("AccountNonceApi_account_nonce for Alice: {:?}", nonce); - Ok(()) -} -*/ - //! ``` - //! - //! ### Making a dynamic Runtime API call - //! - //! If you'd prefer to construct the call at runtime, you can do this using the - //! [`crate::dynamic::runtime_api_call`] method. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::dynamic::Value; -use subxt::{config::PolkadotConfig, OnlineClient}; -use subxt_signer::sr25519::dev; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Create a dynamically runtime API payload that calls the - // `AccountNonceApi_account_nonce` function. - let account = dev::alice().public_key(); - let runtime_api_call = subxt::dynamic::runtime_api_call( - "AccountNonceApi", - "account_nonce", - vec![Value::from_bytes(account)], - ); - - // Submit the call to get back a result. - let nonce = api - .runtime_api() - .at_latest() - .await? - .call(runtime_api_call) - .await?; - - println!("Account nonce: {:#?}", nonce.to_value()); - Ok(()) -} -*/ - //! ``` - //! - //! ### Making a raw call - //! - //! This is generally discouraged in favour of one of the above, but may be necessary (especially if - //! the node you're talking to does not yet serve V15 metadata). Here, you must manually encode - //! the argument bytes and manually provide a type for the response bytes to be decoded into. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::ext::codec::Compact; -use subxt::ext::frame_metadata::RuntimeMetadataPrefixed; -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Use runtime APIs at the latest block: - let runtime_apis = api.runtime_api().at_latest().await?; - - // Ask for metadata and decode it: - let (_, meta): (Compact, RuntimeMetadataPrefixed) = - runtime_apis.call_raw("Metadata_metadata", None).await?; - - println!("{meta:?}"); - Ok(()) -} -*/ - //! ``` - //! - } - pub mod storage { - //! # Storage - //! - //! A Substrate based chain can be seen as a key/value database which starts off at some initial - //! state, and is modified by the extrinsics in each block. This database is referred to as the - //! node storage. With Subxt, you can query this key/value storage with the following steps: - //! - //! 1. [Constructing a storage query](#constructing-a-storage-query). - //! 2. [Submitting the query to get back the associated values](#submitting-it). - //! - //! ## Constructing a storage query - //! - //! We can use the statically generated interface to build storage queries: - //! - //! ```rust,no_run - //! use subxt_signer::sr25519::dev; - //! - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] - //! pub mod polkadot {} - //! - //! let account = dev::alice().public_key().into(); - //! let storage_query = polkadot::storage().system().account(&account); - //! ``` - //! - //! Alternately, we can dynamically construct a storage query. This will not be type checked or - //! validated until it's submitted: - //! - //! ```rust,no_run - //! use subxt_signer::sr25519::dev; - //! use subxt::dynamic::Value; - //! - //! let account = dev::alice().public_key(); - //! let storage_query = subxt::dynamic::storage("System", "Account", vec![ - //! Value::from_bytes(account) - //! ]); - //! ``` - //! - //! As well as accessing specific entries, some storage locations can also be iterated over (such as - //! the map of account information). To do this, suffix `_iter` onto the query constructor (this - //! will only be available on static constructors when iteration is actually possible): - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] - //! pub mod polkadot {} - //! - //! // A static query capable of iterating over accounts: - //! let storage_query = polkadot::storage().system().account_iter(); - //! // A dynamic query to do the same: - //! let storage_query = subxt::dynamic::storage("System", "Account", ()); - //! ``` - //! - //! Some storage entries are maps with multiple keys. As an example, we might end up with - //! an API like `runtime::storage().foo().bar(u8, bool, u16, String)` to fetch some entry "bar". - //! When this is the case, the codegen will generate multiple iterator query functions alongside - //! the function to fetch an individual value: - //! - //! - `runtime::storage().foo().bar(u8, bool, u16, String)`: fetch a single entry from the "bar" map. - //! - `runtime::storage().foo().bar_iter()`: iterate over all of the entries in the "bar" map. - //! - `runtime::storage().foo().bar_iter1(u8)`: iterate over all of the entries in the "bar" map under - //! a given `u8`. - //! - `runtime::storage().foo().bar_iter2(u8, bool)`: iterate over all of the entries in the "bar" map under - //! a given `u8` and `bool` value. - //! - `runtime::storage().foo().bar_iter3(u8, bool, u16)`: iterate over all of the entries in the "bar" map under - //! a given `u8`, `bool` and `u16` value. - //! - //! All valid storage queries implement [`crate::storage::StorageAddress`]. As well as describing - //! how to build a valid storage query, this trait also has some associated types that determine the - //! shape of the result you'll get back, and determine what you can do with it (ie, can you iterate - //! over storage entries using it). - //! - //! Static queries set appropriate values for these associated types, and can therefore only be used - //! where it makes sense. Dynamic queries don't know any better and can be used in more places, but - //! may fail at runtime instead if they are invalid in those places. - //! - //! ## Submitting it - //! - //! Storage queries can be handed to various functions in [`crate::storage::Storage`] in order to - //! obtain the associated values (also referred to as storage entries) back. - //! - //! ### Fetching storage entries - //! - //! The simplest way to access storage entries is to construct a query and then call either - //! [`crate::storage::Storage::fetch()`] or [`crate::storage::Storage::fetch_or_default()`] (the - //! latter will only work for storage queries that have a default value when empty): - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a storage query to access account information. - let account = dev::alice().public_key().into(); - let storage_query = polkadot::storage().system().account(&account); - - // Use that query to `fetch` a result. This returns an `Option<_>`, which will be - // `None` if no value exists at the given address. You can also use `fetch_default` - // where applicable, which will return the default value if none exists. - let result = api - .storage() - .at_latest() - .await? - .fetch(&storage_query) - .await?; - - println!("Alice has free balance: {}", result.unwrap().data.free); - Ok(()) -} -*/ - //! ``` - //! - //! For completeness, below is an example using a dynamic query instead. The return type from a - //! dynamic query is a [`crate::dynamic::DecodedValueThunk`], which can be decoded into a - //! [`crate::dynamic::Value`], or else the raw bytes can be accessed instead. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::dynamic::{At, Value}; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a dynamic storage query to access account information. - let account = dev::alice().public_key(); - let storage_query = - subxt::dynamic::storage("System", "Account", vec![Value::from_bytes(account)]); - - // Use that query to `fetch` a result. Because the query is dynamic, we don't know what the result - // type will be either, and so we get a type back that can be decoded into a dynamic Value type. - let result = api - .storage() - .at_latest() - .await? - .fetch(&storage_query) - .await?; - let value = result.unwrap().to_value()?; - - println!("Alice has free balance: {:?}", value.at("data").at("free")); - Ok(()) -} -*/ - //! ``` - //! - //! ### Iterating storage entries - //! - //! Many storage entries are maps of values; as well as fetching individual values, it's possible to - //! iterate over all of the values stored at that location: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a storage query to iterate over account information. - let storage_query = polkadot::storage().system().account_iter(); - - // Get back an iterator of results (here, we are fetching 10 items at - // a time from the node, but we always iterate over one at a time). - let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - - while let Some(Ok(kv)) = results.next().await { - println!("Keys decoded: {:?}", kv.keys); - println!("Key: 0x{}", hex::encode(&kv.key_bytes)); - println!("Value: {:?}", kv.value); - } - - Ok(()) -} -*/ - //! ``` - //! - //! Here's the same logic but using dynamically constructed values instead: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a dynamic storage query to iterate account information. - // With a dynamic query, we can just provide an empty vector as the keys to iterate over all entries. - let keys: Vec = vec![]; - let storage_query = subxt::dynamic::storage("System", "Account", keys); - - // Use that query to return an iterator over the results. - let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - - while let Some(Ok(kv)) = results.next().await { - println!("Keys decoded: {:?}", kv.keys); - println!("Key: 0x{}", hex::encode(&kv.key_bytes)); - println!("Value: {:?}", kv.value.to_value()?); - } - - Ok(()) -} -*/ - //! ``` - //! - //! Here is an example of iterating over partial keys. In this example some multi-signature operations - //! are sent to the node. We can iterate over the pending multisig operations of a single multisig account: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use polkadot::multisig::events::NewMultisig; -use polkadot::runtime_types::{ - frame_system::pallet::Call, rococo_runtime::RuntimeCall, sp_weights::weight_v2::Weight, -}; -use subxt::utils::AccountId32; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::{dev, Keypair}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Prepare the chain to have 3 open multisig requests (2 of them are alice + bob): - let alice_signer = dev::alice(); - let bob = AccountId32(dev::bob().public_key().0); - let charlie = AccountId32(dev::charlie().public_key().0); - - let new_multisig_1 = submit_remark_as_multi(&alice_signer, &bob, b"Hello", &api).await?; - let new_multisig_2 = submit_remark_as_multi(&alice_signer, &bob, b"Hi", &api).await?; - let new_multisig_3 = submit_remark_as_multi(&alice_signer, &charlie, b"Hello", &api).await?; - - // Note: the NewMultisig event contains the multisig address we need to use for the storage queries: - assert_eq!(new_multisig_1.multisig, new_multisig_2.multisig); - assert_ne!(new_multisig_1.multisig, new_multisig_3.multisig); - - // Build a storage query to iterate over open multisig extrinsics from - // new_multisig_1.multisig which is the AccountId of the alice + bob multisig account - let alice_bob_account_id = &new_multisig_1.multisig; - let storage_query = polkadot::storage() - .multisig() - .multisigs_iter1(alice_bob_account_id); - - // Get back an iterator of results. - let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - - while let Some(Ok(kv)) = results.next().await { - println!("Keys decoded: {:?}", kv.keys); - println!("Key: 0x{}", hex::encode(&kv.key_bytes)); - println!("Value: {:?}", kv.value); - } - Ok(()) -} - -async fn submit_remark_as_multi( - signer: &Keypair, - other: &AccountId32, - remark: &[u8], - api: &OnlineClient, -) -> Result> { - let multisig_remark_tx = polkadot::tx().multisig().as_multi( - 2, - vec![other.clone()], - None, - RuntimeCall::System(Call::remark { - remark: remark.to_vec(), - }), - Weight { - ref_time: 0, - proof_size: 0, - }, - ); - let events = api - .tx() - .sign_and_submit_then_watch_default(&multisig_remark_tx, signer) - .await? - .wait_for_finalized_success() - .await?; - let new_multisig = events - .find_first::()? - .expect("should contain event"); - Ok(new_multisig) -} -*/ - //! ``` - //! - //! ### Advanced - //! - //! For more advanced use cases, have a look at [`crate::storage::Storage::fetch_raw`] and - //! [`crate::storage::Storage::fetch_raw_keys`]. Both of these take raw bytes as arguments, which can be - //! obtained from a [`crate::storage::StorageAddress`] by using - //! [`crate::storage::StorageClient::address_bytes()`] or - //! [`crate::storage::StorageClient::address_root_bytes()`]. - //! - } - pub mod transactions { - //! # Transactions - //! - //! A transaction is an extrinsic that's signed (ie it originates from a given address). The purpose - //! of extrinsics is to modify the node storage in a deterministic way, and so being able to submit - //! transactions to a node is one of the core features of Subxt. - //! - //! > Note: the documentation tends to use the terms _extrinsic_ and _transaction_ interchangeably; - //! > An extrinsic is some data that can be added to a block, and is either signed (a _transaction_) - //! > or unsigned (an _inherent_). Subxt can construct either, but overwhelmingly you'll need to - //! > sign the payload you'd like to submit. - //! - //! Submitting a transaction to a node consists of the following steps: - //! - //! 1. [Constructing a transaction payload to submit](#constructing-a-transaction-payload). - //! 2. [Signing it](#signing-it). - //! 3. [Submitting it (optionally with some additional parameters)](#submitting-it). - //! - //! We'll look at each of these steps in turn. - //! - //! ## Constructing a transaction payload - //! - //! We can use the statically generated interface to build transaction payloads: - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] - //! pub mod polkadot {} - //! - //! let remark = "Hello there".as_bytes().to_vec(); - //! let tx_payload = polkadot::tx().system().remark(remark); - //! ``` - //! - //! > If you're not sure what types to import and use to build a given payload, you can use the - //! > `subxt` CLI tool to generate the interface by using something like `subxt codegen | rustfmt > - //! > interface.rs`, to see what types and things are available (or even just to use directly - //! > instead of the [`#[subxt]`](crate::subxt) macro). - //! - //! Alternately, we can dynamically construct a transaction payload. This will not be type checked or - //! validated until it's submitted: - //! - //! ```rust,no_run - //! use subxt::dynamic::Value; - //! - //! let tx_payload = subxt::dynamic::tx("System", "remark", vec![ - //! Value::from_bytes("Hello there") - //! ]); - //! ``` - //! - //! The [`crate::dynamic::Value`] type is a dynamic type much like a `serde_json::Value` but instead - //! represents any type of data that can be SCALE encoded or decoded. It can be serialized, - //! deserialized and parsed from/to strings. - //! - //! A valid transaction payload is just something that implements the [`crate::tx::TxPayload`] trait; - //! you can implement this trait on your own custom types if the built-in ones are not suitable for - //! your needs. - //! - //! ## Signing it - //! - //! You'll normally need to sign an extrinsic to prove that it originated from an account that you - //! control. To do this, you will typically first create a [`crate::tx::Signer`] instance, which tells - //! Subxt who the extrinsic is from, and takes care of signing the relevant details to prove this. - //! - //! There are two main ways to create a compatible signer instance: - //! 1. The `subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`] - //! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled). - //! 2. Alternately, Subxt can use instances of Substrate's `sp_core::Pair` to sign things by wrapping - //! them in a `crate::tx::PairSigner` (requires the `substrate-compat` feature to be enabled). - //! - //! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via - //! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or - //! need additional signing algorithms that `subxt_signer` doesn't support, and don't care about WASM - //! compatibility. - //! - //! Let's see how to use each of these approaches: - //! - //! ```rust - //! # #[cfg(feature = "substrate-compat")] - //! # { - //! use subxt::config::PolkadotConfig; - //! use std::str::FromStr; - //! - //! //// 1. Use a `subxt_signer` impl: - //! use subxt_signer::{ SecretUri, sr25519 }; - //! - //! // Get hold of a `Signer` for a test account: - //! let alice = sr25519::dev::alice(); - //! - //! // Or generate a keypair, here from an SURI: - //! let uri = SecretUri::from_str("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password") - //! .expect("valid URI"); - //! let keypair = sr25519::Keypair::from_uri(&uri) - //! .expect("valid keypair"); - //! - //! //// 2. Use the corresponding `sp_core::Pair` impl: - //! use subxt::tx::PairSigner; - //! use sp_core::Pair; - //! - //! // Get hold of a `Signer` for a test account: - //! let alice = sp_keyring::AccountKeyring::Alice.pair(); - //! let alice = PairSigner::::new(alice); - //! - //! // Or generate a keypair, here from an SURI: - //! let keypair = sp_core::sr25519::Pair::from_string("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password", None) - //! .expect("valid URI"); - //! let keypair = PairSigner::::new(keypair); - //! # - //! # // Test that these all impl Signer trait while we're here: - //! # - //! # fn is_subxt_signer(_signer: impl subxt::tx::Signer) {} - //! # is_subxt_signer(subxt_signer::sr25519::dev::alice()); - //! # is_subxt_signer(subxt_signer::ecdsa::dev::alice()); - //! # is_subxt_signer(PairSigner::::new(sp_keyring::AccountKeyring::Alice.pair())); - //! # } - //! ``` - //! - //! See the `subxt_signer` crate or the `sp_core::Pair` docs for more ways to construct - //! and work with key pairs. - //! - //! If this isn't suitable/available, you can either implement [`crate::tx::Signer`] yourself to use - //! custom signing logic, or you can use some external signing logic, like so: - //! - //! ```rust,no_run - //! # #[tokio::main] - //! # async fn main() -> Result<(), Box> { - //! use subxt::client::OnlineClient; - //! use subxt::config::PolkadotConfig; - //! use subxt::dynamic::Value; - //! - //! // Create client: - //! let client = OnlineClient::::new().await?; - //! - //! // Create a dummy tx payload to sign: - //! let payload = subxt::dynamic::tx("System", "remark", vec![ - //! Value::from_bytes("Hello there") - //! ]); - //! - //! // Construct the tx but don't sign it. You need to provide the nonce - //! // here, or can use `create_partial_signed` to fetch the correct nonce. - //! let partial_tx = client.tx().create_partial_signed_with_nonce( - //! &payload, - //! 0u64, - //! Default::default() - //! )?; - //! - //! // Fetch the payload that needs to be signed: - //! let signer_payload = partial_tx.signer_payload(); - //! - //! // ... At this point, we can hand off the `signer_payload` to be signed externally. - //! // Ultimately we need to be given back a `signature` (or really, anything - //! // that can be SCALE encoded) and an `address`: - //! let signature; - //! let address; - //! # use subxt::tx::Signer; - //! # let signer = subxt_signer::sr25519::dev::alice(); - //! # signature = signer.sign(&signer_payload).into(); - //! # address = signer.public_key().to_address(); - //! - //! // Now we can build an tx, which one can call `submit` or `submit_and_watch` - //! // on to submit to a node and optionally watch the status. - //! let tx = partial_tx.sign_with_address_and_signature( - //! &address, - //! &signature - //! ); - //! # Ok(()) - //! # } - //! ``` - //! - //! ## Submitting it - //! - //! Once we have signed the transaction, we need to submit it. - //! - //! ### The high level API - //! - //! The highest level approach to doing this is to call - //! [`crate::tx::TxClient::sign_and_submit_then_watch_default`]. This hands back a - //! [`crate::tx::TxProgress`] struct which will monitor the transaction status. We can then call - //! [`crate::tx::TxProgress::wait_for_finalized_success()`] to wait for this transaction to make it - //! into a finalized block, check for an `ExtrinsicSuccess` event, and then hand back the events for - //! inspection. This looks like: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let from = dev::alice(); - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} -*/ - //! ``` - //! - //! ### Providing transaction parameters - //! - //! If you'd like to provide parameters (such as mortality) to the transaction, you can use - //! [`crate::tx::TxClient::sign_and_submit_then_watch`] instead: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::config::polkadot::PolkadotExtrinsicParamsBuilder as Params; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - let latest_block = api.blocks().at_latest().await?; - - // Configure the transaction parameters; we give a small tip and set the - // transaction to live for 32 blocks from the `latest_block` above. - let tx_params = Params::new() - .tip(1_000) - .mortal(latest_block.header(), 32) - .build(); - - // submit the transaction: - let from = dev::alice(); - let hash = api.tx().sign_and_submit(&tx, &from, tx_params).await?; - println!("Balance transfer extrinsic submitted with hash : {hash}"); - - Ok(()) -} -*/ - //! ``` - //! - //! This example doesn't wait for the transaction to be included in a block; it just submits it and - //! hopes for the best! - //! - //! ### Custom handling of transaction status updates - //! - //! If you'd like more control or visibility over exactly which status updates are being emitted for - //! the transaction, you can monitor them as they are emitted and react however you choose: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{tx::TxStatus, OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and then monitor the - // progress of it. - let from = dev::alice(); - let mut balance_transfer_progress = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await?; - - while let Some(status) = balance_transfer_progress.next().await { - match status? { - // It's finalized in a block! - TxStatus::InFinalizedBlock(in_block) => { - println!( - "Transaction {:?} is finalized in block {:?}", - in_block.extrinsic_hash(), - in_block.block_hash() - ); - - // grab the events and fail if no ExtrinsicSuccess event seen: - let events = in_block.wait_for_success().await?; - // We can look for events (this uses the static interface; we can also iterate - // over them and dynamically decode them): - let transfer_event = events.find_first::()?; - - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } else { - println!("Failed to find Balances::Transfer Event"); - } - } - // Just log any other status we encounter: - other => { - println!("Status: {other:?}"); - } - } - } - Ok(()) -} -*/ - //! ``` - //! - //! Take a look at the API docs for [`crate::tx::TxProgress`], [`crate::tx::TxStatus`] and - //! [`crate::tx::TxInBlock`] for more options. - //! - } - } -} -pub mod backend { - //! This module exposes a backend trait for Subxt which allows us to get and set - //! the necessary information (probably from a JSON-RPC API, but that's up to the - //! implementation). - pub mod legacy { - //! This module exposes a legacy backend implementation, which relies - //! on the legacy RPC API methods. - pub mod rpc_methods { - //! An interface to call the raw legacy RPC methods. - use crate::backend::rpc::{rpc_params, RpcClient, RpcSubscription}; - use crate::metadata::Metadata; - use crate::{Config, Error}; - use codec::Decode; - use derivative::Derivative; - use primitive_types::U256; - use serde::{Deserialize, Serialize}; - /// An interface to call the legacy RPC methods. This interface is instantiated with - /// some `T: Config` trait which determines some of the types that the RPC methods will - /// take or hand back. - #[derivative(Clone(bound = ""), Debug(bound = ""))] - pub struct LegacyRpcMethods { - client: RpcClient, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for LegacyRpcMethods { - fn clone(&self) -> Self { - match *self { - LegacyRpcMethods { - client: ref __arg_0, - _marker: ref __arg_1, - } => { - LegacyRpcMethods { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for LegacyRpcMethods { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - LegacyRpcMethods { - client: ref __arg_0, - _marker: ref __arg_1, - } => { - let mut __debug_trait_builder = __f - .debug_struct("LegacyRpcMethods"); - let _ = __debug_trait_builder.field("client", &&(*__arg_0)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - impl LegacyRpcMethods { - /// Instantiate the legacy RPC method interface. - pub fn new(client: RpcClient) -> Self { - LegacyRpcMethods { - client, - _marker: std::marker::PhantomData, - } - } - /// Fetch the raw bytes for a given storage key - pub async fn state_get_storage( - &self, - key: &[u8], - hash: Option, - ) -> Result, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(key)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let data: Option = self - .client - .request("state_getStorage", params) - .await?; - Ok(data.map(|b| b.0)) - } - /// Returns the keys with prefix with pagination support. - /// Up to `count` keys will be returned. - /// If `start_key` is passed, return next keys in storage in lexicographic order. - pub async fn state_get_keys_paged( - &self, - key: &[u8], - count: u32, - start_key: Option<&[u8]>, - at: Option, - ) -> Result, Error> { - let start_key = start_key.map(to_hex); - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(key)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(count) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(start_key) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let data: Vec = self - .client - .request("state_getKeysPaged", params) - .await?; - Ok(data.into_iter().map(|b| b.0).collect()) - } - /// Query historical storage entries in the range from the start block to the end block, - /// defaulting the end block to the current best block if it's not given. The first - /// [`StorageChangeSet`] returned has all of the values for each key, and subsequent ones - /// only contain values for any keys which have changed since the last. - pub async fn state_query_storage( - &self, - keys: impl IntoIterator, - from: T::Hash, - to: Option, - ) -> Result>, Error> { - let keys: Vec = keys.into_iter().map(to_hex).collect(); - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(keys) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(from) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(to) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client - .request("state_queryStorage", params) - .await - .map_err(Into::into) - } - /// Query storage entries at some block, using the best block if none is given. - /// This essentially provides a way to ask for a batch of values given a batch of keys, - /// despite the name of the [`StorageChangeSet`] type. - pub async fn state_query_storage_at( - &self, - keys: impl IntoIterator, - at: Option, - ) -> Result>, Error> { - let keys: Vec = keys.into_iter().map(to_hex).collect(); - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(keys) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client - .request("state_queryStorageAt", params) - .await - .map_err(Into::into) - } - /// Fetch the genesis hash - pub async fn genesis_hash(&self) -> Result { - let block_zero = 0u32; - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(block_zero) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let genesis_hash: Option = self - .client - .request("chain_getBlockHash", params) - .await?; - genesis_hash.ok_or_else(|| "Genesis hash not found".into()) - } - /// Fetch the metadata via the legacy `state_getMetadata` RPC method. - pub async fn state_get_metadata( - &self, - at: Option, - ) -> Result { - let bytes: Bytes = self - .client - .request( - "state_getMetadata", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - let metadata = Metadata::decode(&mut &bytes[..])?; - Ok(metadata) - } - /// Fetch system health - pub async fn system_health(&self) -> Result { - self.client - .request( - "system_health", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch system chain - pub async fn system_chain(&self) -> Result { - self.client - .request( - "system_chain", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch system name - pub async fn system_name(&self) -> Result { - self.client - .request( - "system_name", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch system version - pub async fn system_version(&self) -> Result { - self.client - .request( - "system_version", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch system properties - pub async fn system_properties( - &self, - ) -> Result { - self.client - .request( - "system_properties", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch next nonce for an Account - /// - /// Return account nonce adjusted for extrinsics currently in transaction pool - pub async fn system_account_next_index( - &self, - account_id: &T::AccountId, - ) -> Result - where - T::AccountId: Serialize, - { - self.client - .request( - "system_accountNextIndex", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(&account_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await - } - /// Get a header - pub async fn chain_get_header( - &self, - hash: Option, - ) -> Result, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let header = self.client.request("chain_getHeader", params).await?; - Ok(header) - } - /// Get a block hash, returns hash of latest _best_ block by default. - pub async fn chain_get_block_hash( - &self, - block_number: Option, - ) -> Result, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(block_number) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let block_hash = self - .client - .request("chain_getBlockHash", params) - .await?; - Ok(block_hash) - } - /// Get a block hash of the latest finalized block - pub async fn chain_get_finalized_head(&self) -> Result { - let hash = self - .client - .request( - "chain_getFinalizedHead", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await?; - Ok(hash) - } - /// Get a Block - pub async fn chain_get_block( - &self, - hash: Option, - ) -> Result>, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let block = self.client.request("chain_getBlock", params).await?; - Ok(block) - } - /// Reexecute the specified `block_hash` and gather statistics while doing so. - /// - /// This function requires the specified block and its parent to be available - /// at the queried node. If either the specified block or the parent is pruned, - /// this function will return `None`. - pub async fn dev_get_block_stats( - &self, - block_hash: T::Hash, - ) -> Result, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(block_hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let stats = self.client.request("dev_getBlockStats", params).await?; - Ok(stats) - } - /// Get proof of storage entries at a specific block's state. - pub async fn state_get_read_proof( - &self, - keys: impl IntoIterator, - hash: Option, - ) -> Result, Error> { - let keys: Vec = keys.into_iter().map(to_hex).collect(); - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(keys) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let proof = self.client.request("state_getReadProof", params).await?; - Ok(proof) - } - /// Fetch the runtime version - pub async fn state_get_runtime_version( - &self, - at: Option, - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let version = self - .client - .request("state_getRuntimeVersion", params) - .await?; - Ok(version) - } - /// Subscribe to all new best block headers. - pub async fn chain_subscribe_new_heads( - &self, - ) -> Result, Error> { - let subscription = self - .client - .subscribe( - "chain_subscribeNewHeads", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - "chain_unsubscribeNewHeads", - ) - .await?; - Ok(subscription) - } - /// Subscribe to all new block headers. - pub async fn chain_subscribe_all_heads( - &self, - ) -> Result, Error> { - let subscription = self - .client - .subscribe( - "chain_subscribeAllHeads", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - "chain_unsubscribeAllHeads", - ) - .await?; - Ok(subscription) - } - /// Subscribe to finalized block headers. - /// - /// Note: this may not produce _every_ block in the finalized chain; - /// sometimes multiple blocks are finalized at once, and in this case only the - /// latest one is returned. the higher level APIs that use this "fill in" the - /// gaps for us. - pub async fn chain_subscribe_finalized_heads( - &self, - ) -> Result, Error> { - let subscription = self - .client - .subscribe( - "chain_subscribeFinalizedHeads", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - "chain_unsubscribeFinalizedHeads", - ) - .await?; - Ok(subscription) - } - /// Subscribe to runtime version updates that produce changes in the metadata. - /// The first item emitted by the stream is the current runtime version. - pub async fn state_subscribe_runtime_version( - &self, - ) -> Result, Error> { - let subscription = self - .client - .subscribe( - "state_subscribeRuntimeVersion", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - "state_unsubscribeRuntimeVersion", - ) - .await?; - Ok(subscription) - } - /// Create and submit an extrinsic and return corresponding Hash if successful - pub async fn author_submit_extrinsic( - &self, - extrinsic: &[u8], - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(extrinsic)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let xt_hash = self - .client - .request("author_submitExtrinsic", params) - .await?; - Ok(xt_hash) - } - /// Create and submit an extrinsic and return a subscription to the events triggered. - pub async fn author_submit_and_watch_extrinsic( - &self, - extrinsic: &[u8], - ) -> Result>, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(extrinsic)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let subscription = self - .client - .subscribe( - "author_submitAndWatchExtrinsic", - params, - "author_unwatchExtrinsic", - ) - .await?; - Ok(subscription) - } - /// Insert a key into the keystore. - pub async fn author_insert_key( - &self, - key_type: String, - suri: String, - public: Vec, - ) -> Result<(), Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(key_type) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(suri) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(Bytes(public)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client.request("author_insertKey", params).await?; - Ok(()) - } - /// Generate new session keys and returns the corresponding public keys. - pub async fn author_rotate_keys(&self) -> Result, Error> { - let bytes: Bytes = self - .client - .request( - "author_rotateKeys", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await?; - Ok(bytes.0) - } - /// Checks if the keystore has private keys for the given session public keys. - /// - /// `session_keys` is the SCALE encoded session keys object from the runtime. - /// - /// Returns `true` if all private keys could be found. - pub async fn author_has_session_keys( - &self, - session_keys: Vec, - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(Bytes(session_keys)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client.request("author_hasSessionKeys", params).await - } - /// Checks if the keystore has private keys for the given public key and key type. - /// - /// Returns `true` if a private key could be found. - pub async fn author_has_key( - &self, - public_key: Vec, - key_type: String, - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(Bytes(public_key)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(key_type) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client.request("author_hasKey", params).await - } - /// Execute a runtime API call via `state_call` RPC method. - pub async fn state_call( - &self, - function: &str, - call_parameters: Option<&[u8]>, - at: Option, - ) -> Result, Error> { - let call_parameters = call_parameters.unwrap_or_default(); - let bytes: Bytes = self - .client - .request( - "state_call", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(function) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(to_hex(call_parameters)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(bytes.0) - } - /// Submits the extrinsic to the dry_run RPC, to test if it would succeed. - /// - /// Returns a [`DryRunResult`], which is the result of performing the dry run. - pub async fn dry_run( - &self, - encoded_signed: &[u8], - at: Option, - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(encoded_signed)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let result_bytes: Bytes = self - .client - .request("system_dryRun", params) - .await?; - Ok(DryRunResultBytes(result_bytes.0)) - } - } - /// Storage key. - pub type StorageKey = Vec; - /// Storage data. - pub type StorageData = Vec; - /// Health struct returned by the RPC - #[serde(rename_all = "camelCase")] - pub struct SystemHealth { - /// Number of connected peers - pub peers: usize, - /// Is the node syncing - pub is_syncing: bool, - /// Should this node have any peers - /// - /// Might be false for local chains or when running without discovery. - pub should_have_peers: bool, - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SystemHealth { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "peers" => _serde::__private::Ok(__Field::__field0), - "isSyncing" => _serde::__private::Ok(__Field::__field1), - "shouldHavePeers" => { - _serde::__private::Ok(__Field::__field2) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"peers" => _serde::__private::Ok(__Field::__field0), - b"isSyncing" => _serde::__private::Ok(__Field::__field1), - b"shouldHavePeers" => { - _serde::__private::Ok(__Field::__field2) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SystemHealth; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct SystemHealth", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - usize, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SystemHealth with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - bool, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct SystemHealth with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - bool, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct SystemHealth with 3 elements", - ), - ); - } - }; - _serde::__private::Ok(SystemHealth { - peers: __field0, - is_syncing: __field1, - should_have_peers: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("peers"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "isSyncing", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "shouldHavePeers", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("peers")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("isSyncing")? - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("shouldHavePeers")? - } - }; - _serde::__private::Ok(SystemHealth { - peers: __field0, - is_syncing: __field1, - should_have_peers: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "peers", - "isSyncing", - "shouldHavePeers", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SystemHealth", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for SystemHealth { - #[inline] - fn clone(&self) -> SystemHealth { - SystemHealth { - peers: ::core::clone::Clone::clone(&self.peers), - is_syncing: ::core::clone::Clone::clone(&self.is_syncing), - should_have_peers: ::core::clone::Clone::clone( - &self.should_have_peers, - ), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for SystemHealth { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "SystemHealth", - "peers", - &self.peers, - "is_syncing", - &self.is_syncing, - "should_have_peers", - &&self.should_have_peers, - ) - } - } - /// System properties; an arbitrary JSON object. - pub type SystemProperties = serde_json::Map; - /// A block number - pub type BlockNumber = NumberOrHex; - /// The response from `chain_getBlock` - #[serde(bound = "T: Config")] - pub struct BlockDetails { - /// The block itself. - pub block: Block, - /// Block justification. - pub justifications: Option>, - } - #[automatically_derived] - impl ::core::fmt::Debug for BlockDetails { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "BlockDetails", - "block", - &self.block, - "justifications", - &&self.justifications, - ) - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, T: Config> _serde::Deserialize<'de> for BlockDetails - where - T: Config, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "block" => _serde::__private::Ok(__Field::__field0), - "justifications" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"block" => _serde::__private::Ok(__Field::__field0), - b"justifications" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, T: Config> - where - T: Config, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, T: Config> _serde::de::Visitor<'de> - for __Visitor<'de, T> - where - T: Config, - { - type Value = BlockDetails; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct BlockDetails", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Block, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct BlockDetails with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Option>, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct BlockDetails with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(BlockDetails { - block: __field0, - justifications: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option> = _serde::__private::None; - let mut __field1: _serde::__private::Option< - Option>, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("block"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "justifications", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option>, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("block")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("justifications")? - } - }; - _serde::__private::Ok(BlockDetails { - block: __field0, - justifications: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "block", - "justifications", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "BlockDetails", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Block details in the [`BlockDetails`]. - pub struct Block { - /// The block header. - pub header: T::Header, - /// The accompanying extrinsics. - pub extrinsics: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for Block - where - T::Header: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Block", - "header", - &self.header, - "extrinsics", - &&self.extrinsics, - ) - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, T: Config> _serde::Deserialize<'de> for Block - where - T::Header: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "header" => _serde::__private::Ok(__Field::__field0), - "extrinsics" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"header" => _serde::__private::Ok(__Field::__field0), - b"extrinsics" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, T: Config> - where - T::Header: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, T: Config> _serde::de::Visitor<'de> - for __Visitor<'de, T> - where - T::Header: _serde::Deserialize<'de>, - { - type Value = Block; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct Block", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - T::Header, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Block with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Block with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(Block { - header: __field0, - extrinsics: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option> = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("header"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "extrinsics", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("header")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("extrinsics")? - } - }; - _serde::__private::Ok(Block { - header: __field0, - extrinsics: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "header", - "extrinsics", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Block", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// An abstraction over justification for a block's validity under a consensus algorithm. - pub type BlockJustification = (ConsensusEngineId, EncodedJustification); - /// Consensus engine unique ID. - pub type ConsensusEngineId = [u8; 4]; - /// The encoded justification specific to a consensus engine. - pub type EncodedJustification = Vec; - /// This contains the runtime version information necessary to make transactions, as obtained from - /// the RPC call `state_getRuntimeVersion`, - #[serde(rename_all = "camelCase")] - pub struct RuntimeVersion { - /// Version of the runtime specification. A full-node will not attempt to use its native - /// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, - /// `spec_version` and `authoring_version` are the same between Wasm and native. - pub spec_version: u32, - /// All existing dispatches are fully compatible when this number doesn't change. If this - /// number changes, then `spec_version` must change, also. - /// - /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, - /// either through an alteration in its user-level semantics, a parameter - /// added/removed/changed, a dispatchable being removed, a module being removed, or a - /// dispatchable/module changing its index. - /// - /// It need *not* change when a new module is added or when a dispatchable is added. - pub transaction_version: u32, - /// Fields unnecessary to Subxt are written out to this map. - #[serde(flatten)] - pub other: std::collections::HashMap, - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeVersion { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "RuntimeVersion", - "spec_version", - &self.spec_version, - "transaction_version", - &self.transaction_version, - "other", - &&self.other, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeVersion { - #[inline] - fn clone(&self) -> RuntimeVersion { - RuntimeVersion { - spec_version: ::core::clone::Clone::clone(&self.spec_version), - transaction_version: ::core::clone::Clone::clone( - &self.transaction_version, - ), - other: ::core::clone::Clone::clone(&self.other), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeVersion {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeVersion { - #[inline] - fn eq(&self, other: &RuntimeVersion) -> bool { - self.spec_version == other.spec_version - && self.transaction_version == other.transaction_version - && self.other == other.other - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeVersion { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq< - std::collections::HashMap, - >; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RuntimeVersion { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field<'de> { - __field0, - __field1, - __other(_serde::__private::de::Content<'de>), - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field<'de>; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_bool<__E>( - self, - __value: bool, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::Bool(__value), - ), - ) - } - fn visit_i8<__E>( - self, - __value: i8, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I8(__value), - ), - ) - } - fn visit_i16<__E>( - self, - __value: i16, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I16(__value), - ), - ) - } - fn visit_i32<__E>( - self, - __value: i32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I32(__value), - ), - ) - } - fn visit_i64<__E>( - self, - __value: i64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I64(__value), - ), - ) - } - fn visit_u8<__E>( - self, - __value: u8, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U8(__value), - ), - ) - } - fn visit_u16<__E>( - self, - __value: u16, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U16(__value), - ), - ) - } - fn visit_u32<__E>( - self, - __value: u32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U32(__value), - ), - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U64(__value), - ), - ) - } - fn visit_f32<__E>( - self, - __value: f32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::F32(__value), - ), - ) - } - fn visit_f64<__E>( - self, - __value: f64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::F64(__value), - ), - ) - } - fn visit_char<__E>( - self, - __value: char, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::Char(__value), - ), - ) - } - fn visit_unit<__E>( - self, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other(_serde::__private::de::Content::Unit), - ) - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "specVersion" => _serde::__private::Ok(__Field::__field0), - "transactionVersion" => { - _serde::__private::Ok(__Field::__field1) - } - _ => { - let __value = _serde::__private::de::Content::String( - _serde::__private::ToString::to_string(__value), - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"specVersion" => _serde::__private::Ok(__Field::__field0), - b"transactionVersion" => { - _serde::__private::Ok(__Field::__field1) - } - _ => { - let __value = _serde::__private::de::Content::ByteBuf( - __value.to_vec(), - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_borrowed_str<__E>( - self, - __value: &'de str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "specVersion" => _serde::__private::Ok(__Field::__field0), - "transactionVersion" => { - _serde::__private::Ok(__Field::__field1) - } - _ => { - let __value = _serde::__private::de::Content::Str(__value); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_borrowed_bytes<__E>( - self, - __value: &'de [u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"specVersion" => _serde::__private::Ok(__Field::__field0), - b"transactionVersion" => { - _serde::__private::Ok(__Field::__field1) - } - _ => { - let __value = _serde::__private::de::Content::Bytes( - __value, - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field<'de> { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = RuntimeVersion; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct RuntimeVersion", - ) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __collect = _serde::__private::Vec::< - _serde::__private::Option< - ( - _serde::__private::de::Content, - _serde::__private::de::Content, - ), - >, - >::new(); - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "specVersion", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "transactionVersion", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__other(__name) => { - __collect - .push( - _serde::__private::Some(( - __name, - _serde::de::MapAccess::next_value(&mut __map)?, - )), - ); - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("specVersion")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("transactionVersion")? - } - }; - let __field2: std::collections::HashMap< - String, - serde_json::Value, - > = _serde::de::Deserialize::deserialize( - _serde::__private::de::FlatMapDeserializer( - &mut __collect, - _serde::__private::PhantomData, - ), - )?; - _serde::__private::Ok(RuntimeVersion { - spec_version: __field0, - transaction_version: __field1, - other: __field2, - }) - } - } - _serde::Deserializer::deserialize_map( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Possible transaction status events. - /// - /// # Note - /// - /// This is copied from `sp-transaction-pool` to avoid a dependency on that crate. Therefore it - /// must be kept compatible with that type from the target substrate version. - #[serde(rename_all = "camelCase")] - pub enum TransactionStatus { - /// Transaction is part of the future queue. - Future, - /// Transaction is part of the ready queue. - Ready, - /// The transaction has been broadcast to the given peers. - Broadcast(Vec), - /// Transaction has been included in block with given hash. - InBlock(Hash), - /// The block this transaction was included in has been retracted. - Retracted(Hash), - /// Maximum number of finality watchers has been reached, - /// old watchers are being removed. - FinalityTimeout(Hash), - /// Transaction has been finalized by a finality-gadget, e.g GRANDPA - Finalized(Hash), - /// Transaction has been replaced in the pool, by another transaction - /// that provides the same tags. (e.g. same (sender, nonce)). - Usurped(Hash), - /// Transaction has been dropped from the pool because of the limit. - Dropped, - /// Transaction is no longer valid in the current state. - Invalid, - } - #[automatically_derived] - impl ::core::fmt::Debug - for TransactionStatus { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionStatus::Future => { - ::core::fmt::Formatter::write_str(f, "Future") - } - TransactionStatus::Ready => { - ::core::fmt::Formatter::write_str(f, "Ready") - } - TransactionStatus::Broadcast(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Broadcast", - &__self_0, - ) - } - TransactionStatus::InBlock(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InBlock", - &__self_0, - ) - } - TransactionStatus::Retracted(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Retracted", - &__self_0, - ) - } - TransactionStatus::FinalityTimeout(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "FinalityTimeout", - &__self_0, - ) - } - TransactionStatus::Finalized(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Finalized", - &__self_0, - ) - } - TransactionStatus::Usurped(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Usurped", - &__self_0, - ) - } - TransactionStatus::Dropped => { - ::core::fmt::Formatter::write_str(f, "Dropped") - } - TransactionStatus::Invalid => { - ::core::fmt::Formatter::write_str(f, "Invalid") - } - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for TransactionStatus - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __field6, - __field7, - __field8, - __field9, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - 5u64 => _serde::__private::Ok(__Field::__field5), - 6u64 => _serde::__private::Ok(__Field::__field6), - 7u64 => _serde::__private::Ok(__Field::__field7), - 8u64 => _serde::__private::Ok(__Field::__field8), - 9u64 => _serde::__private::Ok(__Field::__field9), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 10", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "future" => _serde::__private::Ok(__Field::__field0), - "ready" => _serde::__private::Ok(__Field::__field1), - "broadcast" => _serde::__private::Ok(__Field::__field2), - "inBlock" => _serde::__private::Ok(__Field::__field3), - "retracted" => _serde::__private::Ok(__Field::__field4), - "finalityTimeout" => { - _serde::__private::Ok(__Field::__field5) - } - "finalized" => _serde::__private::Ok(__Field::__field6), - "usurped" => _serde::__private::Ok(__Field::__field7), - "dropped" => _serde::__private::Ok(__Field::__field8), - "invalid" => _serde::__private::Ok(__Field::__field9), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"future" => _serde::__private::Ok(__Field::__field0), - b"ready" => _serde::__private::Ok(__Field::__field1), - b"broadcast" => _serde::__private::Ok(__Field::__field2), - b"inBlock" => _serde::__private::Ok(__Field::__field3), - b"retracted" => _serde::__private::Ok(__Field::__field4), - b"finalityTimeout" => { - _serde::__private::Ok(__Field::__field5) - } - b"finalized" => _serde::__private::Ok(__Field::__field6), - b"usurped" => _serde::__private::Ok(__Field::__field7), - b"dropped" => _serde::__private::Ok(__Field::__field8), - b"invalid" => _serde::__private::Ok(__Field::__field9), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "enum TransactionStatus", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(TransactionStatus::Future) - } - (__Field::__field1, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(TransactionStatus::Ready) - } - (__Field::__field2, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Vec, - >(__variant), - TransactionStatus::Broadcast, - ) - } - (__Field::__field3, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::InBlock, - ) - } - (__Field::__field4, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::Retracted, - ) - } - (__Field::__field5, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::FinalityTimeout, - ) - } - (__Field::__field6, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::Finalized, - ) - } - (__Field::__field7, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::Usurped, - ) - } - (__Field::__field8, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(TransactionStatus::Dropped) - } - (__Field::__field9, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(TransactionStatus::Invalid) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "future", - "ready", - "broadcast", - "inBlock", - "retracted", - "finalityTimeout", - "finalized", - "usurped", - "dropped", - "invalid", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "TransactionStatus", - VARIANTS, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The decoded result returned from calling `system_dryRun` on some extrinsic. - pub enum DryRunResult { - /// The transaction could be included in the block and executed. - Success, - /// The transaction could be included in the block, but the call failed to dispatch. - DispatchError(crate::error::DispatchError), - /// The transaction could not be included in the block. - TransactionValidityError, - } - #[automatically_derived] - impl ::core::fmt::Debug for DryRunResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - DryRunResult::Success => { - ::core::fmt::Formatter::write_str(f, "Success") - } - DryRunResult::DispatchError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "DispatchError", - &__self_0, - ) - } - DryRunResult::TransactionValidityError => { - ::core::fmt::Formatter::write_str( - f, - "TransactionValidityError", - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DryRunResult {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DryRunResult { - #[inline] - fn eq(&self, other: &DryRunResult) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - DryRunResult::DispatchError(__self_0), - DryRunResult::DispatchError(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DryRunResult { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - /// The bytes representing an error dry running an extrinsic. call [`DryRunResultBytes::into_dry_run_result`] - /// to attempt to decode this into something more meaningful. - pub struct DryRunResultBytes(pub Vec); - impl DryRunResultBytes { - /// Attempt to decode the error bytes into a [`DryRunResult`] using the provided [`Metadata`]. - pub fn into_dry_run_result( - self, - metadata: &crate::metadata::Metadata, - ) -> Result { - let bytes = self.0; - if bytes[0] == 0 && bytes[1] == 0 { - Ok(DryRunResult::Success) - } else if bytes[0] == 0 && bytes[1] == 1 { - let dispatch_error = crate::error::DispatchError::decode_from( - &bytes[2..], - metadata.clone(), - )?; - Ok(DryRunResult::DispatchError(dispatch_error)) - } else if bytes[0] == 1 { - Ok(DryRunResult::TransactionValidityError) - } else { - Err(crate::Error::Unknown(bytes)) - } - } - } - /// Storage change set - #[serde(rename_all = "camelCase")] - pub struct StorageChangeSet { - /// Block hash - pub block: Hash, - /// A list of changes; tuples of storage key and optional storage data. - pub changes: Vec<(Bytes, Option)>, - } - #[automatically_derived] - impl ::core::clone::Clone - for StorageChangeSet { - #[inline] - fn clone(&self) -> StorageChangeSet { - StorageChangeSet { - block: ::core::clone::Clone::clone(&self.block), - changes: ::core::clone::Clone::clone(&self.changes), - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for StorageChangeSet - where - Hash: _serde::Serialize, - { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "StorageChangeSet", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "block", - &self.block, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "changes", - &self.changes, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for StorageChangeSet - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "block" => _serde::__private::Ok(__Field::__field0), - "changes" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"block" => _serde::__private::Ok(__Field::__field0), - b"changes" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - StorageChangeSet, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = StorageChangeSet; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct StorageChangeSet", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct StorageChangeSet with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec<(Bytes, Option)>, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct StorageChangeSet with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(StorageChangeSet { - block: __field0, - changes: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - Vec<(Bytes, Option)>, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("block"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "changes", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Vec<(Bytes, Option)>, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("block")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("changes")? - } - }; - _serde::__private::Ok(StorageChangeSet { - block: __field0, - changes: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["block", "changes"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "StorageChangeSet", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - StorageChangeSet, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageChangeSet {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for StorageChangeSet { - #[inline] - fn eq(&self, other: &StorageChangeSet) -> bool { - self.block == other.block && self.changes == other.changes - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageChangeSet { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq)>>; - } - } - #[automatically_derived] - impl ::core::fmt::Debug - for StorageChangeSet { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "StorageChangeSet", - "block", - &self.block, - "changes", - &&self.changes, - ) - } - } - /// Statistics of a block returned by the `dev_getBlockStats` RPC. - #[serde(rename_all = "camelCase")] - pub struct BlockStats { - /// The length in bytes of the storage proof produced by executing the block. - pub witness_len: u64, - /// The length in bytes of the storage proof after compaction. - pub witness_compact_len: u64, - /// Length of the block in bytes. - /// - /// This information can also be acquired by downloading the whole block. This merely - /// saves some complexity on the client side. - pub block_len: u64, - /// Number of extrinsics in the block. - /// - /// This information can also be acquired by downloading the whole block. This merely - /// saves some complexity on the client side. - pub num_extrinsics: u64, - } - #[automatically_derived] - impl ::core::clone::Clone for BlockStats { - #[inline] - fn clone(&self) -> BlockStats { - BlockStats { - witness_len: ::core::clone::Clone::clone(&self.witness_len), - witness_compact_len: ::core::clone::Clone::clone( - &self.witness_compact_len, - ), - block_len: ::core::clone::Clone::clone(&self.block_len), - num_extrinsics: ::core::clone::Clone::clone(&self.num_extrinsics), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for BlockStats { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "BlockStats", - "witness_len", - &self.witness_len, - "witness_compact_len", - &self.witness_compact_len, - "block_len", - &self.block_len, - "num_extrinsics", - &&self.num_extrinsics, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BlockStats {} - #[automatically_derived] - impl ::core::cmp::PartialEq for BlockStats { - #[inline] - fn eq(&self, other: &BlockStats) -> bool { - self.witness_len == other.witness_len - && self.witness_compact_len == other.witness_compact_len - && self.block_len == other.block_len - && self.num_extrinsics == other.num_extrinsics - } - } - #[automatically_derived] - impl ::core::cmp::Eq for BlockStats { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for BlockStats { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "BlockStats", - false as usize + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "witnessLen", - &self.witness_len, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "witnessCompactLen", - &self.witness_compact_len, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "blockLen", - &self.block_len, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "numExtrinsics", - &self.num_extrinsics, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for BlockStats { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "witnessLen" => _serde::__private::Ok(__Field::__field0), - "witnessCompactLen" => { - _serde::__private::Ok(__Field::__field1) - } - "blockLen" => _serde::__private::Ok(__Field::__field2), - "numExtrinsics" => _serde::__private::Ok(__Field::__field3), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"witnessLen" => _serde::__private::Ok(__Field::__field0), - b"witnessCompactLen" => { - _serde::__private::Ok(__Field::__field1) - } - b"blockLen" => _serde::__private::Ok(__Field::__field2), - b"numExtrinsics" => _serde::__private::Ok(__Field::__field3), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = BlockStats; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct BlockStats", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct BlockStats with 4 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct BlockStats with 4 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct BlockStats with 4 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct BlockStats with 4 elements", - ), - ); - } - }; - _serde::__private::Ok(BlockStats { - witness_len: __field0, - witness_compact_len: __field1, - block_len: __field2, - num_extrinsics: __field3, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option = _serde::__private::None; - let mut __field3: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "witnessLen", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "witnessCompactLen", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "blockLen", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private::Option::is_some(&__field3) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "numExtrinsics", - ), - ); - } - __field3 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("witnessLen")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("witnessCompactLen")? - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("blockLen")? - } - }; - let __field3 = match __field3 { - _serde::__private::Some(__field3) => __field3, - _serde::__private::None => { - _serde::__private::de::missing_field("numExtrinsics")? - } - }; - _serde::__private::Ok(BlockStats { - witness_len: __field0, - witness_compact_len: __field1, - block_len: __field2, - num_extrinsics: __field3, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "witnessLen", - "witnessCompactLen", - "blockLen", - "numExtrinsics", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "BlockStats", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// ReadProof struct returned by the RPC - /// - /// # Note - /// - /// This is copied from `sc-rpc-api` to avoid a dependency on that crate. Therefore it - /// must be kept compatible with that type from the target substrate version. - #[serde(rename_all = "camelCase")] - pub struct ReadProof { - /// Block hash used to generate the proof - pub at: Hash, - /// A proof used to prove that storage entries are included in the storage trie - pub proof: Vec, - } - #[automatically_derived] - impl ::core::clone::Clone for ReadProof { - #[inline] - fn clone(&self) -> ReadProof { - ReadProof { - at: ::core::clone::Clone::clone(&self.at), - proof: ::core::clone::Clone::clone(&self.proof), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ReadProof { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "ReadProof", - "at", - &self.at, - "proof", - &&self.proof, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ReadProof {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for ReadProof { - #[inline] - fn eq(&self, other: &ReadProof) -> bool { - self.at == other.at && self.proof == other.proof - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ReadProof { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ReadProof - where - Hash: _serde::Serialize, - { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "ReadProof", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "at", - &self.at, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "proof", - &self.proof, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for ReadProof - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "at" => _serde::__private::Ok(__Field::__field0), - "proof" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"at" => _serde::__private::Ok(__Field::__field0), - b"proof" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = ReadProof; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct ReadProof", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ReadProof with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct ReadProof with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(ReadProof { - at: __field0, - proof: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option> = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("at"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("proof"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("at")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("proof")? - } - }; - _serde::__private::Ok(ReadProof { - at: __field0, - proof: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["at", "proof"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ReadProof", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// A number type that can be serialized both as a number or a string that encodes a number in a - /// string. - /// - /// We allow two representations of the block number as input. Either we deserialize to the type - /// that is specified in the block type or we attempt to parse given hex value. - /// - /// The primary motivation for having this type is to avoid overflows when using big integers in - /// JavaScript (which we consider as an important RPC API consumer). - #[serde(untagged)] - pub enum NumberOrHex { - /// The number represented directly. - Number(u64), - /// Hex representation of the number. - Hex(U256), - } - #[automatically_derived] - impl ::core::marker::Copy for NumberOrHex {} - #[automatically_derived] - impl ::core::clone::Clone for NumberOrHex { - #[inline] - fn clone(&self) -> NumberOrHex { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for NumberOrHex { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - NumberOrHex::Number(ref __field0) => { - _serde::Serialize::serialize(__field0, __serializer) - } - NumberOrHex::Hex(ref __field0) => { - _serde::Serialize::serialize(__field0, __serializer) - } - } - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for NumberOrHex { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - let __content = <_serde::__private::de::Content as _serde::Deserialize>::deserialize( - __deserializer, - )?; - let __deserializer = _serde::__private::de::ContentRefDeserializer::< - __D::Error, - >::new(&__content); - if let _serde::__private::Ok(__ok) - = _serde::__private::Result::map( - ::deserialize(__deserializer), - NumberOrHex::Number, - ) { - return _serde::__private::Ok(__ok); - } - if let _serde::__private::Ok(__ok) - = _serde::__private::Result::map( - ::deserialize(__deserializer), - NumberOrHex::Hex, - ) { - return _serde::__private::Ok(__ok); - } - _serde::__private::Err( - _serde::de::Error::custom( - "data did not match any variant of untagged enum NumberOrHex", - ), - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for NumberOrHex { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - NumberOrHex::Number(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Number", - &__self_0, - ) - } - NumberOrHex::Hex(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Hex", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for NumberOrHex {} - #[automatically_derived] - impl ::core::cmp::PartialEq for NumberOrHex { - #[inline] - fn eq(&self, other: &NumberOrHex) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - NumberOrHex::Number(__self_0), - NumberOrHex::Number(__arg1_0), - ) => *__self_0 == *__arg1_0, - (NumberOrHex::Hex(__self_0), NumberOrHex::Hex(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for NumberOrHex { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - impl NumberOrHex { - /// Converts this number into an U256. - pub fn into_u256(self) -> U256 { - match self { - NumberOrHex::Number(n) => n.into(), - NumberOrHex::Hex(h) => h, - } - } - } - impl From for U256 { - fn from(num_or_hex: NumberOrHex) -> U256 { - num_or_hex.into_u256() - } - } - impl From for NumberOrHex { - fn from(x: u8) -> Self { - NumberOrHex::Number(x.into()) - } - } - impl From for NumberOrHex { - fn from(x: u16) -> Self { - NumberOrHex::Number(x.into()) - } - } - impl From for NumberOrHex { - fn from(x: u32) -> Self { - NumberOrHex::Number(x.into()) - } - } - impl From for NumberOrHex { - fn from(x: u64) -> Self { - NumberOrHex::Number(x.into()) - } - } - impl From for NumberOrHex { - fn from(n: u128) -> Self { - NumberOrHex::Hex(n.into()) - } - } - impl From for NumberOrHex { - fn from(n: U256) -> Self { - NumberOrHex::Hex(n) - } - } - /// A quick helper to encode some bytes to hex. - fn to_hex(bytes: impl AsRef<[u8]>) -> String { - { - let res = ::alloc::fmt::format( - format_args!("0x{0}", hex::encode(bytes.as_ref())), - ); - res - } - } - /// Hex-serialized shim for `Vec`. - pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec); - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Bytes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Bytes { - #[inline] - fn eq(&self, other: &Bytes) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Bytes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Bytes { - #[inline] - fn clone(&self) -> Bytes { - Bytes(::core::clone::Clone::clone(&self.0)) - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Bytes { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "Bytes", - { - #[doc(hidden)] - struct __SerializeWith<'__a> { - values: (&'__a Vec,), - phantom: _serde::__private::PhantomData, - } - impl<'__a> _serde::Serialize for __SerializeWith<'__a> { - fn serialize<__S>( - &self, - __s: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - impl_serde::serialize::serialize(self.values.0, __s) - } - } - &__SerializeWith { - values: (&self.0,), - phantom: _serde::__private::PhantomData::, - } - }, - ) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Bytes { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Bytes; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "tuple struct Bytes", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: Vec = impl_serde::serialize::deserialize( - __e, - )?; - _serde::__private::Ok(Bytes(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match { - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: Vec, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: impl_serde::serialize::deserialize(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct Bytes with 1 element", - ), - ); - } - }; - _serde::__private::Ok(Bytes(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "Bytes", - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::hash::Hash for Bytes { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Bytes { - #[inline] - fn partial_cmp( - &self, - other: &Bytes, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Bytes { - #[inline] - fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Bytes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Bytes", - &&self.0, - ) - } - } - impl std::ops::Deref for Bytes { - type Target = [u8]; - fn deref(&self) -> &[u8] { - &self.0[..] - } - } - impl From> for Bytes { - fn from(s: Vec) -> Self { - Bytes(s) - } - } - } - use self::rpc_methods::TransactionStatus as RpcTransactionStatus; - use crate::backend::{ - rpc::RpcClient, Backend, BlockRef, RuntimeVersion, StorageResponse, StreamOf, - StreamOfResults, TransactionStatus, - }; - use crate::{config::Header, Config, Error}; - use async_trait::async_trait; - use futures::{ - future, future::Either, stream, Future, FutureExt, Stream, StreamExt, - }; - use std::collections::VecDeque; - use std::pin::Pin; - use std::task::{Context, Poll}; - pub use rpc_methods::LegacyRpcMethods; - /// The legacy backend. - pub struct LegacyBackend { - methods: LegacyRpcMethods, - } - #[automatically_derived] - impl ::core::fmt::Debug for LegacyBackend { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "LegacyBackend", - "methods", - &&self.methods, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for LegacyBackend { - #[inline] - fn clone(&self) -> LegacyBackend { - LegacyBackend { - methods: ::core::clone::Clone::clone(&self.methods), - } - } - } - impl LegacyBackend { - /// Instantiate a new backend which uses the legacy API methods. - pub fn new(client: RpcClient) -> Self { - Self { - methods: LegacyRpcMethods::new(client), - } - } - } - impl super::sealed::Sealed for LegacyBackend {} - impl Backend for LegacyBackend { - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_values<'life0, 'async_trait>( - &'life0 self, - keys: Vec>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let keys = keys; - let at = at; - let __ret: Result, Error> = { - let methods = __self.methods.clone(); - let iter = keys - .into_iter() - .map(move |key| { - let methods = methods.clone(); - async move { - let res = methods.state_get_storage(&key, Some(at)).await?; - Ok(res.map(|value| StorageResponse { key, value })) - } - }); - let s = stream::iter(iter) - .then(|fut| fut) - .filter_map(|r| future::ready(r.transpose())); - Ok(StreamOf(Box::pin(s))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_descendant_keys<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>, Error>, - > { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result>, Error> = { - let keys = StorageFetchDescendantKeysStream { - at, - key, - methods: __self.methods.clone(), - done: Default::default(), - keys_fut: Default::default(), - pagination_start_key: None, - }; - let keys = keys - .flat_map(|keys| { - match keys { - Err(e) => { - Either::Left(stream::iter(std::iter::once(Err(e)))) - } - Ok(keys) => { - Either::Right(stream::iter(keys.into_iter().map(Ok))) - } - } - }); - Ok(StreamOf(Box::pin(keys))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_descendant_values<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result, Error> = { - let keys_stream = StorageFetchDescendantKeysStream { - at, - key, - methods: __self.methods.clone(), - done: Default::default(), - keys_fut: Default::default(), - pagination_start_key: None, - }; - Ok( - StreamOf( - Box::pin(StorageFetchDescendantValuesStream { - keys: keys_stream, - results_fut: None, - results: Default::default(), - }), - ), - ) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn genesis_hash<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let __ret: Result = { - __self.methods.genesis_hash().await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn block_header<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result, Error> = { - __self.methods.chain_get_header(Some(at)).await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn block_body<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>>, Error>, - > { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result>>, Error> = { - let Some(details) = __self - .methods - .chain_get_block(Some(at)) - .await? else { return Ok(None); - }; - Ok( - Some( - details.block.extrinsics.into_iter().map(|b| b.0).collect(), - ), - ) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn latest_finalized_block_ref<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result, Error> = { - let hash = __self.methods.chain_get_finalized_head().await?; - Ok(BlockRef::from_hash(hash)) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn current_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let __ret: Result = { - let details = __self - .methods - .state_get_runtime_version(None) - .await?; - Ok(RuntimeVersion { - spec_version: details.spec_version, - transaction_version: details.transaction_version, - }) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result, Error> = { - let sub = __self - .methods - .state_subscribe_runtime_version() - .await?; - let sub = sub - .map(|r| { - r.map(|v| RuntimeVersion { - spec_version: v.spec_version, - transaction_version: v.transaction_version, - }) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_all_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - let sub = __self.methods.chain_subscribe_all_heads().await?; - let sub = sub - .map(|r| { - r.map(|h| { - let hash = h.hash(); - (h, BlockRef::from_hash(hash)) - }) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_best_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - let sub = __self.methods.chain_subscribe_new_heads().await?; - let sub = sub - .map(|r| { - r.map(|h| { - let hash = h.hash(); - (h, BlockRef::from_hash(hash)) - }) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_finalized_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - let sub: super::rpc::RpcSubscription<::Header> = __self - .methods - .chain_subscribe_finalized_heads() - .await?; - let last_finalized_block_ref = __self - .latest_finalized_block_ref() - .await?; - let last_finalized_block_num = __self - .block_header(last_finalized_block_ref.hash()) - .await? - .map(|h| h.number().into()); - let sub = subscribe_to_block_headers_filling_in_gaps( - __self.methods.clone(), - sub, - last_finalized_block_num, - ); - let sub = sub - .map(|r| { - r.map(|h| { - let hash = h.hash(); - (h, BlockRef::from_hash(hash)) - }) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn submit_transaction<'life0, 'life1, 'async_trait>( - &'life0 self, - extrinsic: &'life1 [u8], - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults>, - Error, - > = { - let sub = __self - .methods - .author_submit_and_watch_extrinsic(extrinsic) - .await?; - let sub = sub - .filter_map(|r| { - let mapped = r - .map(|tx| { - match tx { - RpcTransactionStatus::Future => None, - RpcTransactionStatus::Retracted(_) => None, - RpcTransactionStatus::Ready => { - Some(TransactionStatus::Validated) - } - RpcTransactionStatus::Broadcast(peers) => { - Some(TransactionStatus::Broadcasted { - num_peers: peers.len() as u32, - }) - } - RpcTransactionStatus::InBlock(hash) => { - Some(TransactionStatus::InBestBlock { - hash: BlockRef::from_hash(hash), - }) - } - RpcTransactionStatus::FinalityTimeout(_) => { - Some(TransactionStatus::Invalid { - message: "Finality timeout".into(), - }) - } - RpcTransactionStatus::Finalized(hash) => { - Some(TransactionStatus::InFinalizedBlock { - hash: BlockRef::from_hash(hash), - }) - } - RpcTransactionStatus::Usurped(_) => { - Some(TransactionStatus::Invalid { - message: "Transaction was usurped by another with the same nonce" - .into(), - }) - } - RpcTransactionStatus::Dropped => { - Some(TransactionStatus::Dropped { - message: "Transaction was dropped".into(), - }) - } - RpcTransactionStatus::Invalid => { - Some(TransactionStatus::Invalid { - message: "Transaction is invalid (eg because of a bad nonce, signature etc)" - .into(), - }) - } - } - }) - .transpose(); - future::ready(mapped) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn call<'life0, 'life1, 'life2, 'async_trait>( - &'life0 self, - method: &'life1 str, - call_parameters: Option<&'life2 [u8]>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - 'life2: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::, Error>> { - return __ret; - } - let __self = self; - let call_parameters = call_parameters; - let at = at; - let __ret: Result, Error> = { - __self - .methods - .state_call(method, call_parameters, Some(at)) - .await - }; - #[allow(unreachable_code)] __ret - }) - } - } - /// Note: This is exposed for testing but is not considered stable and may change - /// without notice in a patch release. - #[doc(hidden)] - pub fn subscribe_to_block_headers_filling_in_gaps( - methods: LegacyRpcMethods, - sub: S, - mut last_block_num: Option, - ) -> impl Stream> + Send - where - T: Config, - S: Stream> + Send, - E: Into + Send + 'static, - { - sub.flat_map(move |s| { - let header = match s { - Ok(header) => header, - Err(e) => return Either::Left(stream::once(async { Err(e.into()) })), - }; - let end_block_num = header.number().into(); - let start_block_num = last_block_num - .map(|n| n + 1) - .unwrap_or(end_block_num); - let methods = methods.clone(); - let previous_headers = stream::iter(start_block_num..end_block_num) - .then(move |n| { - let methods = methods.clone(); - async move { - let hash = methods - .chain_get_block_hash(Some(n.into())) - .await?; - let header = methods.chain_get_header(hash).await?; - Ok::<_, Error>(header) - } - }) - .filter_map(|h| async { h.transpose() }); - last_block_num = Some(end_block_num); - Either::Right(previous_headers.chain(stream::once(async { Ok(header) }))) - }) - } - /// How many keys/values to fetch at once. - const STORAGE_PAGE_SIZE: u32 = 32; - /// This provides a stream of values given some prefix `key`. It - /// internally manages pagination and such. - #[allow(clippy::type_complexity)] - pub struct StorageFetchDescendantKeysStream { - methods: LegacyRpcMethods, - key: Vec, - at: T::Hash, - pagination_start_key: Option>, - keys_fut: Option< - Pin< - Box< - dyn Future>, Error>> + Send + 'static, - >, - >, - >, - done: bool, - } - impl std::marker::Unpin for StorageFetchDescendantKeysStream {} - impl Stream for StorageFetchDescendantKeysStream { - type Item = Result>, Error>; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - let mut this = self.as_mut(); - loop { - if this.done { - return Poll::Ready(None); - } - if let Some(mut keys_fut) = this.keys_fut.take() { - let Poll::Ready(keys) = keys_fut.poll_unpin(cx) else { - this.keys_fut = Some(keys_fut); - return Poll::Pending; - }; - match keys { - Ok(keys) => { - if keys.is_empty() { - this.done = true; - return Poll::Ready(None); - } - this.pagination_start_key = keys.last().cloned(); - return Poll::Ready(Some(Ok(keys))); - } - Err(e) => { - return Poll::Ready(Some(Err(e))); - } - } - } - let methods = this.methods.clone(); - let key = this.key.clone(); - let at = this.at; - let pagination_start_key = this.pagination_start_key.take(); - let keys_fut = async move { - methods - .state_get_keys_paged( - &key, - STORAGE_PAGE_SIZE, - pagination_start_key.as_deref(), - Some(at), - ) - .await - }; - this.keys_fut = Some(Box::pin(keys_fut)); - } - } - } - /// This provides a stream of values given some stream of keys. - #[allow(clippy::type_complexity)] - pub struct StorageFetchDescendantValuesStream { - keys: StorageFetchDescendantKeysStream, - results_fut: Option< - Pin< - Box< - dyn Future< - Output = Result, Vec)>>, Error>, - > + Send + 'static, - >, - >, - >, - results: VecDeque<(Vec, Vec)>, - } - impl Stream for StorageFetchDescendantValuesStream { - type Item = Result; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - let mut this = self.as_mut(); - loop { - if let Some((key, value)) = this.results.pop_front() { - let res = StorageResponse { key, value }; - return Poll::Ready(Some(Ok(res))); - } - if let Some(mut results_fut) = this.results_fut.take() { - match results_fut.poll_unpin(cx) { - Poll::Ready(Ok(Some(results))) => { - this.results = results; - continue; - } - Poll::Ready(Ok(None)) => { - continue; - } - Poll::Ready(Err(e)) => return Poll::Ready(Some(Err(e))), - Poll::Pending => { - this.results_fut = Some(results_fut); - return Poll::Pending; - } - } - } - match this.keys.poll_next_unpin(cx) { - Poll::Ready(Some(Ok(keys))) => { - let methods = this.keys.methods.clone(); - let at = this.keys.at; - let results_fut = async move { - let keys = keys.iter().map(|k| &**k); - let values = methods - .state_query_storage_at(keys, Some(at)) - .await?; - let values: VecDeque<_> = values - .into_iter() - .flat_map(|v| { - v.changes - .into_iter() - .filter_map(|(k, v)| { - let v = v?; - Some((k.0, v.0)) - }) - }) - .collect(); - Ok(Some(values)) - }; - this.results_fut = Some(Box::pin(results_fut)); - continue; - } - Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(e))), - Poll::Ready(None) => return Poll::Ready(None), - Poll::Pending => return Poll::Pending, - } - } - } - } - } - pub mod rpc { - //! RPC types and client for interacting with a substrate node. - //! - //! These are used behind the scenes by Subxt backend implementations, for - //! example [`crate::backend::legacy::LegacyBackend`]. If you need an RPC client, - //! then you can manually instantiate one, and then hand it to Subxt if you'd like - //! to re-use it for the Subxt connection. - //! - //! - [`RpcClientT`] is the underlying dynamic RPC implementation. This provides - //! the low level [`RpcClientT::request_raw`] and [`RpcClientT::subscribe_raw`] - //! methods. - //! - [`RpcClient`] is the higher level wrapper around this, offering - //! the [`RpcClient::request`] and [`RpcClient::subscribe`] methods. - //! - //! # Example - //! - //! Fetching the genesis hash. - //! - //! ```no_run - //! # #[tokio::main] - //! # async fn main() { - //! use subxt::{ - //! client::OnlineClient, - //! config::SubstrateConfig, - //! backend::rpc::RpcClient, - //! backend::legacy::LegacyRpcMethods, - //! }; - //! - //! // Instantiate a default RPC client pointing at some URL. - //! let rpc_client = RpcClient::from_url("ws://localhost:9944") - //! .await - //! .unwrap(); - //! - //! // Instantiate the legacy RPC interface, providing an appropriate - //! // config so that it uses the correct types for your chain. - //! let rpc_methods = LegacyRpcMethods::::new(rpc_client.clone()); - //! - //! // Use it to make RPC calls, here using the legacy genesis_hash method. - //! let genesis_hash = rpc_methods - //! .genesis_hash() - //! .await - //! .unwrap(); - //! - //! println!("{genesis_hash}"); - //! - //! // Instantiate the Subxt interface using the same client and config if you - //! // want to reuse the same connection: - //! let client = OnlineClient::::from_rpc_client(rpc_client); - //! # } - //! ``` - #![allow(clippy::module_inception)] - #[cfg(feature = "jsonrpsee")] - mod jsonrpsee_impl { - use super::{RawRpcFuture, RawRpcSubscription, RpcClientT}; - use crate::error::RpcError; - use futures::stream::{StreamExt, TryStreamExt}; - use jsonrpsee::{ - core::{ - client::{Client, ClientT, SubscriptionClientT, SubscriptionKind}, - traits::ToRpcParams, - }, - types::SubscriptionId, - }; - use serde_json::value::RawValue; - struct Params(Option>); - impl ToRpcParams for Params { - fn to_rpc_params( - self, - ) -> Result>, serde_json::Error> { - Ok(self.0) - } - } - impl RpcClientT for Client { - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box> { - Box::pin(async move { - let res = ClientT::request(self, method, Params(params)) - .await - .map_err(|e| RpcError::ClientError(Box::new(e)))?; - Ok(res) - }) - } - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription> { - Box::pin(async move { - let stream = SubscriptionClientT::subscribe::< - Box, - _, - >(self, sub, Params(params), unsub) - .await - .map_err(|e| RpcError::ClientError(Box::new(e)))?; - let id = match stream.kind() { - SubscriptionKind::Subscription(SubscriptionId::Str(id)) => { - Some(id.clone().into_owned()) - } - _ => None, - }; - let stream = stream - .map_err(|e| RpcError::ClientError(Box::new(e))) - .boxed(); - Ok(RawRpcSubscription { stream, id }) - }) - } - } - } - mod rpc_client { - use super::{RawRpcSubscription, RpcClientT}; - use crate::error::Error; - use futures::{Stream, StreamExt}; - use serde::{de::DeserializeOwned, Serialize}; - use serde_json::value::RawValue; - use std::{pin::Pin, sync::Arc, task::Poll}; - /// A concrete wrapper around an [`RpcClientT`] which provides some higher level helper methods, - /// is cheaply cloneable, and can be handed to things like [`crate::client::OnlineClient`] to - /// instantiate it. - pub struct RpcClient { - client: Arc, - } - #[automatically_derived] - impl ::core::clone::Clone for RpcClient { - #[inline] - fn clone(&self) -> RpcClient { - RpcClient { - client: ::core::clone::Clone::clone(&self.client), - } - } - } - impl RpcClient { - #[cfg(feature = "jsonrpsee")] - /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. - /// - /// Errors if an insecure URL is provided. In this case, use [`RpcClient::from_insecure_url`] instead. - pub async fn from_url>(url: U) -> Result { - crate::utils::validate_url_is_secure(url.as_ref())?; - RpcClient::from_insecure_url(url).await - } - #[cfg(feature = "jsonrpsee")] - /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. - /// - /// Allows insecure URLs without SSL encryption, e.g. (http:// and ws:// URLs). - pub async fn from_insecure_url>( - url: U, - ) -> Result { - let client = jsonrpsee_helpers::client(url.as_ref()) - .await - .map_err(|e| crate::error::RpcError::ClientError(Box::new(e)))?; - Ok(Self::new(client)) - } - /// Create a new [`RpcClient`] from an arbitrary [`RpcClientT`] implementation. - pub fn new(client: R) -> Self { - RpcClient { - client: Arc::new(client), - } - } - /// Make an RPC request, given a method name and some parameters. - /// - /// See [`RpcParams`] and the [`rpc_params!`] macro for an example of how to - /// construct the parameters. - pub async fn request( - &self, - method: &str, - params: RpcParams, - ) -> Result { - let res = self.client.request_raw(method, params.build()).await?; - let val = serde_json::from_str(res.get())?; - Ok(val) - } - /// Subscribe to an RPC endpoint, providing the parameters and the method to call to - /// unsubscribe from it again. - /// - /// See [`RpcParams`] and the [`rpc_params!`] macro for an example of how to - /// construct the parameters. - pub async fn subscribe( - &self, - sub: &str, - params: RpcParams, - unsub: &str, - ) -> Result, Error> { - let sub = self - .client - .subscribe_raw(sub, params.build(), unsub) - .await?; - Ok(RpcSubscription::new(sub)) - } - } - impl std::fmt::Debug for RpcClient { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("RpcClient").finish() - } - } - impl std::ops::Deref for RpcClient { - type Target = dyn RpcClientT; - fn deref(&self) -> &Self::Target { - &*self.client - } - } - pub use rpc_params; - /// This represents the parameters passed to an [`RpcClient`], and exists to - /// enforce that parameters are provided in the correct format. - /// - /// Prefer to use the [`rpc_params!`] macro for simpler creation of these. - /// - /// # Example - /// - /// ```rust - /// use subxt::backend::rpc::RpcParams; - /// - /// let mut params = RpcParams::new(); - /// params.push(1).unwrap(); - /// params.push(true).unwrap(); - /// params.push("foo").unwrap(); - /// - /// assert_eq!(params.build().unwrap().get(), "[1,true,\"foo\"]"); - /// ``` - pub struct RpcParams(Vec); - #[automatically_derived] - impl ::core::fmt::Debug for RpcParams { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "RpcParams", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RpcParams { - #[inline] - fn clone(&self) -> RpcParams { - RpcParams(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::default::Default for RpcParams { - #[inline] - fn default() -> RpcParams { - RpcParams(::core::default::Default::default()) - } - } - impl RpcParams { - /// Create a new empty set of [`RpcParams`]. - pub fn new() -> Self { - Self(Vec::new()) - } - /// Push a parameter into our [`RpcParams`]. This serializes it to JSON - /// in the process, and so will return an error if this is not possible. - pub fn push(&mut self, param: P) -> Result<(), Error> { - if self.0.is_empty() { - self.0.push(b'['); - } else { - self.0.push(b',') - } - serde_json::to_writer(&mut self.0, ¶m)?; - Ok(()) - } - /// Build a [`RawValue`] from our params, returning `None` if no parameters - /// were provided. - pub fn build(mut self) -> Option> { - if self.0.is_empty() { - None - } else { - self.0.push(b']'); - let s = unsafe { String::from_utf8_unchecked(self.0) }; - Some(RawValue::from_string(s).expect("Should be valid JSON")) - } - } - } - /// A generic RPC Subscription. This implements [`Stream`], and so most of - /// the functionality you'll need to interact with it comes from the - /// [`StreamExt`] extension trait. - pub struct RpcSubscription { - inner: RawRpcSubscription, - _marker: std::marker::PhantomData, - } - impl std::fmt::Debug for RpcSubscription { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("RpcSubscription") - .field("inner", &"RawRpcSubscription") - .field("_marker", &self._marker) - .finish() - } - } - impl RpcSubscription { - /// Creates a new [`RpcSubscription`]. - pub fn new(inner: RawRpcSubscription) -> Self { - Self { - inner, - _marker: std::marker::PhantomData, - } - } - /// Obtain the ID associated with this subscription. - pub fn subscription_id(&self) -> Option<&str> { - self.inner.id.as_deref() - } - } - impl RpcSubscription { - /// Returns the next item in the stream. This is just a wrapper around - /// [`StreamExt::next()`] so that you can avoid the extra import. - pub async fn next(&mut self) -> Option> { - StreamExt::next(self).await - } - } - impl std::marker::Unpin for RpcSubscription {} - impl Stream for RpcSubscription { - type Item = Result; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> Poll> { - let res = match self.inner.stream.poll_next_unpin(cx) { - ::futures_core::task::Poll::Ready(t) => t, - ::futures_core::task::Poll::Pending => { - return ::futures_core::task::Poll::Pending; - } - }; - let res = res - .map(|r| { - r.map_err(|e| e.into()) - .and_then(|raw_val| { - serde_json::from_str(raw_val.get()).map_err(|e| e.into()) - }) - }); - Poll::Ready(res) - } - } - #[cfg(all(feature = "jsonrpsee", feature = "native"))] - mod jsonrpsee_helpers { - pub use jsonrpsee::{ - client_transport::ws::{ - self, EitherStream, Url, WsTransportClientBuilder, - }, - core::client::{Client, Error}, - }; - use tokio_util::compat::Compat; - pub type Sender = ws::Sender>; - pub type Receiver = ws::Receiver>; - /// Build WS RPC client from URL - pub async fn client(url: &str) -> Result { - let (sender, receiver) = ws_transport(url).await?; - Ok( - Client::builder() - .max_buffer_capacity_per_subscription(4096) - .build_with_tokio(sender, receiver), - ) - } - async fn ws_transport(url: &str) -> Result<(Sender, Receiver), Error> { - let url = Url::parse(url).map_err(|e| Error::Transport(e.into()))?; - WsTransportClientBuilder::default() - .build(url) - .await - .map_err(|e| Error::Transport(e.into())) - } - } - } - mod rpc_client_t { - use crate::error::RpcError; - use futures::Stream; - use std::{future::Future, pin::Pin}; - pub use serde_json::value::RawValue; - /// A trait describing low level JSON-RPC interactions. Implementations of this can be - /// used to instantiate a [`super::RpcClient`], which can be passed to [`crate::OnlineClient`] - /// or used for lower level RPC calls via eg [`crate::backend::legacy::LegacyRpcMethods`]. - /// - /// This is a low level interface whose methods expect an already-serialized set of params, - /// and return an owned but still-serialized [`RawValue`], deferring deserialization to - /// the caller. This is the case because we want the methods to be object-safe (which prohibits - /// generics), and want to avoid any unnecessary allocations in serializing/deserializing - /// parameters. - /// - /// # Panics - /// - /// Implementations are free to panic if the `RawValue`'s passed to `request_raw` or - /// `subscribe_raw` are not JSON arrays. Internally, we ensure that this is always the case. - pub trait RpcClientT: Send + Sync + 'static { - /// Make a raw request for which we expect a single response back from. Implementations - /// should expect that the params will either be `None`, or be an already-serialized - /// JSON array of parameters. - /// - /// See [`super::RpcParams`] and the [`super::rpc_params!`] macro for an example of how to - /// construct the parameters. - /// - /// Prefer to use the interface provided on [`super::RpcClient`] where possible. - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box>; - /// Subscribe to some method. Implementations should expect that the params will - /// either be `None`, or be an already-serialized JSON array of parameters. - /// - /// See [`super::RpcParams`] and the [`super::rpc_params!`] macro for an example of how to - /// construct the parameters. - /// - /// Prefer to use the interface provided on [`super::RpcClient`] where possible. - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription>; - } - /// A boxed future that is returned from the [`RpcClientT`] methods. - pub type RawRpcFuture<'a, T> = Pin< - Box> + Send + 'a>, - >; - /// The RPC subscription returned from [`RpcClientT`]'s `subscription` method. - pub struct RawRpcSubscription { - /// The subscription stream. - pub stream: Pin< - Box< - dyn Stream< - Item = Result, RpcError>, - > + Send + 'static, - >, - >, - /// The ID associated with the subscription. - pub id: Option, - } - impl RpcClientT for std::sync::Arc { - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box> { - (**self).request_raw(method, params) - } - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription> { - (**self).subscribe_raw(sub, params, unsub) - } - } - impl RpcClientT for Box { - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box> { - (**self).request_raw(method, params) - } - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription> { - (**self).subscribe_raw(sub, params, unsub) - } - } - } - pub use rpc_client::{rpc_params, RpcClient, RpcParams, RpcSubscription}; - pub use rpc_client_t::{RawRpcFuture, RawRpcSubscription, RawValue, RpcClientT}; - } - pub mod unstable { - //! This module will expose a backend implementation based on the new APIs - //! described at . See - //! [`rpc_methods`] for the raw API calls. - //! - //! # Warning - //! - //! Everything in this module is **unstable**, meaning that it could change without - //! warning at any time. - mod follow_stream { - use super::rpc_methods::{FollowEvent, UnstableRpcMethods}; - use crate::config::Config; - use crate::error::Error; - use futures::{FutureExt, Stream, StreamExt}; - use std::future::Future; - use std::pin::Pin; - use std::task::{Context, Poll}; - /// A `Stream` whose goal is to remain subscribed to `chainHead_follow`. It will re-subscribe if the subscription - /// is ended for any reason, and it will return the current `subscription_id` as an event, along with the other - /// follow events. - pub struct FollowStream { - stream_getter: FollowEventStreamGetter, - stream: InnerStreamState, - } - impl std::fmt::Debug for FollowStream { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("FollowStream") - .field("stream_getter", &"..") - .field("stream", &self.stream) - .finish() - } - } - /// A getter function that returns an [`FollowEventStreamFut`]. - pub type FollowEventStreamGetter = Box< - dyn FnMut() -> FollowEventStreamFut + Send, - >; - /// The future which will return a stream of follow events and the subscription ID for it. - pub type FollowEventStreamFut = Pin< - Box< - dyn Future< - Output = Result<(FollowEventStream, String), Error>, - > + Send + 'static, - >, - >; - /// The stream of follow events. - pub type FollowEventStream = Pin< - Box, Error>> + Send + 'static>, - >; - /// Either a ready message with the current subscription ID, or - /// an event from the stream itself. - pub enum FollowStreamMsg { - /// The stream is ready (and has a subscription ID) - Ready(String), - /// An event from the stream. - Event(FollowEvent), - } - #[automatically_derived] - impl ::core::fmt::Debug for FollowStreamMsg { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - FollowStreamMsg::Ready(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Ready", - &__self_0, - ) - } - FollowStreamMsg::Event(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Event", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone - for FollowStreamMsg { - #[inline] - fn clone(&self) -> FollowStreamMsg { - match self { - FollowStreamMsg::Ready(__self_0) => { - FollowStreamMsg::Ready(::core::clone::Clone::clone(__self_0)) - } - FollowStreamMsg::Event(__self_0) => { - FollowStreamMsg::Event(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for FollowStreamMsg {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for FollowStreamMsg { - #[inline] - fn eq(&self, other: &FollowStreamMsg) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - FollowStreamMsg::Ready(__self_0), - FollowStreamMsg::Ready(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowStreamMsg::Event(__self_0), - FollowStreamMsg::Event(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for FollowStreamMsg { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - impl FollowStreamMsg { - /// Return an event, or none if the message is a "ready" one. - pub fn into_event(self) -> Option> { - match self { - FollowStreamMsg::Ready(_) => None, - FollowStreamMsg::Event(e) => Some(e), - } - } - } - enum InnerStreamState { - /// We've just created the stream; we'll start Initializing it - New, - /// We're fetching the inner subscription. Move to Ready when we have one. - Initializing(FollowEventStreamFut), - /// Report back the subscription ID here, and then start ReceivingEvents. - Ready(Option<(FollowEventStream, String)>), - /// We are polling for, and receiving events from the stream. - ReceivingEvents(FollowEventStream), - /// We received a stop event. We'll send one on and restart the stream. - Stopped, - /// The stream is finished and will not restart (likely due to an error). - Finished, - } - impl std::fmt::Debug for InnerStreamState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::New => f.write_fmt(format_args!("New")), - Self::Initializing(_) => { - f.write_fmt(format_args!("Initializing(..)")) - } - Self::Ready(_) => f.write_fmt(format_args!("Ready(..)")), - Self::ReceivingEvents(_) => { - f.write_fmt(format_args!("ReceivingEvents(..)")) - } - Self::Stopped => f.write_fmt(format_args!("Stopped")), - Self::Finished => f.write_fmt(format_args!("Finished")), - } - } - } - impl FollowStream { - /// Create a new [`FollowStream`] given a function which returns the stream. - pub fn new(stream_getter: FollowEventStreamGetter) -> Self { - Self { - stream_getter, - stream: InnerStreamState::New, - } - } - /// Create a new [`FollowStream`] given the RPC methods. - pub fn from_methods( - methods: UnstableRpcMethods, - ) -> FollowStream { - FollowStream { - stream_getter: Box::new(move || { - let methods = methods.clone(); - Box::pin(async move { - let stream = methods.chainhead_unstable_follow(true).await?; - let Some(sub_id) = stream - .subscription_id() - .map(ToOwned::to_owned) else { - return Err( - Error::Other( - "Subscription ID expected for chainHead_follow response, but not given" - .to_owned(), - ), - ); - }; - let stream: FollowEventStream = Box::pin(stream); - Ok((stream, sub_id)) - }) - }), - stream: InnerStreamState::New, - } - } - } - impl std::marker::Unpin for FollowStream {} - impl Stream for FollowStream { - type Item = Result, Error>; - fn poll_next( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - let this = self.get_mut(); - loop { - match &mut this.stream { - InnerStreamState::New => { - let fut = (this.stream_getter)(); - this.stream = InnerStreamState::Initializing(fut); - continue; - } - InnerStreamState::Initializing(fut) => { - match fut.poll_unpin(cx) { - Poll::Pending => { - return Poll::Pending; - } - Poll::Ready(Ok(sub_with_id)) => { - this.stream = InnerStreamState::Ready(Some(sub_with_id)); - continue; - } - Poll::Ready(Err(e)) => { - this.stream = InnerStreamState::Finished; - return Poll::Ready(Some(Err(e))); - } - } - } - InnerStreamState::Ready(stream) => { - let (sub, sub_id) = stream - .take() - .expect("should always be Some"); - this.stream = InnerStreamState::ReceivingEvents(sub); - return Poll::Ready( - Some(Ok(FollowStreamMsg::Ready(sub_id))), - ); - } - InnerStreamState::ReceivingEvents(stream) => { - match stream.poll_next_unpin(cx) { - Poll::Pending => { - return Poll::Pending; - } - Poll::Ready(None) => { - this.stream = InnerStreamState::Stopped; - continue; - } - Poll::Ready(Some(Ok(ev))) => { - if let FollowEvent::Stop = ev { - this.stream = InnerStreamState::Stopped; - continue; - } - return Poll::Ready(Some(Ok(FollowStreamMsg::Event(ev)))); - } - Poll::Ready(Some(Err(e))) => { - this.stream = InnerStreamState::Finished; - return Poll::Ready(Some(Err(e))); - } - } - } - InnerStreamState::Stopped => { - this.stream = InnerStreamState::New; - return Poll::Ready( - Some(Ok(FollowStreamMsg::Event(FollowEvent::Stop))), - ); - } - InnerStreamState::Finished => { - return Poll::Ready(None); - } - } - } - } - } - } - mod follow_stream_driver { - use super::follow_stream_unpin::{ - BlockRef, FollowStreamMsg, FollowStreamUnpin, - }; - use crate::backend::unstable::rpc_methods::{ - FollowEvent, Initialized, RuntimeEvent, - }; - use crate::config::BlockHash; - use crate::error::Error; - use futures::stream::{Stream, StreamExt}; - use std::collections::{HashMap, HashSet, VecDeque}; - use std::ops::DerefMut; - use std::pin::Pin; - use std::sync::{Arc, Mutex}; - use std::task::{Context, Poll, Waker}; - /// A `Stream` which builds on `FollowStreamDriver`, and allows multiple subscribers to obtain events - /// from the single underlying subscription (each being provided an `Initialized` message and all new - /// blocks since then, as if they were each creating a unique `chainHead_follow` subscription). This - /// is the "top" layer of our follow stream subscriptions, and the one that's interacted with elsewhere. - pub struct FollowStreamDriver { - inner: FollowStreamUnpin, - shared: Shared, - } - #[automatically_derived] - impl ::core::fmt::Debug - for FollowStreamDriver { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "FollowStreamDriver", - "inner", - &self.inner, - "shared", - &&self.shared, - ) - } - } - impl FollowStreamDriver { - /// Create a new [`FollowStreamDriver`]. This must be polled by some executor - /// in order for any progress to be made. Things can subscribe to events. - pub fn new(follow_unpin: FollowStreamUnpin) -> Self { - Self { - inner: follow_unpin, - shared: Shared::default(), - } - } - /// Return a handle from which we can create new subscriptions to follow events. - pub fn handle(&self) -> FollowStreamDriverHandle { - FollowStreamDriverHandle { - shared: self.shared.clone(), - } - } - } - impl Stream for FollowStreamDriver { - type Item = Result<(), Error>; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - match self.inner.poll_next_unpin(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(None) => { - self.shared.done(); - Poll::Ready(None) - } - Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))), - Poll::Ready(Some(Ok(item))) => { - self.shared.push_item(item); - Poll::Ready(Some(Ok(()))) - } - } - } - } - /// A handle that can be used to create subscribers, but that doesn't - /// itself subscribe to events. - pub struct FollowStreamDriverHandle { - shared: Shared, - } - #[automatically_derived] - impl ::core::fmt::Debug - for FollowStreamDriverHandle { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "FollowStreamDriverHandle", - "shared", - &&self.shared, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for FollowStreamDriverHandle { - #[inline] - fn clone(&self) -> FollowStreamDriverHandle { - FollowStreamDriverHandle { - shared: ::core::clone::Clone::clone(&self.shared), - } - } - } - impl FollowStreamDriverHandle { - /// Subscribe to follow events. - pub fn subscribe(&self) -> FollowStreamDriverSubscription { - self.shared.subscribe() - } - } - /// A subscription to events from the [`FollowStreamDriver`]. All subscriptions - /// begin first with a `Ready` event containing the current subscription ID, and - /// then with an `Initialized` event containing the latest finalized block and latest - /// runtime information, and then any new/best block events and so on received since - /// the latest finalized block. - pub struct FollowStreamDriverSubscription { - id: usize, - done: bool, - shared: Shared, - local_items: VecDeque>>, - } - #[automatically_derived] - impl ::core::fmt::Debug - for FollowStreamDriverSubscription { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "FollowStreamDriverSubscription", - "id", - &self.id, - "done", - &self.done, - "shared", - &self.shared, - "local_items", - &&self.local_items, - ) - } - } - impl Stream for FollowStreamDriverSubscription { - type Item = FollowStreamMsg>; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - if self.done { - return Poll::Ready(None); - } - loop { - if let Some(item) = self.local_items.pop_front() { - return Poll::Ready(Some(item)); - } - let items = self - .shared - .take_items_and_save_waker(self.id, cx.waker()); - let Some(items) = items else { self.done = true; - return Poll::Ready(None); - }; - if items.is_empty() { - return Poll::Pending; - } else { - self.local_items = items; - } - } - } - } - impl FollowStreamDriverSubscription { - /// Return the current subscription ID. If the subscription has stopped, then this will - /// wait until a new subscription has started with a new ID. - pub async fn subscription_id(self) -> Option { - let ready_event = self - .skip_while(|ev| std::future::ready( - !match ev { - FollowStreamMsg::Ready(_) => true, - _ => false, - }, - )) - .next() - .await?; - match ready_event { - FollowStreamMsg::Ready(sub_id) => Some(sub_id), - _ => None, - } - } - /// Subscribe to the follow events, ignoring any other messages. - pub fn events( - self, - ) -> impl Stream>> + Send + Sync { - self.filter_map(|ev| std::future::ready(ev.into_event())) - } - } - impl Clone for FollowStreamDriverSubscription { - fn clone(&self) -> Self { - self.shared.subscribe() - } - } - impl Drop for FollowStreamDriverSubscription { - fn drop(&mut self) { - self.shared.remove_sub(self.id); - } - } - /// Locked shared state. The driver stream will access this state to push - /// events to any subscribers, and subscribers will access it to pull the - /// events destined for themselves. - struct Shared(Arc>>); - #[automatically_derived] - impl ::core::fmt::Debug - for Shared { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Shared", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for Shared { - #[inline] - fn clone(&self) -> Shared { - Shared(::core::clone::Clone::clone(&self.0)) - } - } - struct SharedState { - done: bool, - next_id: usize, - subscribers: HashMap>, - /// Keep a buffer of all events that should be handed to a new subscription. - block_events_for_new_subscriptions: VecDeque< - FollowEvent>, - >, - current_subscription_id: Option, - current_init_message: Option>>, - seen_runtime_events: HashMap, - } - #[automatically_derived] - impl ::core::fmt::Debug - for SharedState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "done", - "next_id", - "subscribers", - "block_events_for_new_subscriptions", - "current_subscription_id", - "current_init_message", - "seen_runtime_events", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.done, - &self.next_id, - &self.subscribers, - &self.block_events_for_new_subscriptions, - &self.current_subscription_id, - &self.current_init_message, - &&self.seen_runtime_events, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "SharedState", - names, - values, - ) - } - } - impl Default for Shared { - fn default() -> Self { - Shared( - Arc::new( - Mutex::new(SharedState { - next_id: 1, - done: false, - subscribers: HashMap::new(), - current_init_message: None, - current_subscription_id: None, - seen_runtime_events: HashMap::new(), - block_events_for_new_subscriptions: VecDeque::new(), - }), - ), - ) - } - } - impl Shared { - /// Set the shared state to "done"; no more items will be handed to it. - pub fn done(&self) { - let mut shared = self.0.lock().unwrap(); - shared.done = true; - } - /// Cleanup a subscription. - pub fn remove_sub(&self, sub_id: usize) { - let mut shared = self.0.lock().unwrap(); - shared.subscribers.remove(&sub_id); - } - /// Take items for some subscription ID and save the waker. - pub fn take_items_and_save_waker( - &self, - sub_id: usize, - waker: &Waker, - ) -> Option>>> { - let mut shared = self.0.lock().unwrap(); - let is_done = shared.done; - let details = shared.subscribers.get_mut(&sub_id)?; - if details.items.is_empty() && is_done { - return None; - } - let items = std::mem::take(&mut details.items); - if !is_done { - details.waker = Some(waker.clone()); - } - Some(items) - } - /// Push a new item out to subscribers. - pub fn push_item(&self, item: FollowStreamMsg>) { - let mut shared = self.0.lock().unwrap(); - let shared = shared.deref_mut(); - for details in shared.subscribers.values_mut() { - details.items.push_back(item.clone()); - if let Some(waker) = details.waker.take() { - waker.wake(); - } - } - match item { - FollowStreamMsg::Ready(sub_id) => { - shared.current_subscription_id = Some(sub_id); - } - FollowStreamMsg::Event(FollowEvent::Initialized(ev)) => { - shared.current_init_message = Some(ev.clone()); - shared.block_events_for_new_subscriptions.clear(); - } - FollowStreamMsg::Event(FollowEvent::Finalized(finalized_ev)) => { - if let Some(init_message) = &mut shared.current_init_message - { - let newest_runtime = finalized_ev - .finalized_block_hashes - .iter() - .rev() - .filter_map(|h| { - shared.seen_runtime_events.get(&h.hash()).cloned() - }) - .next(); - shared.seen_runtime_events.clear(); - if let Some(finalized) - = finalized_ev.finalized_block_hashes.last() - { - init_message.finalized_block_hash = finalized.clone(); - } - if let Some(runtime_ev) = newest_runtime { - init_message.finalized_block_runtime = Some(runtime_ev); - } - } - let to_remove: HashSet = finalized_ev - .finalized_block_hashes - .iter() - .chain(finalized_ev.pruned_block_hashes.iter()) - .map(|h| h.hash()) - .collect(); - shared - .block_events_for_new_subscriptions - .retain(|ev| match ev { - FollowEvent::NewBlock(new_block_ev) => { - !to_remove.contains(&new_block_ev.block_hash.hash()) - } - FollowEvent::BestBlockChanged(best_block_ev) => { - !to_remove.contains(&best_block_ev.best_block_hash.hash()) - } - _ => true, - }); - } - FollowStreamMsg::Event(FollowEvent::NewBlock(new_block_ev)) => { - if let Some(runtime_event) = &new_block_ev.new_runtime { - shared - .seen_runtime_events - .insert( - new_block_ev.block_hash.hash(), - runtime_event.clone(), - ); - } - shared - .block_events_for_new_subscriptions - .push_back(FollowEvent::NewBlock(new_block_ev)); - } - FollowStreamMsg::Event( - ev @ FollowEvent::BestBlockChanged(_), - ) => { - shared.block_events_for_new_subscriptions.push_back(ev); - } - FollowStreamMsg::Event(FollowEvent::Stop) => { - shared.block_events_for_new_subscriptions.clear(); - shared.current_subscription_id = None; - shared.current_init_message = None; - } - _ => {} - } - } - /// Create a new subscription. - pub fn subscribe(&self) -> FollowStreamDriverSubscription { - let mut shared = self.0.lock().unwrap(); - let id = shared.next_id; - shared.next_id += 1; - shared - .subscribers - .insert( - id, - SubscriberDetails { - items: VecDeque::new(), - waker: None, - }, - ); - let mut local_items = VecDeque::new(); - if let Some(sub_id) = &shared.current_subscription_id { - local_items.push_back(FollowStreamMsg::Ready(sub_id.clone())); - } - if let Some(init_msg) = &shared.current_init_message { - local_items - .push_back( - FollowStreamMsg::Event( - FollowEvent::Initialized(init_msg.clone()), - ), - ); - } - for ev in &shared.block_events_for_new_subscriptions { - local_items.push_back(FollowStreamMsg::Event(ev.clone())); - } - drop(shared); - FollowStreamDriverSubscription { - id, - done: false, - shared: self.clone(), - local_items, - } - } - } - /// Details for a given subscriber: any items it's not yet claimed, - /// and a way to wake it up when there are more items for it. - struct SubscriberDetails { - items: VecDeque>>, - waker: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug - for SubscriberDetails { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "SubscriberDetails", - "items", - &self.items, - "waker", - &&self.waker, - ) - } - } - } - mod follow_stream_unpin { - use super::follow_stream::FollowStream; - use super::UnstableRpcMethods; - use crate::backend::unstable::rpc_methods::{ - BestBlockChanged, Finalized, FollowEvent, Initialized, NewBlock, - }; - use crate::config::{BlockHash, Config}; - use crate::error::Error; - use futures::stream::{FuturesUnordered, Stream, StreamExt}; - use std::collections::{HashMap, HashSet}; - use std::future::Future; - use std::pin::Pin; - use std::sync::{Arc, Mutex}; - use std::task::{Context, Poll, Waker}; - /// The type of stream item. - pub use super::follow_stream::FollowStreamMsg; - /// A `Stream` which builds on `FollowStream`, and handles pinning. It replaces any block hash seen in - /// the follow events with a `BlockRef` which, when all clones are dropped, will lead to an "unpin" call - /// for that block hash being queued. It will also automatically unpin any blocks that exceed a given max - /// age, to try and prevent the underlying stream from ending (and _all_ blocks from being unpinned as a - /// result). Put simply, it tries to keep every block pinned as long as possible until the block is no longer - /// used anywhere. - pub struct FollowStreamUnpin { - inner: FollowStream, - unpin_method: UnpinMethodHolder, - unpin_futs: FuturesUnordered, - rel_block_num: usize, - subscription_id: Option>, - max_block_life: usize, - pinned: HashMap>, - unpin_flags: UnpinFlags, - } - #[automatically_derived] - impl ::core::fmt::Debug - for FollowStreamUnpin { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "inner", - "unpin_method", - "unpin_futs", - "rel_block_num", - "subscription_id", - "max_block_life", - "pinned", - "unpin_flags", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.inner, - &self.unpin_method, - &self.unpin_futs, - &self.rel_block_num, - &self.subscription_id, - &self.max_block_life, - &self.pinned, - &&self.unpin_flags, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "FollowStreamUnpin", - names, - values, - ) - } - } - struct UnpinMethodHolder(UnpinMethod); - impl std::fmt::Debug for UnpinMethodHolder { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt( - format_args!( - "UnpinMethodHolder(Box) -> UnpinFut>)" - ), - ) - } - } - /// The type of the unpin method that we need to provide. - pub type UnpinMethod = Box< - dyn FnMut(Hash, Arc) -> UnpinFut + Send, - >; - /// The future returned from [`UnpinMethod`]. - pub type UnpinFut = Pin + Send + 'static>>; - impl std::marker::Unpin for FollowStreamUnpin {} - impl Stream for FollowStreamUnpin { - type Item = Result>, Error>; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - let mut this = self.as_mut(); - loop { - let unpin_futs_are_pending = match this - .unpin_futs - .poll_next_unpin(cx) - { - Poll::Ready(Some(())) => continue, - Poll::Ready(None) => false, - Poll::Pending => true, - }; - let Poll::Ready(ev) = this.inner.poll_next_unpin(cx) else { - return Poll::Pending; - }; - let Some(ev) = ev else { - return match unpin_futs_are_pending { - true => Poll::Pending, - false => Poll::Ready(None), - }; - }; - let ev = match ev { - Ok(ev) => ev, - Err(e) => { - return Poll::Ready(Some(Err(e))); - } - }; - let ev = match ev { - FollowStreamMsg::Ready(subscription_id) => { - this.subscription_id = Some(subscription_id.clone().into()); - FollowStreamMsg::Ready(subscription_id) - } - FollowStreamMsg::Event( - FollowEvent::Initialized(details), - ) => { - let rel_block_num = this.rel_block_num; - let block_ref = this - .pin_unpinnable_block_at( - rel_block_num, - details.finalized_block_hash, - ); - FollowStreamMsg::Event( - FollowEvent::Initialized(Initialized { - finalized_block_hash: block_ref, - finalized_block_runtime: details.finalized_block_runtime, - }), - ) - } - FollowStreamMsg::Event(FollowEvent::NewBlock(details)) => { - let parent_rel_block_num = this - .pinned - .get(&details.parent_block_hash) - .map(|p| p.rel_block_num) - .unwrap_or(this.rel_block_num); - let block_ref = this - .pin_block_at(parent_rel_block_num + 1, details.block_hash); - let parent_block_ref = this - .pin_block_at( - parent_rel_block_num, - details.parent_block_hash, - ); - FollowStreamMsg::Event( - FollowEvent::NewBlock(NewBlock { - block_hash: block_ref, - parent_block_hash: parent_block_ref, - new_runtime: details.new_runtime, - }), - ) - } - FollowStreamMsg::Event( - FollowEvent::BestBlockChanged(details), - ) => { - let rel_block_num = this.rel_block_num + 1; - let block_ref = this - .pin_block_at(rel_block_num, details.best_block_hash); - FollowStreamMsg::Event( - FollowEvent::BestBlockChanged(BestBlockChanged { - best_block_hash: block_ref, - }), - ) - } - FollowStreamMsg::Event(FollowEvent::Finalized(details)) => { - let finalized_block_refs: Vec<_> = details - .finalized_block_hashes - .into_iter() - .enumerate() - .map(|(idx, hash)| { - let rel_block_num = this.rel_block_num + idx + 1; - this.pin_unpinnable_block_at(rel_block_num, hash) - }) - .collect(); - this.rel_block_num += finalized_block_refs.len(); - let pruned_block_refs: Vec<_> = details - .pruned_block_hashes - .into_iter() - .map(|hash| { - let rel_block_num = this.rel_block_num + 1; - this.pin_unpinnable_block_at(rel_block_num, hash) - }) - .collect(); - this.unpin_blocks(cx.waker()); - FollowStreamMsg::Event( - FollowEvent::Finalized(Finalized { - finalized_block_hashes: finalized_block_refs, - pruned_block_hashes: pruned_block_refs, - }), - ) - } - FollowStreamMsg::Event(FollowEvent::Stop) => { - this.subscription_id = None; - this.pinned.clear(); - this.unpin_futs.clear(); - this.unpin_flags.lock().unwrap().clear(); - this.rel_block_num = 0; - FollowStreamMsg::Event(FollowEvent::Stop) - } - FollowStreamMsg::Event( - FollowEvent::OperationBodyDone(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationBodyDone(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationCallDone(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationCallDone(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationStorageItems(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationStorageItems(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationWaitingForContinue(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationWaitingForContinue(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationStorageDone(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationStorageDone(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationInaccessible(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationInaccessible(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationError(details), - ) => { - FollowStreamMsg::Event(FollowEvent::OperationError(details)) - } - }; - return Poll::Ready(Some(Ok(ev))); - } - } - } - impl FollowStreamUnpin { - /// Create a new [`FollowStreamUnpin`]. - pub fn new( - follow_stream: FollowStream, - unpin_method: UnpinMethod, - max_block_life: usize, - ) -> Self { - Self { - inner: follow_stream, - unpin_method: UnpinMethodHolder(unpin_method), - max_block_life, - pinned: Default::default(), - subscription_id: None, - rel_block_num: 0, - unpin_flags: Default::default(), - unpin_futs: Default::default(), - } - } - /// Create a new [`FollowStreamUnpin`] given the RPC methods. - pub fn from_methods( - follow_stream: FollowStream, - methods: UnstableRpcMethods, - max_block_life: usize, - ) -> FollowStreamUnpin { - let unpin_method = Box::new(move |hash: T::Hash, sub_id: Arc| { - let methods = methods.clone(); - let fut: UnpinFut = Box::pin(async move { - let _ = methods - .chainhead_unstable_unpin(&sub_id, hash) - .await; - }); - fut - }); - FollowStreamUnpin::new(follow_stream, unpin_method, max_block_life) - } - /// Is the block hash currently pinned. - pub fn is_pinned(&self, hash: &Hash) -> bool { - self.pinned.contains_key(hash) - } - /// Pin a block, or return the reference to an already-pinned block. If the block has been registered to - /// be unpinned, we'll clear those flags, so that it won't be unpinned. If the unpin request has already - /// been sent though, then the block will be unpinned. - fn pin_block_at( - &mut self, - rel_block_num: usize, - hash: Hash, - ) -> BlockRef { - self.pin_block_at_setting_unpinnable_flag(rel_block_num, hash, false) - } - /// Pin a block, or return the reference to an already-pinned block. - /// - /// This is the same as [`Self::pin_block_at`], except that it also marks the block as being unpinnable now, - /// which should be done for any block that will no longer be seen in future events. - fn pin_unpinnable_block_at( - &mut self, - rel_block_num: usize, - hash: Hash, - ) -> BlockRef { - self.pin_block_at_setting_unpinnable_flag(rel_block_num, hash, true) - } - fn pin_block_at_setting_unpinnable_flag( - &mut self, - rel_block_num: usize, - hash: Hash, - can_be_unpinned: bool, - ) -> BlockRef { - let entry = self - .pinned - .entry(hash) - .and_modify(|entry| { - entry - .can_be_unpinned = entry.can_be_unpinned || can_be_unpinned; - self.unpin_flags.lock().unwrap().remove(&hash); - }) - .or_insert_with(|| PinnedDetails { - rel_block_num, - block_ref: BlockRef { - inner: Arc::new(BlockRefInner { - hash, - unpin_flags: self.unpin_flags.clone(), - }), - }, - can_be_unpinned, - }); - entry.block_ref.clone() - } - /// Unpin any blocks that are either too old, or have the unpin flag set and are old enough. - fn unpin_blocks(&mut self, waker: &Waker) { - let mut unpin_flags = self.unpin_flags.lock().unwrap(); - let rel_block_num = self.rel_block_num; - let Some(sub_id) = &self.subscription_id else { return; - }; - let mut blocks_to_unpin = ::alloc::vec::Vec::new(); - for (hash, details) in &self.pinned { - if rel_block_num.saturating_sub(details.rel_block_num) - >= self.max_block_life - || (unpin_flags.contains(hash) && details.can_be_unpinned) - { - blocks_to_unpin.push(*hash); - unpin_flags.remove(hash); - } - } - drop(unpin_flags); - if blocks_to_unpin.is_empty() { - return; - } - for hash in blocks_to_unpin { - self.pinned.remove(&hash); - let fut = (self.unpin_method.0)(hash, sub_id.clone()); - self.unpin_futs.push(fut); - } - waker.wake_by_ref(); - } - } - type UnpinFlags = Arc>>; - struct PinnedDetails { - /// How old is the block? - rel_block_num: usize, - /// A block ref we can hand out to keep blocks pinned. - /// Because we store one here until it's unpinned, the live count - /// will only drop to 1 when no external refs are left. - block_ref: BlockRef, - /// Has this block showed up in the list of pruned blocks, or has it - /// been finalized? In this case, it can now been pinned as it won't - /// show up again in future events (except as a "parent block" of some - /// new block, which we're currently ignoring). - can_be_unpinned: bool, - } - #[automatically_derived] - impl ::core::fmt::Debug - for PinnedDetails { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "PinnedDetails", - "rel_block_num", - &self.rel_block_num, - "block_ref", - &self.block_ref, - "can_be_unpinned", - &&self.can_be_unpinned, - ) - } - } - /// All blocks reported will be wrapped in this. - pub struct BlockRef { - inner: Arc>, - } - #[automatically_derived] - impl ::core::fmt::Debug - for BlockRef { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "BlockRef", - "inner", - &&self.inner, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for BlockRef { - #[inline] - fn clone(&self) -> BlockRef { - BlockRef { - inner: ::core::clone::Clone::clone(&self.inner), - } - } - } - struct BlockRefInner { - hash: Hash, - unpin_flags: UnpinFlags, - } - #[automatically_derived] - impl ::core::fmt::Debug for BlockRefInner { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "BlockRefInner", - "hash", - &self.hash, - "unpin_flags", - &&self.unpin_flags, - ) - } - } - impl BlockRef { - /// Return the hash for this block. - pub fn hash(&self) -> Hash { - self.inner.hash - } - } - impl PartialEq for BlockRef { - fn eq(&self, other: &Self) -> bool { - self.inner.hash == other.inner.hash - } - } - impl PartialEq for BlockRef { - fn eq(&self, other: &Hash) -> bool { - &self.inner.hash == other - } - } - impl Drop for BlockRef { - fn drop(&mut self) { - if Arc::strong_count(&self.inner) == 2 { - if let Ok(mut unpin_flags) = self.inner.unpin_flags.lock() { - unpin_flags.insert(self.inner.hash); - } - } - } - } - } - mod storage_items { - use super::follow_stream_driver::FollowStreamDriverHandle; - use super::follow_stream_unpin::BlockRef; - use super::rpc_methods::{ - FollowEvent, MethodResponse, StorageQuery, StorageResult, - UnstableRpcMethods, - }; - use crate::config::Config; - use crate::error::{Error, RpcError}; - use futures::{FutureExt, Stream, StreamExt}; - use std::collections::VecDeque; - use std::future::Future; - use std::pin::Pin; - use std::sync::Arc; - use std::task::{Context, Poll}; - /// Obtain a stream of storage items given some query. this handles continuing - /// and stopping under the hood, and returns a stream of `StorageResult`s. - pub struct StorageItems { - done: bool, - operation_id: Arc, - buffered_responses: VecDeque, - continue_call: ContinueFutGetter, - continue_fut: Option, - follow_event_stream: FollowEventStream, - } - impl StorageItems { - pub async fn from_methods( - queries: impl Iterator>, - at: T::Hash, - follow_handle: &FollowStreamDriverHandle, - methods: UnstableRpcMethods, - ) -> Result { - let sub_id = super::get_subscription_id(follow_handle).await?; - let follow_events = follow_handle.subscribe().events(); - let status = methods - .chainhead_unstable_storage(&sub_id, at, queries, None) - .await?; - let operation_id: Arc = match status { - MethodResponse::LimitReached => { - return Err( - RpcError::request_rejected("limit reached").into(), - ); - } - MethodResponse::Started(s) => s.operation_id.into(), - }; - let continue_call: ContinueFutGetter = { - let operation_id = operation_id.clone(); - Box::new(move || { - let sub_id = sub_id.clone(); - let operation_id = operation_id.clone(); - let methods = methods.clone(); - Box::pin(async move { - methods - .chainhead_unstable_continue(&sub_id, &operation_id) - .await - }) - }) - }; - Ok( - StorageItems::new( - operation_id, - continue_call, - Box::pin(follow_events), - ), - ) - } - fn new( - operation_id: Arc, - continue_call: ContinueFutGetter, - follow_event_stream: FollowEventStream, - ) -> Self { - Self { - done: false, - buffered_responses: VecDeque::new(), - operation_id, - continue_call, - continue_fut: None, - follow_event_stream, - } - } - } - pub type FollowEventStream = Pin< - Box>> + Send + 'static>, - >; - pub type ContinueFutGetter = Box ContinueFut + Send + 'static>; - pub type ContinueFut = Pin< - Box> + Send + 'static>, - >; - impl Stream for StorageItems { - type Item = Result; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - loop { - if self.done { - return Poll::Ready(None); - } - if let Some(item) = self.buffered_responses.pop_front() { - return Poll::Ready(Some(Ok(item))); - } - if let Some(mut fut) = self.continue_fut.take() { - match fut.poll_unpin(cx) { - Poll::Pending => { - self.continue_fut = Some(fut); - return Poll::Pending; - } - Poll::Ready(Err(e)) => { - self.done = true; - return Poll::Ready(Some(Err(e))); - } - Poll::Ready(Ok(())) => {} - } - } - let ev = match self.follow_event_stream.poll_next_unpin(cx) { - Poll::Pending => return Poll::Pending, - Poll::Ready(None) => return Poll::Ready(None), - Poll::Ready(Some(ev)) => ev, - }; - match ev { - FollowEvent::OperationWaitingForContinue( - id, - ) if id.operation_id == *self.operation_id => { - self.continue_fut = Some((self.continue_call)()); - continue; - } - FollowEvent::OperationStorageDone( - id, - ) if id.operation_id == *self.operation_id => { - self.done = true; - return Poll::Ready(None); - } - FollowEvent::OperationStorageItems( - items, - ) if items.operation_id == *self.operation_id => { - self.buffered_responses = items.items; - continue; - } - _ => { - continue; - } - } - } - } - } - } - pub mod rpc_methods { - //! An interface to call the API methods. See - //! for details of the API - //! methods exposed here. - use crate::backend::rpc::{rpc_params, RpcClient, RpcSubscription}; - use crate::config::BlockHash; - use crate::{Config, Error}; - use derivative::Derivative; - use futures::{Stream, StreamExt}; - use serde::{Deserialize, Serialize}; - use std::collections::{HashMap, VecDeque}; - use std::task::Poll; - /// An interface to call the unstable RPC methods. This interface is instantiated with - /// some `T: Config` trait which determines some of the types that the RPC methods will - /// take or hand back. - #[derivative(Clone(bound = ""), Debug(bound = ""))] - pub struct UnstableRpcMethods { - client: RpcClient, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for UnstableRpcMethods { - fn clone(&self) -> Self { - match *self { - UnstableRpcMethods { - client: ref __arg_0, - _marker: ref __arg_1, - } => { - UnstableRpcMethods { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for UnstableRpcMethods { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - UnstableRpcMethods { - client: ref __arg_0, - _marker: ref __arg_1, - } => { - let mut __debug_trait_builder = __f - .debug_struct("UnstableRpcMethods"); - let _ = __debug_trait_builder.field("client", &&(*__arg_0)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - impl UnstableRpcMethods { - /// Instantiate the legacy RPC method interface. - pub fn new(client: RpcClient) -> Self { - UnstableRpcMethods { - client, - _marker: std::marker::PhantomData, - } - } - /// Subscribe to `chainHead_unstable_follow` to obtain all reported blocks by the chain. - /// - /// The subscription ID can be used to make queries for the - /// block's body ([`chainhead_unstable_body`](UnstableRpcMethods::chainhead_unstable_follow)), - /// block's header ([`chainhead_unstable_header`](UnstableRpcMethods::chainhead_unstable_header)), - /// block's storage ([`chainhead_unstable_storage`](UnstableRpcMethods::chainhead_unstable_storage)) and submitting - /// runtime API calls at this block ([`chainhead_unstable_call`](UnstableRpcMethods::chainhead_unstable_call)). - /// - /// # Note - /// - /// When the user is no longer interested in a block, the user is responsible - /// for calling the [`chainhead_unstable_unpin`](UnstableRpcMethods::chainhead_unstable_unpin) method. - /// Failure to do so will result in the subscription being stopped by generating the `Stop` event. - pub async fn chainhead_unstable_follow( - &self, - with_runtime: bool, - ) -> Result, Error> { - let sub = self - .client - .subscribe( - "chainHead_unstable_follow", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(with_runtime) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - "chainHead_unstable_unfollow", - ) - .await?; - Ok(FollowSubscription { - sub, - done: false, - }) - } - /// Resumes a storage fetch started with chainHead_unstable_storage after it has generated an - /// `operationWaitingForContinue` event. - /// - /// Has no effect if the operationId is invalid or refers to an operation that has emitted a - /// `{"event": "operationInaccessible"` event, or if the followSubscription is invalid or stale. - pub async fn chainhead_unstable_continue( - &self, - follow_subscription: &str, - operation_id: &str, - ) -> Result<(), Error> { - self.client - .request( - "chainHead_unstable_continue", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(follow_subscription) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(operation_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(()) - } - /// Stops an operation started with `chainHead_unstable_body`, `chainHead_unstable_call`, or - /// `chainHead_unstable_storage¦. If the operation was still in progress, this interrupts it. - /// If the operation was already finished, this call has no effect. - /// - /// Has no effect if the `followSubscription` is invalid or stale. - pub async fn chainhead_unstable_stop_operation( - &self, - follow_subscription: &str, - operation_id: &str, - ) -> Result<(), Error> { - self.client - .request( - "chainHead_unstable_stopOperation", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(follow_subscription) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(operation_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(()) - } - /// Call the `chainHead_unstable_body` method and return an operation ID to obtain the block's body. - /// - /// The response events are provided on the `chainHead_follow` subscription and identified by - /// the returned operation ID. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_body( - &self, - subscription_id: &str, - hash: T::Hash, - ) -> Result { - let response = self - .client - .request( - "chainHead_unstable_body", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(response) - } - /// Get the block's header using the `chainHead_unstable_header` method. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_header( - &self, - subscription_id: &str, - hash: T::Hash, - ) -> Result, Error> { - let header: Option = self - .client - .request( - "chainHead_unstable_header", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - let header = header - .map(|h| codec::Decode::decode(&mut &*h.0)) - .transpose()?; - Ok(header) - } - /// Call the `chainhead_unstable_storage` method and return an operation ID to obtain the block's storage. - /// - /// The response events are provided on the `chainHead_follow` subscription and identified by - /// the returned operation ID. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_storage( - &self, - subscription_id: &str, - hash: T::Hash, - items: impl IntoIterator>, - child_key: Option<&[u8]>, - ) -> Result { - let items: Vec> = items - .into_iter() - .map(|item| StorageQuery { - key: to_hex(item.key), - query_type: item.query_type, - }) - .collect(); - let response = self - .client - .request( - "chainHead_unstable_storage", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(items) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(child_key.map(to_hex)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(response) - } - /// Call the `chainhead_unstable_storage` method and return an operation ID to obtain the runtime API result. - /// - /// The response events are provided on the `chainHead_follow` subscription and identified by - /// the returned operation ID. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_call( - &self, - subscription_id: &str, - hash: T::Hash, - function: &str, - call_parameters: &[u8], - ) -> Result { - let response = self - .client - .request( - "chainHead_unstable_call", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(function) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(to_hex(call_parameters)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(response) - } - /// Unpin a block reported by the `chainHead_follow` subscription. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_unpin( - &self, - subscription_id: &str, - hash: T::Hash, - ) -> Result<(), Error> { - self.client - .request( - "chainHead_unstable_unpin", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(()) - } - /// Return the genesis hash. - pub async fn chainspec_v1_genesis_hash(&self) -> Result { - let hash = self - .client - .request( - "chainSpec_v1_genesisHash", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await?; - Ok(hash) - } - /// Return a string containing the human-readable name of the chain. - pub async fn chainspec_v1_chain_name(&self) -> Result { - let hash = self - .client - .request( - "chainSpec_v1_chainName", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await?; - Ok(hash) - } - /// Returns the JSON payload found in the chain specification under the key properties. - /// No guarantee is offered about the content of this object, and so it's up to the caller - /// to decide what to deserialize it into. - pub async fn chainspec_v1_properties( - &self, - ) -> Result { - self.client - .request( - "chainSpec_v1_properties", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Returns an array of strings indicating the names of all the JSON-RPC functions supported by - /// the JSON-RPC server. - pub async fn rpc_methods(&self) -> Result, Error> { - self.client - .request( - "rpc_methods", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Attempt to submit a transaction, returning events about its progress. - pub async fn transaction_unstable_submit_and_watch( - &self, - tx: &[u8], - ) -> Result, Error> { - let sub = self - .client - .subscribe( - "transactionWatch_unstable_submitAndWatch", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(tx)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - "transactionWatch_unstable_unwatch", - ) - .await?; - Ok(TransactionSubscription { - sub, - done: false, - }) - } - } - /// This represents events generated by the `follow` method. - /// - /// The block events are generated in the following order: - /// 1. Initialized - generated only once to signal the latest finalized block - /// 2. NewBlock - a new block was added. - /// 3. BestBlockChanged - indicate that the best block is now the one from this event. The block was - /// announced priorly with the `NewBlock` event. - /// 4. Finalized - State the finalized and pruned blocks. - /// - /// The following events are related to operations: - /// - OperationBodyDone: The response of the `chainHead_body` - /// - OperationCallDone: The response of the `chainHead_call` - /// - OperationStorageItems: Items produced by the `chianHead_storage` - /// - OperationWaitingForContinue: Generated after OperationStorageItems and requires the user to - /// call `chainHead_continue` - /// - OperationStorageDone: The `chainHead_storage` method has produced all the results - /// - OperationInaccessible: The server was unable to provide the result, retries might succeed in - /// the future - /// - OperationError: The server encountered an error, retries will not succeed - /// - /// The stop event indicates that the JSON-RPC server was unable to provide a consistent list of - /// the blocks at the head of the chain. - #[serde(rename_all = "camelCase")] - #[serde(tag = "event")] - pub enum FollowEvent { - /// The latest finalized block. - /// - /// This event is generated only once. - Initialized(Initialized), - /// A new non-finalized block was added. - NewBlock(NewBlock), - /// The best block of the chain. - BestBlockChanged(BestBlockChanged), - /// A list of finalized and pruned blocks. - Finalized(Finalized), - /// The response of the `chainHead_body` method. - OperationBodyDone(OperationBodyDone), - /// The response of the `chainHead_call` method. - OperationCallDone(OperationCallDone), - /// Yield one or more items found in the storage. - OperationStorageItems(OperationStorageItems), - /// Ask the user to call `chainHead_continue` to produce more events - /// regarding the operation id. - OperationWaitingForContinue(OperationId), - /// The responses of the `chainHead_storage` method have been produced. - OperationStorageDone(OperationId), - /// The RPC server was unable to provide the response of the following operation id. - /// - /// Repeating the same operation in the future might succeed. - OperationInaccessible(OperationId), - /// The RPC server encountered an error while processing an operation id. - /// - /// Repeating the same operation in the future will not succeed. - OperationError(OperationError), - /// The subscription is dropped and no further events - /// will be generated. - Stop, - } - #[automatically_derived] - impl ::core::fmt::Debug for FollowEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - FollowEvent::Initialized(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Initialized", - &__self_0, - ) - } - FollowEvent::NewBlock(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "NewBlock", - &__self_0, - ) - } - FollowEvent::BestBlockChanged(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "BestBlockChanged", - &__self_0, - ) - } - FollowEvent::Finalized(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Finalized", - &__self_0, - ) - } - FollowEvent::OperationBodyDone(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationBodyDone", - &__self_0, - ) - } - FollowEvent::OperationCallDone(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationCallDone", - &__self_0, - ) - } - FollowEvent::OperationStorageItems(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationStorageItems", - &__self_0, - ) - } - FollowEvent::OperationWaitingForContinue(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationWaitingForContinue", - &__self_0, - ) - } - FollowEvent::OperationStorageDone(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationStorageDone", - &__self_0, - ) - } - FollowEvent::OperationInaccessible(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationInaccessible", - &__self_0, - ) - } - FollowEvent::OperationError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationError", - &__self_0, - ) - } - FollowEvent::Stop => ::core::fmt::Formatter::write_str(f, "Stop"), - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for FollowEvent { - #[inline] - fn clone(&self) -> FollowEvent { - match self { - FollowEvent::Initialized(__self_0) => { - FollowEvent::Initialized( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::NewBlock(__self_0) => { - FollowEvent::NewBlock(::core::clone::Clone::clone(__self_0)) - } - FollowEvent::BestBlockChanged(__self_0) => { - FollowEvent::BestBlockChanged( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::Finalized(__self_0) => { - FollowEvent::Finalized(::core::clone::Clone::clone(__self_0)) - } - FollowEvent::OperationBodyDone(__self_0) => { - FollowEvent::OperationBodyDone( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationCallDone(__self_0) => { - FollowEvent::OperationCallDone( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationStorageItems(__self_0) => { - FollowEvent::OperationStorageItems( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationWaitingForContinue(__self_0) => { - FollowEvent::OperationWaitingForContinue( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationStorageDone(__self_0) => { - FollowEvent::OperationStorageDone( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationInaccessible(__self_0) => { - FollowEvent::OperationInaccessible( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationError(__self_0) => { - FollowEvent::OperationError( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::Stop => FollowEvent::Stop, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for FollowEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for FollowEvent { - #[inline] - fn eq(&self, other: &FollowEvent) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - FollowEvent::Initialized(__self_0), - FollowEvent::Initialized(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::NewBlock(__self_0), - FollowEvent::NewBlock(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::BestBlockChanged(__self_0), - FollowEvent::BestBlockChanged(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::Finalized(__self_0), - FollowEvent::Finalized(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationBodyDone(__self_0), - FollowEvent::OperationBodyDone(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationCallDone(__self_0), - FollowEvent::OperationCallDone(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationStorageItems(__self_0), - FollowEvent::OperationStorageItems(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationWaitingForContinue(__self_0), - FollowEvent::OperationWaitingForContinue(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationStorageDone(__self_0), - FollowEvent::OperationStorageDone(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationInaccessible(__self_0), - FollowEvent::OperationInaccessible(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationError(__self_0), - FollowEvent::OperationError(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for FollowEvent { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for FollowEvent - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __field6, - __field7, - __field8, - __field9, - __field10, - __field11, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - 5u64 => _serde::__private::Ok(__Field::__field5), - 6u64 => _serde::__private::Ok(__Field::__field6), - 7u64 => _serde::__private::Ok(__Field::__field7), - 8u64 => _serde::__private::Ok(__Field::__field8), - 9u64 => _serde::__private::Ok(__Field::__field9), - 10u64 => _serde::__private::Ok(__Field::__field10), - 11u64 => _serde::__private::Ok(__Field::__field11), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 12", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "initialized" => _serde::__private::Ok(__Field::__field0), - "newBlock" => _serde::__private::Ok(__Field::__field1), - "bestBlockChanged" => { - _serde::__private::Ok(__Field::__field2) - } - "finalized" => _serde::__private::Ok(__Field::__field3), - "operationBodyDone" => { - _serde::__private::Ok(__Field::__field4) - } - "operationCallDone" => { - _serde::__private::Ok(__Field::__field5) - } - "operationStorageItems" => { - _serde::__private::Ok(__Field::__field6) - } - "operationWaitingForContinue" => { - _serde::__private::Ok(__Field::__field7) - } - "operationStorageDone" => { - _serde::__private::Ok(__Field::__field8) - } - "operationInaccessible" => { - _serde::__private::Ok(__Field::__field9) - } - "operationError" => { - _serde::__private::Ok(__Field::__field10) - } - "stop" => _serde::__private::Ok(__Field::__field11), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"initialized" => _serde::__private::Ok(__Field::__field0), - b"newBlock" => _serde::__private::Ok(__Field::__field1), - b"bestBlockChanged" => { - _serde::__private::Ok(__Field::__field2) - } - b"finalized" => _serde::__private::Ok(__Field::__field3), - b"operationBodyDone" => { - _serde::__private::Ok(__Field::__field4) - } - b"operationCallDone" => { - _serde::__private::Ok(__Field::__field5) - } - b"operationStorageItems" => { - _serde::__private::Ok(__Field::__field6) - } - b"operationWaitingForContinue" => { - _serde::__private::Ok(__Field::__field7) - } - b"operationStorageDone" => { - _serde::__private::Ok(__Field::__field8) - } - b"operationInaccessible" => { - _serde::__private::Ok(__Field::__field9) - } - b"operationError" => { - _serde::__private::Ok(__Field::__field10) - } - b"stop" => _serde::__private::Ok(__Field::__field11), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "initialized", - "newBlock", - "bestBlockChanged", - "finalized", - "operationBodyDone", - "operationCallDone", - "operationStorageItems", - "operationWaitingForContinue", - "operationStorageDone", - "operationInaccessible", - "operationError", - "stop", - ]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::TaggedContentVisitor::< - __Field, - >::new("event", "internally tagged enum FollowEvent"), - )?; - let __deserializer = _serde::__private::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::__private::Result::map( - as _serde::Deserialize>::deserialize(__deserializer), - FollowEvent::Initialized, - ) - } - __Field::__field1 => { - _serde::__private::Result::map( - as _serde::Deserialize>::deserialize(__deserializer), - FollowEvent::NewBlock, - ) - } - __Field::__field2 => { - _serde::__private::Result::map( - as _serde::Deserialize>::deserialize(__deserializer), - FollowEvent::BestBlockChanged, - ) - } - __Field::__field3 => { - _serde::__private::Result::map( - as _serde::Deserialize>::deserialize(__deserializer), - FollowEvent::Finalized, - ) - } - __Field::__field4 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationBodyDone, - ) - } - __Field::__field5 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationCallDone, - ) - } - __Field::__field6 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationStorageItems, - ) - } - __Field::__field7 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationWaitingForContinue, - ) - } - __Field::__field8 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationStorageDone, - ) - } - __Field::__field9 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationInaccessible, - ) - } - __Field::__field10 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationError, - ) - } - __Field::__field11 => { - _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::InternallyTaggedUnitVisitor::new( - "FollowEvent", - "Stop", - ), - )?; - _serde::__private::Ok(FollowEvent::Stop) - } - } - } - } - }; - /// Contain information about the latest finalized block. - /// - /// # Note - /// - /// This is the first event generated by the `follow` subscription - /// and is submitted only once. - #[serde(rename_all = "camelCase")] - pub struct Initialized { - /// The hash of the latest finalized block. - pub finalized_block_hash: Hash, - /// The runtime version of the finalized block. - /// - /// # Note - /// - /// This is present only if the `with_runtime` flag is set for - /// the `follow` subscription. - pub finalized_block_runtime: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug for Initialized { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Initialized", - "finalized_block_hash", - &self.finalized_block_hash, - "finalized_block_runtime", - &&self.finalized_block_runtime, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for Initialized { - #[inline] - fn clone(&self) -> Initialized { - Initialized { - finalized_block_hash: ::core::clone::Clone::clone( - &self.finalized_block_hash, - ), - finalized_block_runtime: ::core::clone::Clone::clone( - &self.finalized_block_runtime, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Initialized {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for Initialized { - #[inline] - fn eq(&self, other: &Initialized) -> bool { - self.finalized_block_hash == other.finalized_block_hash - && self.finalized_block_runtime == other.finalized_block_runtime - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Initialized { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for Initialized - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "finalizedBlockHash" => { - _serde::__private::Ok(__Field::__field0) - } - "finalizedBlockRuntime" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"finalizedBlockHash" => { - _serde::__private::Ok(__Field::__field0) - } - b"finalizedBlockRuntime" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = Initialized; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct Initialized", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Initialized with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Initialized with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(Initialized { - finalized_block_hash: __field0, - finalized_block_runtime: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - Option, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "finalizedBlockHash", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "finalizedBlockRuntime", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("finalizedBlockHash")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field( - "finalizedBlockRuntime", - )? - } - }; - _serde::__private::Ok(Initialized { - finalized_block_hash: __field0, - finalized_block_runtime: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "finalizedBlockHash", - "finalizedBlockRuntime", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Initialized", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The runtime event generated if the `follow` subscription - /// has set the `with_runtime` flag. - #[serde(rename_all = "camelCase")] - #[serde(tag = "type")] - pub enum RuntimeEvent { - /// The runtime version of this block. - Valid(RuntimeVersionEvent), - /// The runtime could not be obtained due to an error. - Invalid(ErrorEvent), - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - RuntimeEvent::Valid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Valid", - &__self_0, - ) - } - RuntimeEvent::Invalid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Invalid", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeEvent { - #[inline] - fn clone(&self) -> RuntimeEvent { - match self { - RuntimeEvent::Valid(__self_0) => { - RuntimeEvent::Valid(::core::clone::Clone::clone(__self_0)) - } - RuntimeEvent::Invalid(__self_0) => { - RuntimeEvent::Invalid(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeEvent { - #[inline] - fn eq(&self, other: &RuntimeEvent) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - RuntimeEvent::Valid(__self_0), - RuntimeEvent::Valid(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - RuntimeEvent::Invalid(__self_0), - RuntimeEvent::Invalid(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeEvent { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RuntimeEvent { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "valid" => _serde::__private::Ok(__Field::__field0), - "invalid" => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"valid" => _serde::__private::Ok(__Field::__field0), - b"invalid" => _serde::__private::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &["valid", "invalid"]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::TaggedContentVisitor::< - __Field, - >::new("type", "internally tagged enum RuntimeEvent"), - )?; - let __deserializer = _serde::__private::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - RuntimeEvent::Valid, - ) - } - __Field::__field1 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - RuntimeEvent::Invalid, - ) - } - } - } - } - }; - /// The runtime specification of the current block. - /// - /// This event is generated for: - /// - the first announced block by the follow subscription - /// - blocks that suffered a change in runtime compared with their parents - #[serde(rename_all = "camelCase")] - pub struct RuntimeVersionEvent { - /// Details about this runtime. - pub spec: RuntimeSpec, - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeVersionEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "RuntimeVersionEvent", - "spec", - &&self.spec, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeVersionEvent { - #[inline] - fn clone(&self) -> RuntimeVersionEvent { - RuntimeVersionEvent { - spec: ::core::clone::Clone::clone(&self.spec), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeVersionEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeVersionEvent { - #[inline] - fn eq(&self, other: &RuntimeVersionEvent) -> bool { - self.spec == other.spec - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeVersionEvent { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RuntimeVersionEvent { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "spec" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"spec" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = RuntimeVersionEvent; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct RuntimeVersionEvent", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - RuntimeSpec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct RuntimeVersionEvent with 1 element", - ), - ); - } - }; - _serde::__private::Ok(RuntimeVersionEvent { - spec: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("spec"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - RuntimeSpec, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("spec")? - } - }; - _serde::__private::Ok(RuntimeVersionEvent { - spec: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["spec"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "RuntimeVersionEvent", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - RuntimeVersionEvent, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// This contains the runtime version information necessary to make transactions, and is obtained from - /// the "initialized" event of `chainHead_follow` if the `withRuntime` flag is set. - #[serde(rename_all = "camelCase")] - pub struct RuntimeSpec { - /// Opaque string indicating the name of the chain. - pub spec_name: String, - /// Opaque string indicating the name of the implementation of the chain. - pub impl_name: String, - /// Opaque integer. The JSON-RPC client can assume that the Runtime API call to `Metadata_metadata` - /// will always produce the same output as long as the specVersion is the same. - pub spec_version: u32, - /// Opaque integer. Whenever the runtime code changes in a backwards-compatible way, the implVersion - /// is modified while the specVersion is left untouched. - pub impl_version: u32, - /// Opaque integer. Necessary when building the bytes of a transaction. Transactions that have been - /// generated with a different `transaction_version` are incompatible. - pub transaction_version: u32, - /// Object containing a list of "entry point APIs" supported by the runtime. Each key is an opaque string - /// indicating the API, and each value is an integer version number. Before making a runtime call (using - /// chainHead_call), you should make sure that this list contains the entry point API corresponding to the - /// call and with a known version number. - /// - /// **Note:** In Substrate, the keys in the apis field consists of the hexadecimal-encoded 8-bytes blake2 - /// hash of the name of the API. For example, the `TaggedTransactionQueue` API is 0xd2bc9897eed08f15. - #[serde(with = "hashmap_as_tuple_list")] - pub apis: HashMap, - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeSpec { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "spec_name", - "impl_name", - "spec_version", - "impl_version", - "transaction_version", - "apis", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.spec_name, - &self.impl_name, - &self.spec_version, - &self.impl_version, - &self.transaction_version, - &&self.apis, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "RuntimeSpec", - names, - values, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeSpec { - #[inline] - fn clone(&self) -> RuntimeSpec { - RuntimeSpec { - spec_name: ::core::clone::Clone::clone(&self.spec_name), - impl_name: ::core::clone::Clone::clone(&self.impl_name), - spec_version: ::core::clone::Clone::clone(&self.spec_version), - impl_version: ::core::clone::Clone::clone(&self.impl_version), - transaction_version: ::core::clone::Clone::clone( - &self.transaction_version, - ), - apis: ::core::clone::Clone::clone(&self.apis), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeSpec {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeSpec { - #[inline] - fn eq(&self, other: &RuntimeSpec) -> bool { - self.spec_name == other.spec_name - && self.impl_name == other.impl_name - && self.spec_version == other.spec_version - && self.impl_version == other.impl_version - && self.transaction_version == other.transaction_version - && self.apis == other.apis - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeSpec { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RuntimeSpec { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - 5u64 => _serde::__private::Ok(__Field::__field5), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "specName" => _serde::__private::Ok(__Field::__field0), - "implName" => _serde::__private::Ok(__Field::__field1), - "specVersion" => _serde::__private::Ok(__Field::__field2), - "implVersion" => _serde::__private::Ok(__Field::__field3), - "transactionVersion" => { - _serde::__private::Ok(__Field::__field4) - } - "apis" => _serde::__private::Ok(__Field::__field5), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"specName" => _serde::__private::Ok(__Field::__field0), - b"implName" => _serde::__private::Ok(__Field::__field1), - b"specVersion" => _serde::__private::Ok(__Field::__field2), - b"implVersion" => _serde::__private::Ok(__Field::__field3), - b"transactionVersion" => { - _serde::__private::Ok(__Field::__field4) - } - b"apis" => _serde::__private::Ok(__Field::__field5), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = RuntimeSpec; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct RuntimeSpec", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field5 = match { - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: HashMap, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: hashmap_as_tuple_list::deserialize(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 5usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - _serde::__private::Ok(RuntimeSpec { - spec_name: __field0, - impl_name: __field1, - spec_version: __field2, - impl_version: __field3, - transaction_version: __field4, - apis: __field5, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option = _serde::__private::None; - let mut __field3: _serde::__private::Option = _serde::__private::None; - let mut __field4: _serde::__private::Option = _serde::__private::None; - let mut __field5: _serde::__private::Option< - HashMap, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "specName", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "implName", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "specVersion", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private::Option::is_some(&__field3) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "implVersion", - ), - ); - } - __field3 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private::Option::is_some(&__field4) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "transactionVersion", - ), - ); - } - __field4 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field5 => { - if _serde::__private::Option::is_some(&__field5) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("apis"), - ); - } - __field5 = _serde::__private::Some({ - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: HashMap, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: hashmap_as_tuple_list::deserialize(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - match _serde::de::MapAccess::next_value::< - __DeserializeWith<'de>, - >(&mut __map) { - _serde::__private::Ok(__wrapper) => __wrapper.value, - _serde::__private::Err(__err) => { - return _serde::__private::Err(__err); - } - } - }); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("specName")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("implName")? - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("specVersion")? - } - }; - let __field3 = match __field3 { - _serde::__private::Some(__field3) => __field3, - _serde::__private::None => { - _serde::__private::de::missing_field("implVersion")? - } - }; - let __field4 = match __field4 { - _serde::__private::Some(__field4) => __field4, - _serde::__private::None => { - _serde::__private::de::missing_field("transactionVersion")? - } - }; - let __field5 = match __field5 { - _serde::__private::Some(__field5) => __field5, - _serde::__private::None => { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::missing_field("apis"), - ); - } - }; - _serde::__private::Ok(RuntimeSpec { - spec_name: __field0, - impl_name: __field1, - spec_version: __field2, - impl_version: __field3, - transaction_version: __field4, - apis: __field5, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "specName", - "implName", - "specVersion", - "implVersion", - "transactionVersion", - "apis", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "RuntimeSpec", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The operation could not be processed due to an error. - #[serde(rename_all = "camelCase")] - pub struct ErrorEvent { - /// Reason of the error. - pub error: String, - } - #[automatically_derived] - impl ::core::fmt::Debug for ErrorEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "ErrorEvent", - "error", - &&self.error, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for ErrorEvent { - #[inline] - fn clone(&self) -> ErrorEvent { - ErrorEvent { - error: ::core::clone::Clone::clone(&self.error), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ErrorEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ErrorEvent { - #[inline] - fn eq(&self, other: &ErrorEvent) -> bool { - self.error == other.error - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ErrorEvent { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ErrorEvent { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ErrorEvent; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct ErrorEvent", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ErrorEvent with 1 element", - ), - ); - } - }; - _serde::__private::Ok(ErrorEvent { error: __field0 }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(ErrorEvent { error: __field0 }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["error"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ErrorEvent", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate a new non-finalized block. - #[serde(rename_all = "camelCase")] - pub struct NewBlock { - /// The hash of the new block. - pub block_hash: Hash, - /// The parent hash of the new block. - pub parent_block_hash: Hash, - /// The runtime version of the new block. - /// - /// # Note - /// - /// This is present only if the `with_runtime` flag is set for - /// the `follow` subscription. - pub new_runtime: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug for NewBlock { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "NewBlock", - "block_hash", - &self.block_hash, - "parent_block_hash", - &self.parent_block_hash, - "new_runtime", - &&self.new_runtime, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for NewBlock { - #[inline] - fn clone(&self) -> NewBlock { - NewBlock { - block_hash: ::core::clone::Clone::clone(&self.block_hash), - parent_block_hash: ::core::clone::Clone::clone( - &self.parent_block_hash, - ), - new_runtime: ::core::clone::Clone::clone(&self.new_runtime), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for NewBlock {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for NewBlock { - #[inline] - fn eq(&self, other: &NewBlock) -> bool { - self.block_hash == other.block_hash - && self.parent_block_hash == other.parent_block_hash - && self.new_runtime == other.new_runtime - } - } - #[automatically_derived] - impl ::core::cmp::Eq for NewBlock { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for NewBlock - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "blockHash" => _serde::__private::Ok(__Field::__field0), - "parentBlockHash" => { - _serde::__private::Ok(__Field::__field1) - } - "newRuntime" => _serde::__private::Ok(__Field::__field2), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"blockHash" => _serde::__private::Ok(__Field::__field0), - b"parentBlockHash" => { - _serde::__private::Ok(__Field::__field1) - } - b"newRuntime" => _serde::__private::Ok(__Field::__field2), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = NewBlock; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct NewBlock", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct NewBlock with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct NewBlock with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct NewBlock with 3 elements", - ), - ); - } - }; - _serde::__private::Ok(NewBlock { - block_hash: __field0, - parent_block_hash: __field1, - new_runtime: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option< - Option, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "blockHash", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "parentBlockHash", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "newRuntime", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("blockHash")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("parentBlockHash")? - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("newRuntime")? - } - }; - _serde::__private::Ok(NewBlock { - block_hash: __field0, - parent_block_hash: __field1, - new_runtime: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "blockHash", - "parentBlockHash", - "newRuntime", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "NewBlock", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate the block hash of the new best block. - #[serde(rename_all = "camelCase")] - pub struct BestBlockChanged { - /// The block hash of the new best block. - pub best_block_hash: Hash, - } - #[automatically_derived] - impl ::core::fmt::Debug - for BestBlockChanged { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "BestBlockChanged", - "best_block_hash", - &&self.best_block_hash, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for BestBlockChanged { - #[inline] - fn clone(&self) -> BestBlockChanged { - BestBlockChanged { - best_block_hash: ::core::clone::Clone::clone( - &self.best_block_hash, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BestBlockChanged {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for BestBlockChanged { - #[inline] - fn eq(&self, other: &BestBlockChanged) -> bool { - self.best_block_hash == other.best_block_hash - } - } - #[automatically_derived] - impl ::core::cmp::Eq for BestBlockChanged { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for BestBlockChanged - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "bestBlockHash" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"bestBlockHash" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - BestBlockChanged, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = BestBlockChanged; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct BestBlockChanged", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct BestBlockChanged with 1 element", - ), - ); - } - }; - _serde::__private::Ok(BestBlockChanged { - best_block_hash: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "bestBlockHash", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("bestBlockHash")? - } - }; - _serde::__private::Ok(BestBlockChanged { - best_block_hash: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["bestBlockHash"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "BestBlockChanged", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - BestBlockChanged, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate the finalized and pruned block hashes. - #[serde(rename_all = "camelCase")] - pub struct Finalized { - /// Block hashes that are finalized. - pub finalized_block_hashes: Vec, - /// Block hashes that are pruned (removed). - pub pruned_block_hashes: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for Finalized { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Finalized", - "finalized_block_hashes", - &self.finalized_block_hashes, - "pruned_block_hashes", - &&self.pruned_block_hashes, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for Finalized { - #[inline] - fn clone(&self) -> Finalized { - Finalized { - finalized_block_hashes: ::core::clone::Clone::clone( - &self.finalized_block_hashes, - ), - pruned_block_hashes: ::core::clone::Clone::clone( - &self.pruned_block_hashes, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Finalized {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for Finalized { - #[inline] - fn eq(&self, other: &Finalized) -> bool { - self.finalized_block_hashes == other.finalized_block_hashes - && self.pruned_block_hashes == other.pruned_block_hashes - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Finalized { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for Finalized - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "finalizedBlockHashes" => { - _serde::__private::Ok(__Field::__field0) - } - "prunedBlockHashes" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"finalizedBlockHashes" => { - _serde::__private::Ok(__Field::__field0) - } - b"prunedBlockHashes" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = Finalized; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct Finalized", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Finalized with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Finalized with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(Finalized { - finalized_block_hashes: __field0, - pruned_block_hashes: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option> = _serde::__private::None; - let mut __field1: _serde::__private::Option> = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "finalizedBlockHashes", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "prunedBlockHashes", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field( - "finalizedBlockHashes", - )? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("prunedBlockHashes")? - } - }; - _serde::__private::Ok(Finalized { - finalized_block_hashes: __field0, - pruned_block_hashes: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "finalizedBlockHashes", - "prunedBlockHashes", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Finalized", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate the operation id of the event. - #[serde(rename_all = "camelCase")] - pub struct OperationId { - /// The operation id of the event. - pub operation_id: String, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "OperationId", - "operation_id", - &&self.operation_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationId { - #[inline] - fn clone(&self) -> OperationId { - OperationId { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationId { - #[inline] - fn eq(&self, other: &OperationId) -> bool { - self.operation_id == other.operation_id - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationId; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationId", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationId with 1 element", - ), - ); - } - }; - _serde::__private::Ok(OperationId { - operation_id: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - _serde::__private::Ok(OperationId { - operation_id: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["operationId"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationId", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The response of the `chainHead_body` method. - #[serde(rename_all = "camelCase")] - pub struct OperationBodyDone { - /// The operation id of the event. - pub operation_id: String, - /// Array of hexadecimal-encoded scale-encoded extrinsics found in the block. - pub value: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationBodyDone { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "OperationBodyDone", - "operation_id", - &self.operation_id, - "value", - &&self.value, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationBodyDone { - #[inline] - fn clone(&self) -> OperationBodyDone { - OperationBodyDone { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - value: ::core::clone::Clone::clone(&self.value), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationBodyDone {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationBodyDone { - #[inline] - fn eq(&self, other: &OperationBodyDone) -> bool { - self.operation_id == other.operation_id && self.value == other.value - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationBodyDone { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationBodyDone { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "value" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"value" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationBodyDone; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationBodyDone", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationBodyDone with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct OperationBodyDone with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(OperationBodyDone { - operation_id: __field0, - value: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option> = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("value"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("value")? - } - }; - _serde::__private::Ok(OperationBodyDone { - operation_id: __field0, - value: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "value", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationBodyDone", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The response of the `chainHead_call` method. - #[serde(rename_all = "camelCase")] - pub struct OperationCallDone { - /// The operation id of the event. - pub operation_id: String, - /// Hexadecimal-encoded output of the runtime function call. - pub output: Bytes, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationCallDone { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "OperationCallDone", - "operation_id", - &self.operation_id, - "output", - &&self.output, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationCallDone { - #[inline] - fn clone(&self) -> OperationCallDone { - OperationCallDone { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - output: ::core::clone::Clone::clone(&self.output), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationCallDone {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationCallDone { - #[inline] - fn eq(&self, other: &OperationCallDone) -> bool { - self.operation_id == other.operation_id - && self.output == other.output - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationCallDone { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationCallDone { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "output" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"output" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationCallDone; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationCallDone", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationCallDone with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Bytes, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct OperationCallDone with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(OperationCallDone { - operation_id: __field0, - output: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("output"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("output")? - } - }; - _serde::__private::Ok(OperationCallDone { - operation_id: __field0, - output: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "output", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationCallDone", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The response of the `chainHead_call` method. - #[serde(rename_all = "camelCase")] - pub struct OperationStorageItems { - /// The operation id of the event. - pub operation_id: String, - /// The resulting items. - pub items: VecDeque, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationStorageItems { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "OperationStorageItems", - "operation_id", - &self.operation_id, - "items", - &&self.items, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationStorageItems { - #[inline] - fn clone(&self) -> OperationStorageItems { - OperationStorageItems { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - items: ::core::clone::Clone::clone(&self.items), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationStorageItems {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationStorageItems { - #[inline] - fn eq(&self, other: &OperationStorageItems) -> bool { - self.operation_id == other.operation_id && self.items == other.items - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationStorageItems { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationStorageItems { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "items" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"items" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData< - OperationStorageItems, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationStorageItems; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationStorageItems", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationStorageItems with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - VecDeque, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct OperationStorageItems with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(OperationStorageItems { - operation_id: __field0, - items: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - VecDeque, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("items"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - VecDeque, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("items")? - } - }; - _serde::__private::Ok(OperationStorageItems { - operation_id: __field0, - items: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "items", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationStorageItems", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - OperationStorageItems, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate a problem during the operation. - #[serde(rename_all = "camelCase")] - pub struct OperationError { - /// The operation id of the event. - pub operation_id: String, - /// The reason of the error. - pub error: String, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "OperationError", - "operation_id", - &self.operation_id, - "error", - &&self.error, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationError { - #[inline] - fn clone(&self) -> OperationError { - OperationError { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - error: ::core::clone::Clone::clone(&self.error), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationError { - #[inline] - fn eq(&self, other: &OperationError) -> bool { - self.operation_id == other.operation_id && self.error == other.error - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationError { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "error" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"error" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationError; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationError", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationError with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct OperationError with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(OperationError { - operation_id: __field0, - error: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(OperationError { - operation_id: __field0, - error: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "error", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationError", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The storage result. - #[serde(rename_all = "camelCase")] - pub struct StorageResult { - /// The hex-encoded key of the result. - pub key: Bytes, - /// The result of the query. - #[serde(flatten)] - pub result: StorageResultType, - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "StorageResult", - "key", - &self.key, - "result", - &&self.result, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageResult { - #[inline] - fn clone(&self) -> StorageResult { - StorageResult { - key: ::core::clone::Clone::clone(&self.key), - result: ::core::clone::Clone::clone(&self.result), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageResult {} - #[automatically_derived] - impl ::core::cmp::PartialEq for StorageResult { - #[inline] - fn eq(&self, other: &StorageResult) -> bool { - self.key == other.key && self.result == other.result - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageResult { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for StorageResult { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field<'de> { - __field0, - __other(_serde::__private::de::Content<'de>), - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field<'de>; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_bool<__E>( - self, - __value: bool, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::Bool(__value), - ), - ) - } - fn visit_i8<__E>( - self, - __value: i8, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I8(__value), - ), - ) - } - fn visit_i16<__E>( - self, - __value: i16, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I16(__value), - ), - ) - } - fn visit_i32<__E>( - self, - __value: i32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I32(__value), - ), - ) - } - fn visit_i64<__E>( - self, - __value: i64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I64(__value), - ), - ) - } - fn visit_u8<__E>( - self, - __value: u8, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U8(__value), - ), - ) - } - fn visit_u16<__E>( - self, - __value: u16, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U16(__value), - ), - ) - } - fn visit_u32<__E>( - self, - __value: u32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U32(__value), - ), - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U64(__value), - ), - ) - } - fn visit_f32<__E>( - self, - __value: f32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::F32(__value), - ), - ) - } - fn visit_f64<__E>( - self, - __value: f64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::F64(__value), - ), - ) - } - fn visit_char<__E>( - self, - __value: char, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::Char(__value), - ), - ) - } - fn visit_unit<__E>( - self, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other(_serde::__private::de::Content::Unit), - ) - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "key" => _serde::__private::Ok(__Field::__field0), - _ => { - let __value = _serde::__private::de::Content::String( - _serde::__private::ToString::to_string(__value), - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"key" => _serde::__private::Ok(__Field::__field0), - _ => { - let __value = _serde::__private::de::Content::ByteBuf( - __value.to_vec(), - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_borrowed_str<__E>( - self, - __value: &'de str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "key" => _serde::__private::Ok(__Field::__field0), - _ => { - let __value = _serde::__private::de::Content::Str(__value); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_borrowed_bytes<__E>( - self, - __value: &'de [u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"key" => _serde::__private::Ok(__Field::__field0), - _ => { - let __value = _serde::__private::de::Content::Bytes( - __value, - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field<'de> { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = StorageResult; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct StorageResult", - ) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __collect = _serde::__private::Vec::< - _serde::__private::Option< - ( - _serde::__private::de::Content, - _serde::__private::de::Content, - ), - >, - >::new(); - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("key"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__other(__name) => { - __collect - .push( - _serde::__private::Some(( - __name, - _serde::de::MapAccess::next_value(&mut __map)?, - )), - ); - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("key")? - } - }; - let __field1: StorageResultType = _serde::de::Deserialize::deserialize( - _serde::__private::de::FlatMapDeserializer( - &mut __collect, - _serde::__private::PhantomData, - ), - )?; - _serde::__private::Ok(StorageResult { - key: __field0, - result: __field1, - }) - } - } - _serde::Deserializer::deserialize_map( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The type of the storage query. - #[serde(rename_all = "camelCase")] - pub enum StorageResultType { - /// Fetch the value of the provided key. - Value(Bytes), - /// Fetch the hash of the value of the provided key. - Hash(Bytes), - /// Fetch the closest descendant merkle value. - ClosestDescendantMerkleValue(Bytes), - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageResultType { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - StorageResultType::Value(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Value", - &__self_0, - ) - } - StorageResultType::Hash(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Hash", - &__self_0, - ) - } - StorageResultType::ClosestDescendantMerkleValue(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ClosestDescendantMerkleValue", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageResultType { - #[inline] - fn clone(&self) -> StorageResultType { - match self { - StorageResultType::Value(__self_0) => { - StorageResultType::Value( - ::core::clone::Clone::clone(__self_0), - ) - } - StorageResultType::Hash(__self_0) => { - StorageResultType::Hash( - ::core::clone::Clone::clone(__self_0), - ) - } - StorageResultType::ClosestDescendantMerkleValue(__self_0) => { - StorageResultType::ClosestDescendantMerkleValue( - ::core::clone::Clone::clone(__self_0), - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageResultType {} - #[automatically_derived] - impl ::core::cmp::PartialEq for StorageResultType { - #[inline] - fn eq(&self, other: &StorageResultType) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - StorageResultType::Value(__self_0), - StorageResultType::Value(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - StorageResultType::Hash(__self_0), - StorageResultType::Hash(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - StorageResultType::ClosestDescendantMerkleValue(__self_0), - StorageResultType::ClosestDescendantMerkleValue(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageResultType { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for StorageResultType { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 3", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "value" => _serde::__private::Ok(__Field::__field0), - "hash" => _serde::__private::Ok(__Field::__field1), - "closestDescendantMerkleValue" => { - _serde::__private::Ok(__Field::__field2) - } - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"value" => _serde::__private::Ok(__Field::__field0), - b"hash" => _serde::__private::Ok(__Field::__field1), - b"closestDescendantMerkleValue" => { - _serde::__private::Ok(__Field::__field2) - } - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = StorageResultType; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "enum StorageResultType", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Bytes, - >(__variant), - StorageResultType::Value, - ) - } - (__Field::__field1, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Bytes, - >(__variant), - StorageResultType::Hash, - ) - } - (__Field::__field2, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Bytes, - >(__variant), - StorageResultType::ClosestDescendantMerkleValue, - ) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "value", - "hash", - "closestDescendantMerkleValue", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "StorageResultType", - VARIANTS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The method response of `chainHead_body`, `chainHead_call` and `chainHead_storage`. - #[serde(rename_all = "camelCase")] - #[serde(tag = "result")] - pub enum MethodResponse { - /// The method has started. - Started(MethodResponseStarted), - /// The RPC server cannot handle the request at the moment. - LimitReached, - } - #[automatically_derived] - impl ::core::fmt::Debug for MethodResponse { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - MethodResponse::Started(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Started", - &__self_0, - ) - } - MethodResponse::LimitReached => { - ::core::fmt::Formatter::write_str(f, "LimitReached") - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for MethodResponse { - #[inline] - fn clone(&self) -> MethodResponse { - match self { - MethodResponse::Started(__self_0) => { - MethodResponse::Started( - ::core::clone::Clone::clone(__self_0), - ) - } - MethodResponse::LimitReached => MethodResponse::LimitReached, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for MethodResponse {} - #[automatically_derived] - impl ::core::cmp::PartialEq for MethodResponse { - #[inline] - fn eq(&self, other: &MethodResponse) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - MethodResponse::Started(__self_0), - MethodResponse::Started(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for MethodResponse { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for MethodResponse { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "started" => _serde::__private::Ok(__Field::__field0), - "limitReached" => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"started" => _serde::__private::Ok(__Field::__field0), - b"limitReached" => _serde::__private::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "started", - "limitReached", - ]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::TaggedContentVisitor::< - __Field, - >::new("result", "internally tagged enum MethodResponse"), - )?; - let __deserializer = _serde::__private::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - MethodResponse::Started, - ) - } - __Field::__field1 => { - _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::InternallyTaggedUnitVisitor::new( - "MethodResponse", - "LimitReached", - ), - )?; - _serde::__private::Ok(MethodResponse::LimitReached) - } - } - } - } - }; - /// The `started` result of a method. - #[serde(rename_all = "camelCase")] - pub struct MethodResponseStarted { - /// The operation id of the response. - pub operation_id: String, - /// The number of items from the back of the `chainHead_storage` that have been discarded. - pub discarded_items: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug for MethodResponseStarted { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "MethodResponseStarted", - "operation_id", - &self.operation_id, - "discarded_items", - &&self.discarded_items, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for MethodResponseStarted { - #[inline] - fn clone(&self) -> MethodResponseStarted { - MethodResponseStarted { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - discarded_items: ::core::clone::Clone::clone( - &self.discarded_items, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for MethodResponseStarted {} - #[automatically_derived] - impl ::core::cmp::PartialEq for MethodResponseStarted { - #[inline] - fn eq(&self, other: &MethodResponseStarted) -> bool { - self.operation_id == other.operation_id - && self.discarded_items == other.discarded_items - } - } - #[automatically_derived] - impl ::core::cmp::Eq for MethodResponseStarted { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for MethodResponseStarted { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "discardedItems" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"discardedItems" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData< - MethodResponseStarted, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = MethodResponseStarted; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct MethodResponseStarted", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct MethodResponseStarted with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct MethodResponseStarted with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(MethodResponseStarted { - operation_id: __field0, - discarded_items: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - Option, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "discardedItems", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("discardedItems")? - } - }; - _serde::__private::Ok(MethodResponseStarted { - operation_id: __field0, - discarded_items: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "discardedItems", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "MethodResponseStarted", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - MethodResponseStarted, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The storage item received as parameter. - #[serde(rename_all = "camelCase")] - pub struct StorageQuery { - /// The provided key. - pub key: Key, - /// The type of the storage query. - #[serde(rename = "type")] - pub query_type: StorageQueryType, - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageQuery { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "StorageQuery", - "key", - &self.key, - "query_type", - &&self.query_type, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageQuery { - #[inline] - fn clone(&self) -> StorageQuery { - StorageQuery { - key: ::core::clone::Clone::clone(&self.key), - query_type: ::core::clone::Clone::clone(&self.query_type), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageQuery {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for StorageQuery { - #[inline] - fn eq(&self, other: &StorageQuery) -> bool { - self.key == other.key && self.query_type == other.query_type - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageQuery { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for StorageQuery - where - Key: _serde::Serialize, - { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "StorageQuery", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key", - &self.key, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "type", - &self.query_type, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Key> _serde::Deserialize<'de> for StorageQuery - where - Key: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "key" => _serde::__private::Ok(__Field::__field0), - "type" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"key" => _serde::__private::Ok(__Field::__field0), - b"type" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Key> - where - Key: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Key> _serde::de::Visitor<'de> for __Visitor<'de, Key> - where - Key: _serde::Deserialize<'de>, - { - type Value = StorageQuery; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct StorageQuery", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Key, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct StorageQuery with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - StorageQueryType, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct StorageQuery with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(StorageQuery { - key: __field0, - query_type: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - StorageQueryType, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("key"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("type"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - StorageQueryType, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("key")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("type")? - } - }; - _serde::__private::Ok(StorageQuery { - key: __field0, - query_type: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["key", "type"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "StorageQuery", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The type of the storage query. - #[serde(rename_all = "camelCase")] - pub enum StorageQueryType { - /// Fetch the value of the provided key. - Value, - /// Fetch the hash of the value of the provided key. - Hash, - /// Fetch the closest descendant merkle value. - ClosestDescendantMerkleValue, - /// Fetch the values of all descendants of they provided key. - DescendantsValues, - /// Fetch the hashes of the values of all descendants of they provided key. - DescendantsHashes, - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageQueryType { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - StorageQueryType::Value => "Value", - StorageQueryType::Hash => "Hash", - StorageQueryType::ClosestDescendantMerkleValue => { - "ClosestDescendantMerkleValue" - } - StorageQueryType::DescendantsValues => "DescendantsValues", - StorageQueryType::DescendantsHashes => "DescendantsHashes", - }, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageQueryType { - #[inline] - fn clone(&self) -> StorageQueryType { - match self { - StorageQueryType::Value => StorageQueryType::Value, - StorageQueryType::Hash => StorageQueryType::Hash, - StorageQueryType::ClosestDescendantMerkleValue => { - StorageQueryType::ClosestDescendantMerkleValue - } - StorageQueryType::DescendantsValues => { - StorageQueryType::DescendantsValues - } - StorageQueryType::DescendantsHashes => { - StorageQueryType::DescendantsHashes - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageQueryType {} - #[automatically_derived] - impl ::core::cmp::PartialEq for StorageQueryType { - #[inline] - fn eq(&self, other: &StorageQueryType) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageQueryType { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for StorageQueryType { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - StorageQueryType::Value => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 0u32, - "value", - ) - } - StorageQueryType::Hash => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 1u32, - "hash", - ) - } - StorageQueryType::ClosestDescendantMerkleValue => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 2u32, - "closestDescendantMerkleValue", - ) - } - StorageQueryType::DescendantsValues => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 3u32, - "descendantsValues", - ) - } - StorageQueryType::DescendantsHashes => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 4u32, - "descendantsHashes", - ) - } - } - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for StorageQueryType { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 5", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "value" => _serde::__private::Ok(__Field::__field0), - "hash" => _serde::__private::Ok(__Field::__field1), - "closestDescendantMerkleValue" => { - _serde::__private::Ok(__Field::__field2) - } - "descendantsValues" => { - _serde::__private::Ok(__Field::__field3) - } - "descendantsHashes" => { - _serde::__private::Ok(__Field::__field4) - } - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"value" => _serde::__private::Ok(__Field::__field0), - b"hash" => _serde::__private::Ok(__Field::__field1), - b"closestDescendantMerkleValue" => { - _serde::__private::Ok(__Field::__field2) - } - b"descendantsValues" => { - _serde::__private::Ok(__Field::__field3) - } - b"descendantsHashes" => { - _serde::__private::Ok(__Field::__field4) - } - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = StorageQueryType; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "enum StorageQueryType", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(StorageQueryType::Value) - } - (__Field::__field1, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(StorageQueryType::Hash) - } - (__Field::__field2, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok( - StorageQueryType::ClosestDescendantMerkleValue, - ) - } - (__Field::__field3, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(StorageQueryType::DescendantsValues) - } - (__Field::__field4, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(StorageQueryType::DescendantsHashes) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "value", - "hash", - "closestDescendantMerkleValue", - "descendantsValues", - "descendantsHashes", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "StorageQueryType", - VARIANTS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// A subscription which returns follow events, and ends when a Stop event occurs. - pub struct FollowSubscription { - sub: RpcSubscription>, - done: bool, - } - impl FollowSubscription { - /// Fetch the next item in the stream. - pub async fn next(&mut self) -> Option<::Item> { - ::next(self).await - } - /// Fetch the subscription ID for the stream. - pub fn subscription_id(&self) -> Option<&str> { - self.sub.subscription_id() - } - } - impl Stream for FollowSubscription { - type Item = > as Stream>::Item; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - if self.done { - return Poll::Ready(None); - } - let res = self.sub.poll_next_unpin(cx); - if let Poll::Ready(Some(Ok(FollowEvent::Stop))) = &res { - self.done = true; - } - res - } - } - /// A subscription which returns transaction status events, stopping - /// when no more events will be sent. - pub struct TransactionSubscription { - sub: RpcSubscription>, - done: bool, - } - impl TransactionSubscription { - /// Fetch the next item in the stream. - pub async fn next(&mut self) -> Option<::Item> { - ::next(self).await - } - } - impl Stream for TransactionSubscription { - type Item = > as Stream>::Item; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - if self.done { - return Poll::Ready(None); - } - let res = self.sub.poll_next_unpin(cx); - if let Poll::Ready(Some(Ok(res))) = &res { - if match res { - TransactionStatus::Dropped { .. } - | TransactionStatus::Error { .. } - | TransactionStatus::Invalid { .. } - | TransactionStatus::Finalized { .. } => true, - _ => false, - } { - self.done = true; - } - } - res - } - } - /// Transaction progress events - #[serde(rename_all = "camelCase")] - #[serde(tag = "event")] - pub enum TransactionStatus { - /// Transaction is part of the future queue. - Validated, - /// The transaction has been broadcast to other nodes. - Broadcasted { - /// Number of peers it's been broadcast to. - num_peers: u32, - }, - /// Transaction has been included in block with given details. - /// Null is returned if the transaction is no longer in any block - /// of the best chain. - BestChainBlockIncluded { - /// Details of the block it's been seen in. - block: Option>, - }, - /// The transaction is in a block that's been finalized. - Finalized { - /// Details of the block it's been seen in. - block: TransactionBlockDetails, - }, - /// Something went wrong in the node. - Error { - /// Human readable message; what went wrong. - error: String, - }, - /// Transaction is invalid (bad nonce, signature etc). - Invalid { - /// Human readable message; why was it invalid. - error: String, - }, - /// The transaction was dropped. - Dropped { - /// Was the transaction broadcasted to other nodes before being dropped? - broadcasted: bool, - /// Human readable message; why was it dropped. - error: String, - }, - } - #[automatically_derived] - impl ::core::fmt::Debug - for TransactionStatus { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionStatus::Validated => { - ::core::fmt::Formatter::write_str(f, "Validated") - } - TransactionStatus::Broadcasted { num_peers: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Broadcasted", - "num_peers", - &__self_0, - ) - } - TransactionStatus::BestChainBlockIncluded { block: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "BestChainBlockIncluded", - "block", - &__self_0, - ) - } - TransactionStatus::Finalized { block: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Finalized", - "block", - &__self_0, - ) - } - TransactionStatus::Error { error: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Error", - "error", - &__self_0, - ) - } - TransactionStatus::Invalid { error: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Invalid", - "error", - &__self_0, - ) - } - TransactionStatus::Dropped { - broadcasted: __self_0, - error: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Dropped", - "broadcasted", - __self_0, - "error", - &__self_1, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone - for TransactionStatus { - #[inline] - fn clone(&self) -> TransactionStatus { - match self { - TransactionStatus::Validated => TransactionStatus::Validated, - TransactionStatus::Broadcasted { num_peers: __self_0 } => { - TransactionStatus::Broadcasted { - num_peers: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::BestChainBlockIncluded { block: __self_0 } => { - TransactionStatus::BestChainBlockIncluded { - block: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Finalized { block: __self_0 } => { - TransactionStatus::Finalized { - block: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Error { error: __self_0 } => { - TransactionStatus::Error { - error: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Invalid { error: __self_0 } => { - TransactionStatus::Invalid { - error: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Dropped { - broadcasted: __self_0, - error: __self_1, - } => { - TransactionStatus::Dropped { - broadcasted: ::core::clone::Clone::clone(__self_0), - error: ::core::clone::Clone::clone(__self_1), - } - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionStatus {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for TransactionStatus { - #[inline] - fn eq(&self, other: &TransactionStatus) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionStatus::Broadcasted { num_peers: __self_0 }, - TransactionStatus::Broadcasted { num_peers: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::BestChainBlockIncluded { - block: __self_0, - }, - TransactionStatus::BestChainBlockIncluded { - block: __arg1_0, - }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Finalized { block: __self_0 }, - TransactionStatus::Finalized { block: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Error { error: __self_0 }, - TransactionStatus::Error { error: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Invalid { error: __self_0 }, - TransactionStatus::Invalid { error: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Dropped { - broadcasted: __self_0, - error: __self_1, - }, - TransactionStatus::Dropped { - broadcasted: __arg1_0, - error: __arg1_1, - }, - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TransactionStatus { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq< - Option>, - >; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for TransactionStatus - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __field6, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - 5u64 => _serde::__private::Ok(__Field::__field5), - 6u64 => _serde::__private::Ok(__Field::__field6), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 7", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "validated" => _serde::__private::Ok(__Field::__field0), - "broadcasted" => _serde::__private::Ok(__Field::__field1), - "bestChainBlockIncluded" => { - _serde::__private::Ok(__Field::__field2) - } - "finalized" => _serde::__private::Ok(__Field::__field3), - "error" => _serde::__private::Ok(__Field::__field4), - "invalid" => _serde::__private::Ok(__Field::__field5), - "dropped" => _serde::__private::Ok(__Field::__field6), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"validated" => _serde::__private::Ok(__Field::__field0), - b"broadcasted" => _serde::__private::Ok(__Field::__field1), - b"bestChainBlockIncluded" => { - _serde::__private::Ok(__Field::__field2) - } - b"finalized" => _serde::__private::Ok(__Field::__field3), - b"error" => _serde::__private::Ok(__Field::__field4), - b"invalid" => _serde::__private::Ok(__Field::__field5), - b"dropped" => _serde::__private::Ok(__Field::__field6), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "validated", - "broadcasted", - "bestChainBlockIncluded", - "finalized", - "error", - "invalid", - "dropped", - ]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::TaggedContentVisitor::< - __Field, - >::new("event", "internally tagged enum TransactionStatus"), - )?; - let __deserializer = _serde::__private::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::InternallyTaggedUnitVisitor::new( - "TransactionStatus", - "Validated", - ), - )?; - _serde::__private::Ok(TransactionStatus::Validated) - } - __Field::__field1 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "num_peers" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"num_peers" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Broadcasted", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Broadcasted with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Broadcasted { - num_peers: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "num_peers", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("num_peers")? - } - }; - _serde::__private::Ok(TransactionStatus::Broadcasted { - num_peers: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["num_peers"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field2 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "block" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"block" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::BestChainBlockIncluded", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Option>, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::BestChainBlockIncluded with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::BestChainBlockIncluded { - block: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option< - Option>, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("block"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option>, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("block")? - } - }; - _serde::__private::Ok(TransactionStatus::BestChainBlockIncluded { - block: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["block"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field3 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "block" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"block" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Finalized", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - TransactionBlockDetails, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Finalized with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Finalized { - block: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option< - TransactionBlockDetails, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("block"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - TransactionBlockDetails, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("block")? - } - }; - _serde::__private::Ok(TransactionStatus::Finalized { - block: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["block"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field4 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Error", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Error with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Error { - error: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(TransactionStatus::Error { - error: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["error"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field5 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Invalid", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Invalid with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Invalid { - error: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(TransactionStatus::Invalid { - error: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["error"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field6 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "broadcasted" => _serde::__private::Ok(__Field::__field0), - "error" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"broadcasted" => _serde::__private::Ok(__Field::__field0), - b"error" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Dropped", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - bool, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Dropped with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct variant TransactionStatus::Dropped with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Dropped { - broadcasted: __field0, - error: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "broadcasted", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("broadcasted")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(TransactionStatus::Dropped { - broadcasted: __field0, - error: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "broadcasted", - "error", - ]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - } - } - }; - /// Details of a block that a transaction is seen in. - pub struct TransactionBlockDetails { - /// The block hash. - pub hash: Hash, - /// The index of the transaction in the block. - #[serde(with = "unsigned_number_as_string")] - pub index: u64, - } - #[automatically_derived] - impl ::core::fmt::Debug - for TransactionBlockDetails { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "TransactionBlockDetails", - "hash", - &self.hash, - "index", - &&self.index, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for TransactionBlockDetails { - #[inline] - fn clone(&self) -> TransactionBlockDetails { - TransactionBlockDetails { - hash: ::core::clone::Clone::clone(&self.hash), - index: ::core::clone::Clone::clone(&self.index), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for TransactionBlockDetails {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for TransactionBlockDetails { - #[inline] - fn eq(&self, other: &TransactionBlockDetails) -> bool { - self.hash == other.hash && self.index == other.index - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for TransactionBlockDetails { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> - for TransactionBlockDetails - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "hash" => _serde::__private::Ok(__Field::__field0), - "index" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"hash" => _serde::__private::Ok(__Field::__field0), - b"index" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionBlockDetails, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionBlockDetails; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct TransactionBlockDetails", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct TransactionBlockDetails with 2 elements", - ), - ); - } - }; - let __field1 = match { - #[doc(hidden)] - struct __DeserializeWith<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - value: u64, - phantom: _serde::__private::PhantomData< - TransactionBlockDetails, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::Deserialize<'de> - for __DeserializeWith<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: unsigned_number_as_string::deserialize( - __deserializer, - )?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de, Hash>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct TransactionBlockDetails with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(TransactionBlockDetails { - hash: __field0, - index: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("hash"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("index"), - ); - } - __field1 = _serde::__private::Some({ - #[doc(hidden)] - struct __DeserializeWith<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - value: u64, - phantom: _serde::__private::PhantomData< - TransactionBlockDetails, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::Deserialize<'de> - for __DeserializeWith<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: unsigned_number_as_string::deserialize( - __deserializer, - )?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - match _serde::de::MapAccess::next_value::< - __DeserializeWith<'de, Hash>, - >(&mut __map) { - _serde::__private::Ok(__wrapper) => __wrapper.value, - _serde::__private::Err(__err) => { - return _serde::__private::Err(__err); - } - } - }); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("hash")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::missing_field("index"), - ); - } - }; - _serde::__private::Ok(TransactionBlockDetails { - hash: __field0, - index: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["hash", "index"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "TransactionBlockDetails", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionBlockDetails, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Hex-serialized shim for `Vec`. - pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec); - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Bytes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Bytes { - #[inline] - fn eq(&self, other: &Bytes) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Bytes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Bytes { - #[inline] - fn clone(&self) -> Bytes { - Bytes(::core::clone::Clone::clone(&self.0)) - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Bytes { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "Bytes", - { - #[doc(hidden)] - struct __SerializeWith<'__a> { - values: (&'__a Vec,), - phantom: _serde::__private::PhantomData, - } - impl<'__a> _serde::Serialize for __SerializeWith<'__a> { - fn serialize<__S>( - &self, - __s: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - impl_serde::serialize::serialize(self.values.0, __s) - } - } - &__SerializeWith { - values: (&self.0,), - phantom: _serde::__private::PhantomData::, - } - }, - ) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Bytes { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Bytes; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "tuple struct Bytes", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: Vec = impl_serde::serialize::deserialize( - __e, - )?; - _serde::__private::Ok(Bytes(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match { - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: Vec, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: impl_serde::serialize::deserialize(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct Bytes with 1 element", - ), - ); - } - }; - _serde::__private::Ok(Bytes(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "Bytes", - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::hash::Hash for Bytes { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Bytes { - #[inline] - fn partial_cmp( - &self, - other: &Bytes, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Bytes { - #[inline] - fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Bytes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Bytes", - &&self.0, - ) - } - } - impl std::ops::Deref for Bytes { - type Target = [u8]; - fn deref(&self) -> &[u8] { - &self.0[..] - } - } - impl From> for Bytes { - fn from(s: Vec) -> Self { - Bytes(s) - } - } - fn to_hex(bytes: impl AsRef<[u8]>) -> String { - { - let res = ::alloc::fmt::format( - format_args!("0x{0}", hex::encode(bytes.as_ref())), - ); - res - } - } - /// Attempt to deserialize either a string or integer into an integer. - /// See - pub(crate) mod unsigned_number_as_string { - use serde::de::{Deserializer, Visitor}; - use std::fmt; - /// Deserialize a number from a string or number. - pub fn deserialize<'de, N: From, D>( - deserializer: D, - ) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_any(NumberVisitor(std::marker::PhantomData)) - } - struct NumberVisitor(std::marker::PhantomData); - impl<'de, N: From> Visitor<'de> for NumberVisitor { - type Value = N; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter - .write_str("an unsigned integer or a string containing one") - } - fn visit_str( - self, - v: &str, - ) -> Result { - let n: u64 = v.parse().map_err(serde::de::Error::custom)?; - Ok(n.into()) - } - fn visit_u64( - self, - v: u64, - ) -> Result { - Ok(v.into()) - } - } - } - /// A temporary shim to decode "spec.apis" if it comes back as an array like: - /// - /// ```text - /// [["0xABC", 1], ["0xCDE", 2]] - /// ``` - /// - /// The expected format (which this also supports deserializing from) is: - /// - /// ```text - /// { "0xABC": 1, "0xCDE": 2 } - /// ``` - /// - /// We can delete this when the correct format is being returned. - /// - /// Adapted from - pub(crate) mod hashmap_as_tuple_list { - use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; - use std::collections::HashMap; - use std::fmt; - use std::hash::{BuildHasher, Hash}; - use std::marker::PhantomData; - /// Deserialize a [`HashMap`] from a list of tuples or object - pub fn deserialize<'de, K, V, BH, D>( - deserializer: D, - ) -> Result, D::Error> - where - D: Deserializer<'de>, - K: Eq + Hash + Deserialize<'de>, - V: Deserialize<'de>, - BH: BuildHasher + Default, - { - deserializer.deserialize_any(HashMapVisitor(PhantomData)) - } - #[allow(clippy::type_complexity)] - struct HashMapVisitor(PhantomData HashMap>); - impl<'de, K, V, BH> Visitor<'de> for HashMapVisitor - where - K: Deserialize<'de> + Eq + Hash, - V: Deserialize<'de>, - BH: BuildHasher + Default, - { - type Value = HashMap; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a list of key-value pairs") - } - fn visit_map(self, mut m: A) -> Result - where - A: serde::de::MapAccess<'de>, - { - let mut map = HashMap::with_capacity_and_hasher( - m.size_hint().unwrap_or(0), - BH::default(), - ); - while let Some((key, value)) = m.next_entry()? { - map.insert(key, value); - } - Ok(map) - } - fn visit_seq(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - let mut map = HashMap::with_capacity_and_hasher( - seq.size_hint().unwrap_or(0), - BH::default(), - ); - while let Some((key, value)) = seq.next_element()? { - map.insert(key, value); - } - Ok(map) - } - } - } - } - use self::rpc_methods::{ - FollowEvent, MethodResponse, RuntimeEvent, StorageQuery, StorageQueryType, - StorageResultType, - }; - use crate::backend::{ - rpc::RpcClient, Backend, BlockRef, BlockRefT, RuntimeVersion, - StorageResponse, StreamOf, StreamOfResults, TransactionStatus, - }; - use crate::config::BlockHash; - use crate::error::{Error, RpcError}; - use crate::Config; - use async_trait::async_trait; - use follow_stream_driver::{FollowStreamDriver, FollowStreamDriverHandle}; - use futures::{Stream, StreamExt}; - use std::collections::HashMap; - use std::sync::Arc; - use std::task::Poll; - use storage_items::StorageItems; - pub use rpc_methods::UnstableRpcMethods; - /// Configure and build an [`UnstableBackend`]. - pub struct UnstableBackendBuilder { - max_block_life: usize, - _marker: std::marker::PhantomData, - } - impl Default for UnstableBackendBuilder { - fn default() -> Self { - Self::new() - } - } - impl UnstableBackendBuilder { - /// Create a new [`UnstableBackendBuilder`]. - pub fn new() -> Self { - Self { - max_block_life: usize::MAX, - _marker: std::marker::PhantomData, - } - } - /// The age of a block is defined here as the difference between the current finalized block number - /// and the block number of a given block. Once the difference equals or exceeds the number given - /// here, the block is unpinned. - /// - /// By default, we will never automatically unpin blocks, but if the number of pinned blocks that we - /// keep hold of exceeds the number that the server can tolerate, then a `stop` event is generated and - /// we are forced to resubscribe, losing any pinned blocks. - pub fn max_block_life(mut self, max_block_life: usize) -> Self { - self.max_block_life = max_block_life; - self - } - /// Given an [`RpcClient`] to use to make requests, this returns a tuple of an [`UnstableBackend`], - /// which implements the [`Backend`] trait, and an [`UnstableBackendDriver`] which must be polled in - /// order for the backend to make progress. - pub fn build( - self, - client: RpcClient, - ) -> (UnstableBackend, UnstableBackendDriver) { - let rpc_methods = UnstableRpcMethods::new(client); - let follow_stream = follow_stream::FollowStream::< - T::Hash, - >::from_methods(rpc_methods.clone()); - let follow_stream_unpin = follow_stream_unpin::FollowStreamUnpin::< - T::Hash, - >::from_methods(follow_stream, rpc_methods.clone(), self.max_block_life); - let follow_stream_driver = FollowStreamDriver::new(follow_stream_unpin); - let backend = UnstableBackend { - methods: rpc_methods, - follow_handle: follow_stream_driver.handle(), - }; - let driver = UnstableBackendDriver { - driver: follow_stream_driver, - }; - (backend, driver) - } - } - /// Driver for the [`UnstableBackend`]. This must be polled in order for the - /// backend to make progress. - pub struct UnstableBackendDriver { - driver: FollowStreamDriver, - } - #[automatically_derived] - impl ::core::fmt::Debug - for UnstableBackendDriver - where - T::Hash: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "UnstableBackendDriver", - "driver", - &&self.driver, - ) - } - } - impl Stream for UnstableBackendDriver { - type Item = as Stream>::Item; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - self.driver.poll_next_unpin(cx) - } - } - /// The unstable backend. - pub struct UnstableBackend { - methods: UnstableRpcMethods, - follow_handle: FollowStreamDriverHandle, - } - #[automatically_derived] - impl ::core::fmt::Debug for UnstableBackend - where - T::Hash: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "UnstableBackend", - "methods", - &self.methods, - "follow_handle", - &&self.follow_handle, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for UnstableBackend - where - T::Hash: ::core::clone::Clone, - { - #[inline] - fn clone(&self) -> UnstableBackend { - UnstableBackend { - methods: ::core::clone::Clone::clone(&self.methods), - follow_handle: ::core::clone::Clone::clone(&self.follow_handle), - } - } - } - impl UnstableBackend { - /// Configure and construct an [`UnstableBackend`] and the associated [`UnstableBackendDriver`]. - pub fn builder() -> UnstableBackendBuilder { - UnstableBackendBuilder::new() - } - /// Stream block headers based on the provided filter fn - async fn stream_headers( - &self, - f: F, - ) -> Result)>, Error> - where - F: Fn(FollowEvent>) -> I + Copy - + Send + 'static, - I: IntoIterator> + Send - + 'static, - ::IntoIter: Send, - { - let sub_id = get_subscription_id(&self.follow_handle).await?; - let sub_id = Arc::new(sub_id); - let methods = self.methods.clone(); - let headers = self - .follow_handle - .subscribe() - .events() - .flat_map(move |ev| { - let sub_id = sub_id.clone(); - let methods = methods.clone(); - let block_refs = f(ev).into_iter(); - futures::stream::iter(block_refs) - .filter_map(move |block_ref| { - let sub_id = sub_id.clone(); - let methods = methods.clone(); - async move { - let res = methods - .chainhead_unstable_header(&sub_id, block_ref.hash()) - .await - .transpose()?; - let header = match res { - Ok(header) => header, - Err(e) => return Some(Err(e)), - }; - Some(Ok((header, block_ref.into()))) - } - }) - }); - Ok(StreamOf(Box::pin(headers))) - } - } - impl BlockRefT - for follow_stream_unpin::BlockRef {} - impl From> - for BlockRef { - fn from(b: follow_stream_unpin::BlockRef) -> Self { - BlockRef::new(b.hash(), b) - } - } - impl super::sealed::Sealed for UnstableBackend {} - impl Backend for UnstableBackend { - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_values<'life0, 'async_trait>( - &'life0 self, - keys: Vec>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let keys = keys; - let at = at; - let __ret: Result, Error> = { - let queries = keys - .iter() - .map(|key| StorageQuery { - key: &**key, - query_type: StorageQueryType::Value, - }); - let storage_items = StorageItems::from_methods( - queries, - at, - &__self.follow_handle, - __self.methods.clone(), - ) - .await?; - let storage_result_stream = storage_items - .filter_map(|val| async move { - let val = match val { - Ok(val) => val, - Err(e) => return Some(Err(e)), - }; - let StorageResultType::Value(result) = val.result else { - return None; - }; - Some( - Ok(StorageResponse { - key: val.key.0, - value: result.0, - }), - ) - }); - Ok(StreamOf(Box::pin(storage_result_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_descendant_keys<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>, Error>, - > { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result>, Error> = { - let query = StorageQuery { - key: &*key, - query_type: StorageQueryType::DescendantsHashes, - }; - let storage_items = StorageItems::from_methods( - std::iter::once(query), - at, - &__self.follow_handle, - __self.methods.clone(), - ) - .await?; - let storage_result_stream = storage_items - .map(|val| val.map(|v| v.key.0)); - Ok(StreamOf(Box::pin(storage_result_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_descendant_values<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result, Error> = { - let query = StorageQuery { - key: &*key, - query_type: StorageQueryType::DescendantsValues, - }; - let storage_items = StorageItems::from_methods( - std::iter::once(query), - at, - &__self.follow_handle, - __self.methods.clone(), - ) - .await?; - let storage_result_stream = storage_items - .filter_map(|val| async move { - let val = match val { - Ok(val) => val, - Err(e) => return Some(Err(e)), - }; - let StorageResultType::Value(result) = val.result else { - return None; - }; - Some( - Ok(StorageResponse { - key: val.key.0, - value: result.0, - }), - ) - }); - Ok(StreamOf(Box::pin(storage_result_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn genesis_hash<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let __ret: Result = { - __self.methods.chainspec_v1_genesis_hash().await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn block_header<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result, Error> = { - let sub_id = get_subscription_id(&__self.follow_handle).await?; - __self.methods.chainhead_unstable_header(&sub_id, at).await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn block_body<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>>, Error>, - > { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result>>, Error> = { - let sub_id = get_subscription_id(&__self.follow_handle).await?; - let follow_events = __self.follow_handle.subscribe().events(); - let status = __self - .methods - .chainhead_unstable_body(&sub_id, at) - .await?; - let operation_id = match status { - MethodResponse::LimitReached => { - return Err( - RpcError::request_rejected("limit reached").into(), - ); - } - MethodResponse::Started(s) => s.operation_id, - }; - let mut exts_stream = follow_events - .filter_map(|ev| { - let FollowEvent::OperationBodyDone(body) = ev else { - return std::future::ready(None); - }; - if body.operation_id != operation_id { - return std::future::ready(None); - } - let exts: Vec<_> = body - .value - .into_iter() - .map(|ext| ext.0) - .collect(); - std::future::ready(Some(exts)) - }); - Ok(exts_stream.next().await) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn latest_finalized_block_ref<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result, Error> = { - let next_ref: Option> = __self - .follow_handle - .subscribe() - .events() - .filter_map(|ev| { - let out = match ev { - FollowEvent::Initialized(init) => { - Some(init.finalized_block_hash.into()) - } - _ => None, - }; - std::future::ready(out) - }) - .next() - .await; - next_ref.ok_or_else(|| RpcError::SubscriptionDropped.into()) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn current_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let __ret: Result = { - let runtime_version = __self - .stream_runtime_version() - .await? - .next() - .await; - match runtime_version { - None => Err(Error::Rpc(RpcError::SubscriptionDropped)), - Some(Err(e)) => Err(e), - Some(Ok(version)) => Ok(version), - } - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result, Error> = { - let mut runtimes = HashMap::new(); - let runtime_stream = __self - .follow_handle - .subscribe() - .events() - .filter_map(move |ev| { - let output = match ev { - FollowEvent::Initialized(ev) => { - runtimes.remove(&ev.finalized_block_hash.hash()); - ev.finalized_block_runtime - } - FollowEvent::NewBlock(ev) => { - if let Some(runtime) = ev.new_runtime { - runtimes.insert(ev.block_hash.hash(), runtime); - } - None - } - FollowEvent::Finalized(ev) => { - let next_runtime = { - let mut it = ev - .finalized_block_hashes - .iter() - .rev() - .filter_map(|h| runtimes.get(&h.hash()).cloned()) - .peekable(); - let next = it.next(); - if it.peek().is_some() { - { - use ::tracing::__macro_support::Callsite as _; - static __CALLSITE: ::tracing::callsite::DefaultCallsite = { - static META: ::tracing::Metadata<'static> = { - ::tracing_core::metadata::Metadata::new( - "event subxt/src/backend/unstable/mod.rs:377", - "subxt", - ::tracing::Level::WARN, - ::core::option::Option::Some( - "subxt/src/backend/unstable/mod.rs", - ), - ::core::option::Option::Some(377u32), - ::core::option::Option::Some("subxt::backend::unstable"), - ::tracing_core::field::FieldSet::new( - &["message"], - ::tracing_core::callsite::Identifier(&__CALLSITE), - ), - ::tracing::metadata::Kind::EVENT, - ) - }; - ::tracing::callsite::DefaultCallsite::new(&META) - }; - let enabled = ::tracing::Level::WARN - <= ::tracing::level_filters::STATIC_MAX_LEVEL - && ::tracing::Level::WARN - <= ::tracing::level_filters::LevelFilter::current() - && { - let interest = __CALLSITE.interest(); - !interest.is_never() - && ::tracing::__macro_support::__is_enabled( - __CALLSITE.metadata(), - interest, - ) - }; - if enabled { - (|value_set: ::tracing::field::ValueSet| { - let meta = __CALLSITE.metadata(); - ::tracing::Event::dispatch(meta, &value_set); - })({ - #[allow(unused_imports)] - use ::tracing::field::{debug, display, Value}; - let mut iter = __CALLSITE.metadata().fields().iter(); - __CALLSITE - .metadata() - .fields() - .value_set( - &[ - ( - &::core::iter::Iterator::next(&mut iter) - .expect("FieldSet corrupted (this is a bug)"), - ::core::option::Option::Some( - &format_args!( - "Several runtime upgrades in the finalized blocks but only the latest runtime upgrade is returned" - ) as &dyn Value, - ), - ), - ], - ) - }); - } else { - } - }; - } - next - }; - for block in ev - .finalized_block_hashes - .iter() - .chain(ev.pruned_block_hashes.iter()) - { - runtimes.remove(&block.hash()); - } - next_runtime - } - _ => None, - }; - let runtime_event = match output { - None => return std::future::ready(None), - Some(ev) => ev, - }; - let runtime_details = match runtime_event { - RuntimeEvent::Invalid(err) => { - return std::future::ready( - Some(Err(Error::Other(err.error))), - ); - } - RuntimeEvent::Valid(ev) => ev, - }; - std::future::ready( - Some( - Ok(RuntimeVersion { - spec_version: runtime_details.spec.spec_version, - transaction_version: runtime_details - .spec - .transaction_version, - }), - ), - ) - }); - Ok(StreamOf(Box::pin(runtime_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_all_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - __self - .stream_headers(|ev| match ev { - FollowEvent::Initialized(ev) => { - Some(ev.finalized_block_hash) - } - FollowEvent::NewBlock(ev) => Some(ev.block_hash), - _ => None, - }) - .await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_best_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - __self - .stream_headers(|ev| match ev { - FollowEvent::Initialized(ev) => { - Some(ev.finalized_block_hash) - } - FollowEvent::BestBlockChanged(ev) => { - Some(ev.best_block_hash) - } - _ => None, - }) - .await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_finalized_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - __self - .stream_headers(|ev| match ev { - FollowEvent::Initialized(ev) => { - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ev.finalized_block_hash]), - ) - } - FollowEvent::Finalized(ev) => ev.finalized_block_hashes, - _ => ::alloc::vec::Vec::new(), - }) - .await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn submit_transaction<'life0, 'life1, 'async_trait>( - &'life0 self, - extrinsic: &'life1 [u8], - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults>, - Error, - > = { - enum SeenBlockMarker { - New, - Finalized, - } - let mut seen_blocks_sub = __self - .follow_handle - .subscribe() - .events(); - let mut tx_progress = __self - .methods - .transaction_unstable_submit_and_watch(extrinsic) - .await?; - let mut seen_blocks = HashMap::new(); - let mut done = false; - let mut finalized_hash: Option = None; - let start_instant = instant::Instant::now(); - let err_other = |s: &str| Some(Err(Error::Other(s.into()))); - let tx_stream = futures::stream::poll_fn(move |cx| { - loop { - if done { - return Poll::Ready(None); - } - if start_instant.elapsed().as_secs() > 240 { - return Poll::Ready( - err_other( - "Timeout waiting for the transaction to be finalized", - ), - ); - } - let follow_ev_poll = match seen_blocks_sub - .poll_next_unpin(cx) - { - Poll::Ready(None) => { - return Poll::Ready( - err_other("chainHead_follow stream ended unexpectedly"), - ); - } - Poll::Ready(Some(follow_ev)) => Poll::Ready(follow_ev), - Poll::Pending => Poll::Pending, - }; - let follow_ev_is_pending = follow_ev_poll.is_pending(); - if let Poll::Ready(follow_ev) = follow_ev_poll { - match follow_ev { - FollowEvent::NewBlock(ev) => { - if finalized_hash.is_none() { - seen_blocks - .insert( - ev.block_hash.hash(), - (SeenBlockMarker::New, ev.block_hash), - ); - } - } - FollowEvent::Finalized(ev) => { - for block_ref in ev.finalized_block_hashes { - seen_blocks - .insert( - block_ref.hash(), - (SeenBlockMarker::Finalized, block_ref), - ); - } - } - FollowEvent::Stop => { - return Poll::Ready( - err_other( - "chainHead_follow emitted 'stop' event during transaction submission", - ), - ); - } - _ => {} - } - continue; - } - if let Some(hash) = &finalized_hash { - if let Some((SeenBlockMarker::Finalized, block_ref)) - = seen_blocks.remove(hash) - { - done = true; - let ev = TransactionStatus::InFinalizedBlock { - hash: block_ref.into(), - }; - return Poll::Ready(Some(Ok(ev))); - } else { - seen_blocks.clear(); - if follow_ev_is_pending { - return Poll::Pending; - } else { - continue; - } - } - } - let tx_progress_ev = match tx_progress.poll_next_unpin(cx) { - Poll::Pending => return Poll::Pending, - Poll::Ready(None) => { - return Poll::Ready( - err_other( - "No more transaction progress events, but we haven't seen a Finalized one yet", - ), - ); - } - Poll::Ready(Some(Err(e))) => { - return Poll::Ready(Some(Err(e))); - } - Poll::Ready(Some(Ok(ev))) => ev, - }; - let tx_progress_ev = match tx_progress_ev { - rpc_methods::TransactionStatus::Finalized { block } => { - finalized_hash = Some(block.hash); - continue; - } - rpc_methods::TransactionStatus::BestChainBlockIncluded { - block: Some(block), - } => { - let block_ref = match seen_blocks.get(&block.hash) { - Some((_, block_ref)) => block_ref.clone().into(), - None => BlockRef::from_hash(block.hash), - }; - TransactionStatus::InBestBlock { - hash: block_ref, - } - } - rpc_methods::TransactionStatus::BestChainBlockIncluded { - block: None, - } => TransactionStatus::NoLongerInBestBlock, - rpc_methods::TransactionStatus::Broadcasted { - num_peers, - } => { - TransactionStatus::Broadcasted { - num_peers, - } - } - rpc_methods::TransactionStatus::Dropped { error, .. } => { - TransactionStatus::Dropped { - message: error, - } - } - rpc_methods::TransactionStatus::Error { error } => { - TransactionStatus::Dropped { - message: error, - } - } - rpc_methods::TransactionStatus::Invalid { error } => { - TransactionStatus::Invalid { - message: error, - } - } - rpc_methods::TransactionStatus::Validated => { - TransactionStatus::Validated - } - }; - return Poll::Ready(Some(Ok(tx_progress_ev))); - } - }); - Ok(StreamOf(Box::pin(tx_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn call<'life0, 'life1, 'life2, 'async_trait>( - &'life0 self, - method: &'life1 str, - call_parameters: Option<&'life2 [u8]>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - 'life2: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::, Error>> { - return __ret; - } - let __self = self; - let call_parameters = call_parameters; - let at = at; - let __ret: Result, Error> = { - let sub_id = get_subscription_id(&__self.follow_handle).await?; - let follow_events = __self.follow_handle.subscribe().events(); - let call_parameters = call_parameters.unwrap_or(&[]); - let status = __self - .methods - .chainhead_unstable_call( - &sub_id, - at, - method, - call_parameters, - ) - .await?; - let operation_id = match status { - MethodResponse::LimitReached => { - return Err( - RpcError::request_rejected("limit reached").into(), - ); - } - MethodResponse::Started(s) => s.operation_id, - }; - let mut call_data_stream = follow_events - .filter_map(|ev| { - let FollowEvent::OperationCallDone(body) = ev else { - return std::future::ready(None); - }; - if body.operation_id != operation_id { - return std::future::ready(None); - } - std::future::ready(Some(body.output.0)) - }); - call_data_stream - .next() - .await - .ok_or_else(|| RpcError::SubscriptionDropped.into()) - }; - #[allow(unreachable_code)] __ret - }) - } - } - /// A helper to obtain a subscription ID. - async fn get_subscription_id( - follow_handle: &FollowStreamDriverHandle, - ) -> Result { - let Some(sub_id) = follow_handle.subscribe().subscription_id().await else { - return Err(RpcError::SubscriptionDropped.into()); - }; - Ok(sub_id) - } - } - use crate::error::Error; - use crate::metadata::Metadata; - use crate::Config; - use async_trait::async_trait; - use codec::{Decode, Encode}; - use futures::{Stream, StreamExt}; - use std::pin::Pin; - use std::sync::Arc; - /// Prevent the backend trait being implemented externally. - #[doc(hidden)] - pub(crate) mod sealed { - pub trait Sealed {} - } - /// This trait exposes the interface that Subxt will use to communicate with - /// a backend. Its goal is to be as minimal as possible. - pub trait Backend: sealed::Sealed + Send + Sync + 'static { - /// Fetch values from storage. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn storage_fetch_values<'life0, 'async_trait>( - &'life0 self, - keys: Vec>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Fetch keys underneath the given key from storage. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn storage_fetch_descendant_keys<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Fetch values underneath the given key from storage. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn storage_fetch_descendant_values<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Fetch the genesis hash - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn genesis_hash<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Get a block header - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn block_header<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Return the extrinsics found in the block. Each extrinsic is represented - /// by a vector of bytes which has _not_ been SCALE decoded (in other words, the - /// first bytes in the vector will decode to the compact encoded length of the extrinsic) - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn block_body<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Get the most recent finalized block hash. - /// Note: needed only in blocks client for finalized block stream; can prolly be removed. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn latest_finalized_block_ref<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Get information about the current runtime. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn current_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// A stream of all new runtime versions as they occur. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn stream_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// A stream of all new block headers as they arrive. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn stream_all_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// A stream of best block headers. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn stream_best_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// A stream of finalized block headers. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn stream_finalized_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Submit a transaction. This will return a stream of events about it. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn submit_transaction<'life0, 'life1, 'async_trait>( - &'life0 self, - bytes: &'life1 [u8], - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - Self: 'async_trait; - /// Make a call to some runtime API. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn call<'life0, 'life1, 'life2, 'async_trait>( - &'life0 self, - method: &'life1 str, - call_parameters: Option<&'life2 [u8]>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - 'life2: 'async_trait, - Self: 'async_trait; - } - /// helpeful utility methods derived from those provided on [`Backend`] - pub trait BackendExt: Backend { - /// Fetch a single value from storage. - #[must_use] - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_value<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: ::core::marker::Sync + 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::>, Error>> { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result>, Error> = { - __self - .storage_fetch_values( - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([key]), - ), - at, - ) - .await? - .next() - .await - .transpose() - .map(|o| o.map(|s| s.value)) - }; - #[allow(unreachable_code)] __ret - }) - } - /// The same as a [`Backend::call()`], but it will also attempt to decode the - /// result into the given type, which is a fairly common operation. - #[must_use] - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn call_decoding<'life0, 'life1, 'life2, 'async_trait, D>( - &'life0 self, - method: &'life1 str, - call_parameters: Option<&'life2 [u8]>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - D: 'async_trait + codec::Decode, - 'life0: 'async_trait, - 'life1: 'async_trait, - 'life2: 'async_trait, - Self: ::core::marker::Sync + 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let call_parameters = call_parameters; - let at = at; - let __ret: Result = { - let bytes = __self.call(method, call_parameters, at).await?; - let res = D::decode(&mut &*bytes)?; - Ok(res) - }; - #[allow(unreachable_code)] __ret - }) - } - /// Return the metadata at some version. - #[must_use] - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn metadata_at_version<'life0, 'async_trait>( - &'life0 self, - version: u32, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: ::core::marker::Sync + 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let version = version; - let at = at; - let __ret: Result = { - let param = version.encode(); - let opaque: Option = __self - .call_decoding("Metadata_metadata_at_version", Some(¶m), at) - .await?; - let Some(opaque) = opaque else { - return Err(Error::Other("Metadata version not found".into())); - }; - let metadata: Metadata = Decode::decode(&mut &opaque.0[..])?; - Ok(metadata) - }; - #[allow(unreachable_code)] __ret - }) - } - /// Return V14 metadata from the legacy `Metadata_metadata` call. - #[must_use] - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn legacy_metadata<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: ::core::marker::Sync + 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result = { - let opaque: frame_metadata::OpaqueMetadata = __self - .call_decoding("Metadata_metadata", None, at) - .await?; - let metadata: Metadata = Decode::decode(&mut &opaque.0[..])?; - Ok(metadata) - }; - #[allow(unreachable_code)] __ret - }) - } - } - impl + ?Sized, T: Config> BackendExt for B {} - /// An opaque struct which, while alive, indicates that some references to a block - /// still exist. This gives the backend the opportunity to keep the corresponding block - /// details around for a while if it likes and is able to. No guarantees can be made about - /// how long the corresponding details might be available for, but if no references to a block - /// exist, then the backend is free to discard any details for it. - pub struct BlockRef { - hash: H, - _pointer: Option>, - } - #[automatically_derived] - impl ::core::clone::Clone for BlockRef { - #[inline] - fn clone(&self) -> BlockRef { - BlockRef { - hash: ::core::clone::Clone::clone(&self.hash), - _pointer: ::core::clone::Clone::clone(&self._pointer), - } - } - } - impl From for BlockRef { - fn from(value: H) -> Self { - BlockRef::from_hash(value) - } - } - impl PartialEq for BlockRef { - fn eq(&self, other: &Self) -> bool { - self.hash == other.hash - } - } - impl Eq for BlockRef {} - impl PartialOrd for BlockRef { - fn partial_cmp(&self, other: &Self) -> Option { - self.hash.partial_cmp(&other.hash) - } - } - impl Ord for BlockRef { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.hash.cmp(&other.hash) - } - } - impl std::fmt::Debug for BlockRef { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("BlockRef").field(&self.hash).finish() - } - } - impl std::hash::Hash for BlockRef { - fn hash(&self, state: &mut Hasher) { - self.hash.hash(state); - } - } - impl BlockRef { - /// A [`BlockRef`] that doesn't reference a given block, but does have an associated hash. - /// This is used in the legacy backend, which has no notion of pinning blocks. - pub fn from_hash(hash: H) -> Self { - Self { hash, _pointer: None } - } - /// Construct a [`BlockRef`] from an instance of the underlying trait. It's expected - /// that the [`Backend`] implementation will call this if it wants to track which blocks - /// are potentially in use. - pub fn new(hash: H, inner: P) -> Self { - Self { - hash, - _pointer: Some(Arc::new(inner)), - } - } - /// Return the hash of the referenced block. - pub fn hash(&self) -> H - where - H: Copy, - { - self.hash - } - } - /// A trait that a [`Backend`] can implement to know when some block - /// can be unpinned: when this is dropped, there are no remaining references - /// to the block that it's associated with. - pub trait BlockRefT: Send + Sync + 'static {} - /// A stream of some item. - pub struct StreamOf(Pin + Send + 'static>>); - impl Stream for StreamOf { - type Item = T; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - self.0.poll_next_unpin(cx) - } - } - impl std::fmt::Debug for StreamOf { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("StreamOf").field(&"").finish() - } - } - impl StreamOf { - /// Construct a new stream. - pub fn new(inner: Pin + Send + 'static>>) -> Self { - StreamOf(inner) - } - /// Returns the next item in the stream. This is just a wrapper around - /// [`StreamExt::next()`] so that you can avoid the extra import. - pub async fn next(&mut self) -> Option { - StreamExt::next(self).await - } - } - /// A stream of [`Result`]. - pub type StreamOfResults = StreamOf>; - /// Runtime version information needed to submit transactions. - pub struct RuntimeVersion { - /// Version of the runtime specification. A full-node will not attempt to use its native - /// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, - /// `spec_version` and `authoring_version` are the same between Wasm and native. - pub spec_version: u32, - /// All existing dispatches are fully compatible when this number doesn't change. If this - /// number changes, then `spec_version` must change, also. - /// - /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, - /// either through an alteration in its user-level semantics, a parameter - /// added/removed/changed, a dispatchable being removed, a module being removed, or a - /// dispatchable/module changing its index. - /// - /// It need *not* change when a new module is added or when a dispatchable is added. - pub transaction_version: u32, - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeVersion { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "RuntimeVersion", - "spec_version", - &self.spec_version, - "transaction_version", - &&self.transaction_version, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeVersion { - #[inline] - fn clone(&self) -> RuntimeVersion { - RuntimeVersion { - spec_version: ::core::clone::Clone::clone(&self.spec_version), - transaction_version: ::core::clone::Clone::clone( - &self.transaction_version, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeVersion {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeVersion { - #[inline] - fn eq(&self, other: &RuntimeVersion) -> bool { - self.spec_version == other.spec_version - && self.transaction_version == other.transaction_version - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeVersion { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - /// The status of the transaction. - /// - /// If the status is [`TransactionStatus::InFinalizedBlock`], [`TransactionStatus::Error`], - /// [`TransactionStatus::Invalid`] or [`TransactionStatus::Dropped`], then no future - /// events will be emitted. - pub enum TransactionStatus { - /// Transaction is part of the future queue. - Validated, - /// The transaction has been broadcast to other nodes. - Broadcasted { - /// Number of peers it's been broadcast to. - num_peers: u32, - }, - /// Transaction is no longer in a best block. - NoLongerInBestBlock, - /// Transaction has been included in block with given hash. - InBestBlock { - /// Block hash the transaction is in. - hash: BlockRef, - }, - /// Transaction has been finalized by a finality-gadget, e.g GRANDPA - InFinalizedBlock { - /// Block hash the transaction is in. - hash: BlockRef, - }, - /// Something went wrong in the node. - Error { - /// Human readable message; what went wrong. - message: String, - }, - /// Transaction is invalid (bad nonce, signature etc). - Invalid { - /// Human readable message; why was it invalid. - message: String, - }, - /// The transaction was dropped. - Dropped { - /// Human readable message; why was it dropped. - message: String, - }, - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionStatus { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionStatus::Validated => { - ::core::fmt::Formatter::write_str(f, "Validated") - } - TransactionStatus::Broadcasted { num_peers: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Broadcasted", - "num_peers", - &__self_0, - ) - } - TransactionStatus::NoLongerInBestBlock => { - ::core::fmt::Formatter::write_str(f, "NoLongerInBestBlock") - } - TransactionStatus::InBestBlock { hash: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "InBestBlock", - "hash", - &__self_0, - ) - } - TransactionStatus::InFinalizedBlock { hash: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "InFinalizedBlock", - "hash", - &__self_0, - ) - } - TransactionStatus::Error { message: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Error", - "message", - &__self_0, - ) - } - TransactionStatus::Invalid { message: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Invalid", - "message", - &__self_0, - ) - } - TransactionStatus::Dropped { message: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Dropped", - "message", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for TransactionStatus { - #[inline] - fn clone(&self) -> TransactionStatus { - match self { - TransactionStatus::Validated => TransactionStatus::Validated, - TransactionStatus::Broadcasted { num_peers: __self_0 } => { - TransactionStatus::Broadcasted { - num_peers: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::NoLongerInBestBlock => { - TransactionStatus::NoLongerInBestBlock - } - TransactionStatus::InBestBlock { hash: __self_0 } => { - TransactionStatus::InBestBlock { - hash: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::InFinalizedBlock { hash: __self_0 } => { - TransactionStatus::InFinalizedBlock { - hash: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Error { message: __self_0 } => { - TransactionStatus::Error { - message: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Invalid { message: __self_0 } => { - TransactionStatus::Invalid { - message: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Dropped { message: __self_0 } => { - TransactionStatus::Dropped { - message: ::core::clone::Clone::clone(__self_0), - } - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionStatus {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for TransactionStatus { - #[inline] - fn eq(&self, other: &TransactionStatus) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionStatus::Broadcasted { num_peers: __self_0 }, - TransactionStatus::Broadcasted { num_peers: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::InBestBlock { hash: __self_0 }, - TransactionStatus::InBestBlock { hash: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::InFinalizedBlock { hash: __self_0 }, - TransactionStatus::InFinalizedBlock { hash: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Error { message: __self_0 }, - TransactionStatus::Error { message: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Invalid { message: __self_0 }, - TransactionStatus::Invalid { message: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Dropped { message: __self_0 }, - TransactionStatus::Dropped { message: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TransactionStatus { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - } - } - /// A response from calls like [`Backend::storage_fetch_values`] or - /// [`Backend::storage_fetch_descendant_values`]. - pub struct StorageResponse { - /// The key. - pub key: Vec, - /// The associated value. - pub value: Vec, - } -} -pub mod blocks { - //! This module exposes the necessary functionality for working with events. - mod block_types { - use crate::{ - backend::BlockRef, - blocks::{extrinsic_types::ExtrinsicPartTypeIds, Extrinsics}, - client::{OfflineClientT, OnlineClientT}, - config::{Config, Header}, - error::{BlockError, DecodeError, Error}, - events, runtime_api::RuntimeApi, storage::Storage, - }; - use codec::{Decode, Encode}; - use futures::lock::Mutex as AsyncMutex; - use std::sync::Arc; - /// A representation of a block. - pub struct Block { - header: T::Header, - block_ref: BlockRef, - client: C, - cached_events: CachedEvents, - } - pub(crate) type CachedEvents = Arc>>>; - impl Block - where - T: Config, - C: OfflineClientT, - { - pub(crate) fn new( - header: T::Header, - block_ref: BlockRef, - client: C, - ) -> Self { - Block { - header, - block_ref, - client, - cached_events: Default::default(), - } - } - /// Return a reference to the given block. While this reference is kept alive, - /// the backend will (if possible) endeavour to keep hold of the block. - pub fn reference(&self) -> BlockRef { - self.block_ref.clone() - } - /// Return the block hash. - pub fn hash(&self) -> T::Hash { - self.block_ref.hash() - } - /// Return the block number. - pub fn number(&self) -> ::Number { - self.header().number() - } - /// Return the entire block header. - pub fn header(&self) -> &T::Header { - &self.header - } - } - impl Block - where - T: Config, - C: OnlineClientT, - { - /// Return the events associated with the block, fetching them from the node if necessary. - pub async fn events(&self) -> Result, Error> { - get_events(&self.client, self.header.hash(), &self.cached_events).await - } - /// Fetch and return the extrinsics in the block body. - pub async fn extrinsics(&self) -> Result, Error> { - let ids = ExtrinsicPartTypeIds::new(&self.client.metadata())?; - let block_hash = self.header.hash(); - let Some(extrinsics) = self - .client - .backend() - .block_body(block_hash) - .await? else { return Err(BlockError::not_found(block_hash).into()); - }; - Ok( - Extrinsics::new( - self.client.clone(), - extrinsics, - self.cached_events.clone(), - ids, - block_hash, - ), - ) - } - /// Work with storage. - pub fn storage(&self) -> Storage { - Storage::new(self.client.clone(), self.block_ref.clone()) - } - /// Execute a runtime API call at this block. - pub async fn runtime_api(&self) -> Result, Error> { - Ok(RuntimeApi::new(self.client.clone(), self.block_ref.clone())) - } - /// Get the account nonce for a given account ID at this block. - pub async fn account_nonce( - &self, - account_id: &T::AccountId, - ) -> Result { - get_account_nonce(&self.client, account_id, self.hash()).await - } - } - pub(crate) async fn get_events( - client: &C, - block_hash: T::Hash, - cached_events: &AsyncMutex>>, - ) -> Result, Error> - where - T: Config, - C: OnlineClientT, - { - let mut lock = cached_events.lock().await; - let events = match &*lock { - Some(events) => events.clone(), - None => { - let events = events::EventsClient::new(client.clone()) - .at(block_hash) - .await?; - lock.replace(events.clone()); - events - } - }; - Ok(events) - } - pub(crate) async fn get_account_nonce( - client: &C, - account_id: &T::AccountId, - block_hash: T::Hash, - ) -> Result - where - C: OnlineClientT, - T: Config, - { - let account_nonce_bytes = client - .backend() - .call( - "AccountNonceApi_account_nonce", - Some(&account_id.encode()), - block_hash, - ) - .await?; - let cursor = &mut &account_nonce_bytes[..]; - let account_nonce: u64 = match account_nonce_bytes.len() { - 2 => u16::decode(cursor)?.into(), - 4 => u32::decode(cursor)?.into(), - 8 => u64::decode(cursor)?, - _ => { - return Err( - Error::Decode( - DecodeError::custom_string({ - let res = ::alloc::fmt::format( - format_args!( - "state call AccountNonceApi_account_nonce returned an unexpected number of bytes: {0} (expected 2, 4 or 8)", - account_nonce_bytes.len() - ), - ); - res - }), - ), - ); - } - }; - Ok(account_nonce) - } - } - mod blocks_client { - use super::Block; - use crate::{ - backend::{BlockRef, StreamOfResults}, - client::OnlineClientT, config::Config, error::{BlockError, Error}, - utils::PhantomDataSendSync, - }; - use derivative::Derivative; - use futures::StreamExt; - use std::future::Future; - type BlockStream = StreamOfResults; - type BlockStreamRes = Result, Error>; - /// A client for working with blocks. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct BlocksClient { - client: Client, - _marker: PhantomDataSendSync, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for BlocksClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - BlocksClient { client: ref __arg_0, _marker: ref __arg_1 } => { - BlocksClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl BlocksClient { - /// Create a new [`BlocksClient`]. - pub fn new(client: Client) -> Self { - Self { - client, - _marker: PhantomDataSendSync::new(), - } - } - } - impl BlocksClient - where - T: Config, - Client: OnlineClientT, - { - /// Obtain block details given the provided block hash. - /// - /// # Warning - /// - /// This call only supports blocks produced since the most recent - /// runtime upgrade. You can attempt to retrieve older blocks, - /// but may run into errors attempting to work with them. - pub fn at( - &self, - block_ref: impl Into>, - ) -> impl Future, Error>> + Send + 'static { - self.at_or_latest(Some(block_ref.into())) - } - /// Obtain block details of the latest block hash. - pub fn at_latest( - &self, - ) -> impl Future, Error>> + Send + 'static { - self.at_or_latest(None) - } - /// Obtain block details given the provided block hash, or the latest block if `None` is - /// provided. - fn at_or_latest( - &self, - block_ref: Option>, - ) -> impl Future, Error>> + Send + 'static { - let client = self.client.clone(); - async move { - let block_ref = match block_ref { - Some(r) => r, - None => client.backend().latest_finalized_block_ref().await?, - }; - let block_header = match client - .backend() - .block_header(block_ref.hash()) - .await? - { - Some(header) => header, - None => { - return Err(BlockError::not_found(block_ref.hash()).into()); - } - }; - Ok(Block::new(block_header, block_ref, client)) - } - } - /// Subscribe to all new blocks imported by the node. - /// - /// **Note:** You probably want to use [`Self::subscribe_finalized()`] most of - /// the time. - pub fn subscribe_all( - &self, - ) -> impl Future< - Output = Result>, Error>, - > + Send + 'static - where - Client: Send + Sync + 'static, - { - let client = self.client.clone(); - header_sub_fut_to_block_sub( - self.clone(), - async move { - let sub = client.backend().stream_all_block_headers().await?; - BlockStreamRes::Ok(sub) - }, - ) - } - /// Subscribe to all new blocks imported by the node onto the current best fork. - /// - /// **Note:** You probably want to use [`Self::subscribe_finalized()`] most of - /// the time. - pub fn subscribe_best( - &self, - ) -> impl Future< - Output = Result>, Error>, - > + Send + 'static - where - Client: Send + Sync + 'static, - { - let client = self.client.clone(); - header_sub_fut_to_block_sub( - self.clone(), - async move { - let sub = client.backend().stream_best_block_headers().await?; - BlockStreamRes::Ok(sub) - }, - ) - } - /// Subscribe to finalized blocks. - pub fn subscribe_finalized( - &self, - ) -> impl Future< - Output = Result>, Error>, - > + Send + 'static - where - Client: Send + Sync + 'static, - { - let client = self.client.clone(); - header_sub_fut_to_block_sub( - self.clone(), - async move { - let sub = client - .backend() - .stream_finalized_block_headers() - .await?; - BlockStreamRes::Ok(sub) - }, - ) - } - } - /// Take a promise that will return a subscription to some block headers, - /// and return a subscription to some blocks based on this. - async fn header_sub_fut_to_block_sub( - blocks_client: BlocksClient, - sub: S, - ) -> Result>, Error> - where - T: Config, - S: Future< - Output = Result)>, Error>, - > + Send + 'static, - Client: OnlineClientT + Send + Sync + 'static, - { - let sub = sub - .await? - .then(move |header_and_ref| { - let client = blocks_client.client.clone(); - async move { - let (header, block_ref) = match header_and_ref { - Ok(header_and_ref) => header_and_ref, - Err(e) => return Err(e), - }; - Ok(Block::new(header, block_ref, client)) - } - }); - BlockStreamRes::Ok(StreamOfResults::new(Box::pin(sub))) - } - } - mod extrinsic_types { - use crate::{ - blocks::block_types::{get_events, CachedEvents}, - client::{OfflineClientT, OnlineClientT}, - config::{Config, Hasher}, - error::{BlockError, Error, MetadataError}, - events, metadata::types::PalletMetadata, Metadata, - }; - use crate::config::signed_extensions::{ - ChargeAssetTxPayment, ChargeTransactionPayment, CheckNonce, - }; - use crate::config::SignedExtension; - use crate::dynamic::DecodedValue; - use crate::utils::strip_compact_prefix; - use codec::Decode; - use derivative::Derivative; - use scale_decode::{DecodeAsFields, DecodeAsType}; - use std::sync::Arc; - /// Trait to uniquely identify the extrinsic's identity from the runtime metadata. - /// - /// Generated API structures that represent an extrinsic implement this trait. - /// - /// The trait is utilized to decode emitted extrinsics from a block, via obtaining the - /// form of the `Extrinsic` from the metadata. - pub trait StaticExtrinsic: DecodeAsFields { - /// Pallet name. - const PALLET: &'static str; - /// Call name. - const CALL: &'static str; - /// Returns true if the given pallet and call names match this extrinsic. - fn is_extrinsic(pallet: &str, call: &str) -> bool { - Self::PALLET == pallet && Self::CALL == call - } - } - /// The body of a block. - pub struct Extrinsics { - client: C, - extrinsics: Vec>, - cached_events: CachedEvents, - ids: ExtrinsicPartTypeIds, - hash: T::Hash, - } - impl Extrinsics - where - T: Config, - C: OfflineClientT, - { - pub(crate) fn new( - client: C, - extrinsics: Vec>, - cached_events: CachedEvents, - ids: ExtrinsicPartTypeIds, - hash: T::Hash, - ) -> Self { - Self { - client, - extrinsics, - cached_events, - ids, - hash, - } - } - /// The number of extrinsics. - pub fn len(&self) -> usize { - self.extrinsics.len() - } - /// Are there no extrinsics in this block? - pub fn is_empty(&self) -> bool { - self.extrinsics.is_empty() - } - /// Return the block hash that these extrinsics are from. - pub fn block_hash(&self) -> T::Hash { - self.hash - } - /// Returns an iterator over the extrinsics in the block body. - pub fn iter( - &self, - ) -> impl Iterator< - Item = Result, Error>, - > + Send + Sync + 'static { - let extrinsics = self.extrinsics.clone(); - let num_extrinsics = self.extrinsics.len(); - let client = self.client.clone(); - let hash = self.hash; - let cached_events = self.cached_events.clone(); - let ids = self.ids; - let mut index = 0; - std::iter::from_fn(move || { - if index == num_extrinsics { - None - } else { - match ExtrinsicDetails::decode_from( - index as u32, - &extrinsics[index], - client.clone(), - hash, - cached_events.clone(), - ids, - ) { - Ok(extrinsic_details) => { - index += 1; - Some(Ok(extrinsic_details)) - } - Err(e) => { - index = num_extrinsics; - Some(Err(e)) - } - } - } - }) - } - /// Iterate through the extrinsics using metadata to dynamically decode and skip - /// them, and return only those which should decode to the provided `E` type. - /// If an error occurs, all subsequent iterations return `None`. - pub fn find( - &self, - ) -> impl Iterator, Error>> + '_ { - self.iter() - .filter_map(|res| match res { - Err(err) => Some(Err(err)), - Ok(details) => { - match details.as_extrinsic::() { - Err(err) => Some(Err(err)), - Ok(None) => None, - Ok(Some(value)) => { - Some(Ok(FoundExtrinsic { details, value })) - } - } - } - }) - } - /// Iterate through the extrinsics using metadata to dynamically decode and skip - /// them, and return the first extrinsic found which decodes to the provided `E` type. - pub fn find_first( - &self, - ) -> Result>, Error> { - self.find::().next().transpose() - } - /// Iterate through the extrinsics using metadata to dynamically decode and skip - /// them, and return the last extrinsic found which decodes to the provided `Ev` type. - pub fn find_last( - &self, - ) -> Result>, Error> { - self.find::().last().transpose() - } - /// Find an extrinsics that decodes to the type provided. Returns true if it was found. - pub fn has(&self) -> Result { - Ok(self.find::().next().transpose()?.is_some()) - } - } - /// A single extrinsic in a block. - pub struct ExtrinsicDetails { - /// The index of the extrinsic in the block. - index: u32, - /// Extrinsic bytes. - bytes: Arc<[u8]>, - /// Some if the extrinsic payload is signed. - signed_details: Option, - /// The start index in the `bytes` from which the call is encoded. - call_start_idx: usize, - /// The pallet index. - pallet_index: u8, - /// The variant index. - variant_index: u8, - /// The block hash of this extrinsic (needed to fetch events). - block_hash: T::Hash, - /// Subxt client. - client: C, - /// Cached events. - cached_events: CachedEvents, - /// Subxt metadata to fetch the extrinsic metadata. - metadata: Metadata, - _marker: std::marker::PhantomData, - } - /// Details only available in signed extrinsics. - pub struct SignedExtrinsicDetails { - /// start index of the range in `bytes` of `ExtrinsicDetails` that encodes the address. - address_start_idx: usize, - /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the address. Equivalent to signature_start_idx. - address_end_idx: usize, - /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the signature. Equivalent to extra_start_idx. - signature_end_idx: usize, - /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the signature. - extra_end_idx: usize, - } - impl ExtrinsicDetails - where - T: Config, - C: OfflineClientT, - { - pub(crate) fn decode_from( - index: u32, - extrinsic_bytes: &[u8], - client: C, - block_hash: T::Hash, - cached_events: CachedEvents, - ids: ExtrinsicPartTypeIds, - ) -> Result, Error> { - const SIGNATURE_MASK: u8 = 0b1000_0000; - const VERSION_MASK: u8 = 0b0111_1111; - const LATEST_EXTRINSIC_VERSION: u8 = 4; - let metadata = client.metadata(); - let bytes: Arc<[u8]> = strip_compact_prefix(extrinsic_bytes)?.1.into(); - let first_byte: u8 = Decode::decode(&mut &bytes[..])?; - let version = first_byte & VERSION_MASK; - if version != LATEST_EXTRINSIC_VERSION { - return Err(BlockError::UnsupportedVersion(version).into()); - } - let is_signed = first_byte & SIGNATURE_MASK != 0; - let cursor = &mut &bytes[1..]; - let signed_details = is_signed - .then(|| -> Result { - let address_start_idx = bytes.len() - cursor.len(); - scale_decode::visitor::decode_with_visitor( - cursor, - ids.address, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(scale_decode::Error::from)?; - let address_end_idx = bytes.len() - cursor.len(); - scale_decode::visitor::decode_with_visitor( - cursor, - ids.signature, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(scale_decode::Error::from)?; - let signature_end_idx = bytes.len() - cursor.len(); - scale_decode::visitor::decode_with_visitor( - cursor, - ids.extra, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(scale_decode::Error::from)?; - let extra_end_idx = bytes.len() - cursor.len(); - Ok(SignedExtrinsicDetails { - address_start_idx, - address_end_idx, - signature_end_idx, - extra_end_idx, - }) - }) - .transpose()?; - let call_start_idx = bytes.len() - cursor.len(); - let cursor = &mut &bytes[call_start_idx..]; - let pallet_index: u8 = Decode::decode(cursor)?; - let variant_index: u8 = Decode::decode(cursor)?; - Ok(ExtrinsicDetails { - index, - bytes, - signed_details, - call_start_idx, - pallet_index, - variant_index, - block_hash, - client, - cached_events, - metadata, - _marker: std::marker::PhantomData, - }) - } - /// Is the extrinsic signed? - pub fn is_signed(&self) -> bool { - self.signed_details.is_some() - } - /// The index of the extrinsic in the block. - pub fn index(&self) -> u32 { - self.index - } - /// Return _all_ of the bytes representing this extrinsic, which include, in order: - /// - First byte: abbbbbbb (a = 0 for unsigned, 1 for signed, b = version) - /// - SignatureType (if the payload is signed) - /// - Address - /// - Signature - /// - Extra fields - /// - Extrinsic call bytes - pub fn bytes(&self) -> &[u8] { - &self.bytes - } - /// Return only the bytes representing this extrinsic call: - /// - First byte is the pallet index - /// - Second byte is the variant (call) index - /// - Followed by field bytes. - /// - /// # Note - /// - /// Please use [`Self::bytes`] if you want to get all extrinsic bytes. - pub fn call_bytes(&self) -> &[u8] { - &self.bytes[self.call_start_idx..] - } - /// Return the bytes representing the fields stored in this extrinsic. - /// - /// # Note - /// - /// This is a subset of [`Self::call_bytes`] that does not include the - /// first two bytes that denote the pallet index and the variant index. - pub fn field_bytes(&self) -> &[u8] { - &self.call_bytes()[2..] - } - /// Return only the bytes of the address that signed this extrinsic. - /// - /// # Note - /// - /// Returns `None` if the extrinsic is not signed. - pub fn address_bytes(&self) -> Option<&[u8]> { - self.signed_details - .as_ref() - .map(|e| &self.bytes[e.address_start_idx..e.address_end_idx]) - } - /// Returns Some(signature_bytes) if the extrinsic was signed otherwise None is returned. - pub fn signature_bytes(&self) -> Option<&[u8]> { - self.signed_details - .as_ref() - .map(|e| &self.bytes[e.address_end_idx..e.signature_end_idx]) - } - /// Returns the signed extension `extra` bytes of the extrinsic. - /// Each signed extension has an `extra` type (May be zero-sized). - /// These bytes are the scale encoded `extra` fields of each signed extension in order of the signed extensions. - /// They do *not* include the `additional` signed bytes that are used as part of the payload that is signed. - /// - /// Note: Returns `None` if the extrinsic is not signed. - pub fn signed_extensions_bytes(&self) -> Option<&[u8]> { - self.signed_details - .as_ref() - .map(|e| &self.bytes[e.signature_end_idx..e.extra_end_idx]) - } - /// Returns `None` if the extrinsic is not signed. - pub fn signed_extensions(&self) -> Option> { - let signed = self.signed_details.as_ref()?; - let extra_bytes = &self - .bytes[signed.signature_end_idx..signed.extra_end_idx]; - Some(ExtrinsicSignedExtensions { - bytes: extra_bytes, - metadata: &self.metadata, - _marker: std::marker::PhantomData, - }) - } - /// The index of the pallet that the extrinsic originated from. - pub fn pallet_index(&self) -> u8 { - self.pallet_index - } - /// The index of the extrinsic variant that the extrinsic originated from. - pub fn variant_index(&self) -> u8 { - self.variant_index - } - /// The name of the pallet from whence the extrinsic originated. - pub fn pallet_name(&self) -> Result<&str, Error> { - Ok(self.extrinsic_metadata()?.pallet.name()) - } - /// The name of the call (ie the name of the variant that it corresponds to). - pub fn variant_name(&self) -> Result<&str, Error> { - Ok(&self.extrinsic_metadata()?.variant.name) - } - /// Fetch the metadata for this extrinsic. - pub fn extrinsic_metadata(&self) -> Result { - let pallet = self.metadata.pallet_by_index_err(self.pallet_index())?; - let variant = pallet - .call_variant_by_index(self.variant_index()) - .ok_or_else(|| MetadataError::VariantIndexNotFound( - self.variant_index(), - ))?; - Ok(ExtrinsicMetadataDetails { - pallet, - variant, - }) - } - /// Decode and provide the extrinsic fields back in the form of a [`scale_value::Composite`] - /// type which represents the named or unnamed fields that were present in the extrinsic. - pub fn field_values( - &self, - ) -> Result, Error> { - let bytes = &mut self.field_bytes(); - let extrinsic_metadata = self.extrinsic_metadata()?; - let mut fields = extrinsic_metadata - .variant - .fields - .iter() - .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); - let decoded = >::decode_as_fields(bytes, &mut fields, self.metadata.types())?; - Ok(decoded) - } - /// Attempt to decode these [`ExtrinsicDetails`] into a type representing the extrinsic fields. - /// Such types are exposed in the codegen as `pallet_name::calls::types::CallName` types. - pub fn as_extrinsic(&self) -> Result, Error> { - let extrinsic_metadata = self.extrinsic_metadata()?; - if extrinsic_metadata.pallet.name() == E::PALLET - && extrinsic_metadata.variant.name == E::CALL - { - let mut fields = extrinsic_metadata - .variant - .fields - .iter() - .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); - let decoded = E::decode_as_fields( - &mut self.field_bytes(), - &mut fields, - self.metadata.types(), - )?; - Ok(Some(decoded)) - } else { - Ok(None) - } - } - /// Attempt to decode these [`ExtrinsicDetails`] into an outer call enum type (which includes - /// the pallet and extrinsic enum variants as well as the extrinsic fields). A compatible - /// type for this is exposed via static codegen as a root level `Call` type. - pub fn as_root_extrinsic(&self) -> Result { - let decoded = E::decode_as_type( - &mut &self.call_bytes()[..], - self.metadata.outer_enums().call_enum_ty(), - self.metadata.types(), - )?; - Ok(decoded) - } - } - impl ExtrinsicDetails - where - T: Config, - C: OnlineClientT, - { - /// The events associated with the extrinsic. - pub async fn events(&self) -> Result, Error> { - let events = get_events( - &self.client, - self.block_hash, - &self.cached_events, - ) - .await?; - let ext_hash = T::Hasher::hash_of(&self.bytes); - Ok(ExtrinsicEvents::new(ext_hash, self.index, events)) - } - } - /// A Static Extrinsic found in a block coupled with it's details. - pub struct FoundExtrinsic { - pub details: ExtrinsicDetails, - pub value: E, - } - /// Details for the given extrinsic plucked from the metadata. - pub struct ExtrinsicMetadataDetails<'a> { - pub pallet: PalletMetadata<'a>, - pub variant: &'a scale_info::Variant, - } - /// The type IDs extracted from the metadata that represent the - /// generic type parameters passed to the `UncheckedExtrinsic` from - /// the substrate-based chain. - pub(crate) struct ExtrinsicPartTypeIds { - /// The address (source) of the extrinsic. - address: u32, - /// The extrinsic call type. - _call: u32, - /// The signature of the extrinsic. - signature: u32, - /// The extra parameters of the extrinsic. - extra: u32, - } - #[automatically_derived] - impl ::core::fmt::Debug for ExtrinsicPartTypeIds { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "ExtrinsicPartTypeIds", - "address", - &self.address, - "_call", - &self._call, - "signature", - &self.signature, - "extra", - &&self.extra, - ) - } - } - #[automatically_derived] - impl ::core::marker::Copy for ExtrinsicPartTypeIds {} - #[automatically_derived] - impl ::core::clone::Clone for ExtrinsicPartTypeIds { - #[inline] - fn clone(&self) -> ExtrinsicPartTypeIds { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - impl ExtrinsicPartTypeIds { - /// Extract the generic type parameters IDs from the extrinsic type. - pub(crate) fn new(metadata: &Metadata) -> Result { - Ok(ExtrinsicPartTypeIds { - address: metadata.extrinsic().address_ty(), - _call: metadata.extrinsic().call_ty(), - signature: metadata.extrinsic().signature_ty(), - extra: metadata.extrinsic().extra_ty(), - }) - } - } - /// The events associated with a given extrinsic. - #[derivative(Debug(bound = ""))] - pub struct ExtrinsicEvents { - ext_hash: T::Hash, - idx: u32, - events: events::Events, - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for ExtrinsicEvents { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - ExtrinsicEvents { - ext_hash: ref __arg_0, - idx: ref __arg_1, - events: ref __arg_2, - } => { - let mut __debug_trait_builder = __f - .debug_struct("ExtrinsicEvents"); - let _ = __debug_trait_builder.field("ext_hash", &&(*__arg_0)); - let _ = __debug_trait_builder.field("idx", &&(*__arg_1)); - let _ = __debug_trait_builder.field("events", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - impl ExtrinsicEvents { - pub(crate) fn new( - ext_hash: T::Hash, - idx: u32, - events: events::Events, - ) -> Self { - Self { ext_hash, idx, events } - } - /// Return the hash of the block that the extrinsic is in. - pub fn block_hash(&self) -> T::Hash { - self.events.block_hash() - } - /// The index of the extrinsic that these events are produced from. - pub fn extrinsic_index(&self) -> u32 { - self.idx - } - /// Return the hash of the extrinsic. - pub fn extrinsic_hash(&self) -> T::Hash { - self.ext_hash - } - /// Return all of the events in the block that the extrinsic is in. - pub fn all_events_in_block(&self) -> &events::Events { - &self.events - } - /// Iterate over all of the raw events associated with this transaction. - /// - /// This works in the same way that [`events::Events::iter()`] does, with the - /// exception that it filters out events not related to the submitted extrinsic. - pub fn iter( - &self, - ) -> impl Iterator, Error>> + '_ { - self.events - .iter() - .filter(|ev| { - ev.as_ref() - .map(|ev| { - ev.phase() == events::Phase::ApplyExtrinsic(self.idx) - }) - .unwrap_or(true) - }) - } - /// Find all of the transaction events matching the event type provided as a generic parameter. - /// - /// This works in the same way that [`events::Events::find()`] does, with the - /// exception that it filters out events not related to the submitted extrinsic. - pub fn find( - &self, - ) -> impl Iterator> + '_ { - self.iter() - .filter_map(|ev| { - ev.and_then(|ev| ev.as_event::().map_err(Into::into)) - .transpose() - }) - } - /// Iterate through the transaction events using metadata to dynamically decode and skip - /// them, and return the first event found which decodes to the provided `Ev` type. - /// - /// This works in the same way that [`events::Events::find_first()`] does, with the - /// exception that it ignores events not related to the submitted extrinsic. - pub fn find_first( - &self, - ) -> Result, Error> { - self.find::().next().transpose() - } - /// Iterate through the transaction events using metadata to dynamically decode and skip - /// them, and return the last event found which decodes to the provided `Ev` type. - /// - /// This works in the same way that [`events::Events::find_last()`] does, with the - /// exception that it ignores events not related to the submitted extrinsic. - pub fn find_last( - &self, - ) -> Result, Error> { - self.find::().last().transpose() - } - /// Find an event in those associated with this transaction. Returns true if it was found. - /// - /// This works in the same way that [`events::Events::has()`] does, with the - /// exception that it ignores events not related to the submitted extrinsic. - pub fn has(&self) -> Result { - Ok(self.find::().next().transpose()?.is_some()) - } - } - /// The signed extensions of an extrinsic. - pub struct ExtrinsicSignedExtensions<'a, T: Config> { - bytes: &'a [u8], - metadata: &'a Metadata, - _marker: std::marker::PhantomData, - } - #[automatically_derived] - impl<'a, T: ::core::fmt::Debug + Config> ::core::fmt::Debug - for ExtrinsicSignedExtensions<'a, T> { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "ExtrinsicSignedExtensions", - "bytes", - &self.bytes, - "metadata", - &self.metadata, - "_marker", - &&self._marker, - ) - } - } - #[automatically_derived] - impl<'a, T: ::core::clone::Clone + Config> ::core::clone::Clone - for ExtrinsicSignedExtensions<'a, T> { - #[inline] - fn clone(&self) -> ExtrinsicSignedExtensions<'a, T> { - ExtrinsicSignedExtensions { - bytes: ::core::clone::Clone::clone(&self.bytes), - metadata: ::core::clone::Clone::clone(&self.metadata), - _marker: ::core::clone::Clone::clone(&self._marker), - } - } - } - impl<'a, T: Config> ExtrinsicSignedExtensions<'a, T> { - /// Returns an iterator over each of the signed extension details of the extrinsic. - /// If the decoding of any signed extension fails, an error item is yielded and the iterator stops. - pub fn iter( - &self, - ) -> impl Iterator, Error>> { - let signed_extension_types = self - .metadata - .extrinsic() - .signed_extensions(); - let num_signed_extensions = signed_extension_types.len(); - let bytes = self.bytes; - let mut index = 0; - let mut byte_start_idx = 0; - let metadata = &self.metadata; - std::iter::from_fn(move || { - if index == num_signed_extensions { - return None; - } - let extension = &signed_extension_types[index]; - let ty_id = extension.extra_ty(); - let cursor = &mut &bytes[byte_start_idx..]; - if let Err(err) - = scale_decode::visitor::decode_with_visitor( - cursor, - ty_id, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(|e| Error::Decode(e.into())) - { - index = num_signed_extensions; - return Some(Err(err)); - } - let byte_end_idx = bytes.len() - cursor.len(); - let bytes = &bytes[byte_start_idx..byte_end_idx]; - byte_start_idx = byte_end_idx; - index += 1; - Some( - Ok(ExtrinsicSignedExtension { - bytes, - ty_id, - identifier: extension.identifier(), - metadata, - _marker: std::marker::PhantomData, - }), - ) - }) - } - /// Searches through all signed extensions to find a specific one. - /// If the Signed Extension is not found `Ok(None)` is returned. - /// If the Signed Extension is found but decoding failed `Err(_)` is returned. - pub fn find>( - &self, - ) -> Result, Error> { - for ext in self.iter() { - let ext = ext?; - match ext.as_signed_extension::() { - Ok(Some(e)) => return Ok(Some(e)), - Ok(None) => continue, - Err(e) => return Err(e), - } - } - Ok(None) - } - /// The tip of an extrinsic, extracted from the ChargeTransactionPayment or ChargeAssetTxPayment - /// signed extension, depending on which is present. - /// - /// Returns `None` if `tip` was not found or decoding failed. - pub fn tip(&self) -> Option { - self.find::() - .ok() - .flatten() - .map(|e| e.tip()) - .or_else(|| { - self.find::>() - .ok() - .flatten() - .map(|e| e.tip()) - }) - } - /// The nonce of the account that submitted the extrinsic, extracted from the CheckNonce signed extension. - /// - /// Returns `None` if `nonce` was not found or decoding failed. - pub fn nonce(&self) -> Option { - self.find::().ok()? - } - } - /// A single signed extension - pub struct ExtrinsicSignedExtension<'a, T: Config> { - bytes: &'a [u8], - ty_id: u32, - identifier: &'a str, - metadata: &'a Metadata, - _marker: std::marker::PhantomData, - } - #[automatically_derived] - impl<'a, T: ::core::fmt::Debug + Config> ::core::fmt::Debug - for ExtrinsicSignedExtension<'a, T> { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "ExtrinsicSignedExtension", - "bytes", - &self.bytes, - "ty_id", - &self.ty_id, - "identifier", - &self.identifier, - "metadata", - &self.metadata, - "_marker", - &&self._marker, - ) - } - } - #[automatically_derived] - impl<'a, T: ::core::clone::Clone + Config> ::core::clone::Clone - for ExtrinsicSignedExtension<'a, T> { - #[inline] - fn clone(&self) -> ExtrinsicSignedExtension<'a, T> { - ExtrinsicSignedExtension { - bytes: ::core::clone::Clone::clone(&self.bytes), - ty_id: ::core::clone::Clone::clone(&self.ty_id), - identifier: ::core::clone::Clone::clone(&self.identifier), - metadata: ::core::clone::Clone::clone(&self.metadata), - _marker: ::core::clone::Clone::clone(&self._marker), - } - } - } - impl<'a, T: Config> ExtrinsicSignedExtension<'a, T> { - /// The bytes representing this signed extension. - pub fn bytes(&self) -> &'a [u8] { - self.bytes - } - /// The name of the signed extension. - pub fn name(&self) -> &'a str { - self.identifier - } - /// The type id of the signed extension. - pub fn type_id(&self) -> u32 { - self.ty_id - } - /// Signed Extension as a [`scale_value::Value`] - pub fn value(&self) -> Result { - self.as_type() - } - /// Decodes the bytes of this Signed Extension into its associated `Decoded` type. - /// Returns `Ok(None)` if the data we have doesn't match the Signed Extension we're asking to - /// decode with. - pub fn as_signed_extension>( - &self, - ) -> Result, Error> { - if !S::matches(self.identifier, self.ty_id, self.metadata.types()) { - return Ok(None); - } - self.as_type::().map(Some) - } - fn as_type(&self) -> Result { - let value = E::decode_as_type( - &mut &self.bytes[..], - self.ty_id, - self.metadata.types(), - )?; - Ok(value) - } - } - } - /// A reference to a block. - pub use crate::backend::BlockRef; - pub use block_types::Block; - pub use blocks_client::BlocksClient; - pub use extrinsic_types::{ - ExtrinsicDetails, ExtrinsicEvents, ExtrinsicSignedExtension, - ExtrinsicSignedExtensions, Extrinsics, StaticExtrinsic, - }; - pub(crate) use block_types::get_account_nonce; -} -pub mod client { - //! This module provides two clients that can be used to work with - //! transactions, storage and events. The [`OfflineClient`] works - //! entirely offline and can be passed to any function that doesn't - //! require network access. The [`OnlineClient`] requires network - //! access. - mod offline_client { - use crate::custom_values::CustomValuesClient; - use crate::{ - backend::RuntimeVersion, blocks::BlocksClient, constants::ConstantsClient, - events::EventsClient, runtime_api::RuntimeApiClient, storage::StorageClient, - tx::TxClient, Config, Metadata, - }; - use derivative::Derivative; - use std::sync::Arc; - /// A trait representing a client that can perform - /// offline-only actions. - pub trait OfflineClientT: Clone + Send + Sync + 'static { - /// Return the provided [`Metadata`]. - fn metadata(&self) -> Metadata; - /// Return the provided genesis hash. - fn genesis_hash(&self) -> T::Hash; - /// Return the provided [`RuntimeVersion`]. - fn runtime_version(&self) -> RuntimeVersion; - /// Work with transactions. - fn tx(&self) -> TxClient { - TxClient::new(self.clone()) - } - /// Work with events. - fn events(&self) -> EventsClient { - EventsClient::new(self.clone()) - } - /// Work with storage. - fn storage(&self) -> StorageClient { - StorageClient::new(self.clone()) - } - /// Access constants. - fn constants(&self) -> ConstantsClient { - ConstantsClient::new(self.clone()) - } - /// Work with blocks. - fn blocks(&self) -> BlocksClient { - BlocksClient::new(self.clone()) - } - /// Work with runtime API. - fn runtime_api(&self) -> RuntimeApiClient { - RuntimeApiClient::new(self.clone()) - } - /// Work this custom types. - fn custom_values(&self) -> CustomValuesClient { - CustomValuesClient::new(self.clone()) - } - } - /// A client that is capable of performing offline-only operations. - /// Can be constructed as long as you can populate the required fields. - #[derivative(Debug(bound = ""), Clone(bound = ""))] - pub struct OfflineClient { - inner: Arc>, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for OfflineClient { - fn clone(&self) -> Self { - match *self { - OfflineClient { inner: ref __arg_0 } => { - OfflineClient { - inner: (*__arg_0).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for OfflineClient { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - OfflineClient { inner: ref __arg_0 } => { - let mut __debug_trait_builder = __f - .debug_struct("OfflineClient"); - let _ = __debug_trait_builder.field("inner", &&(*__arg_0)); - __debug_trait_builder.finish() - } - } - } - } - #[derivative(Debug(bound = ""), Clone(bound = ""))] - struct Inner { - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: Metadata, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Inner { - fn clone(&self) -> Self { - match *self { - Inner { - genesis_hash: ref __arg_0, - runtime_version: ref __arg_1, - metadata: ref __arg_2, - } => { - Inner { - genesis_hash: (*__arg_0).clone(), - runtime_version: (*__arg_1).clone(), - metadata: (*__arg_2).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Inner { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Inner { - genesis_hash: ref __arg_0, - runtime_version: ref __arg_1, - metadata: ref __arg_2, - } => { - let mut __debug_trait_builder = __f.debug_struct("Inner"); - let _ = __debug_trait_builder - .field("genesis_hash", &&(*__arg_0)); - let _ = __debug_trait_builder - .field("runtime_version", &&(*__arg_1)); - let _ = __debug_trait_builder.field("metadata", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - impl OfflineClient { - /// Construct a new [`OfflineClient`], providing - /// the necessary runtime and compile-time arguments. - pub fn new( - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: impl Into, - ) -> OfflineClient { - OfflineClient { - inner: Arc::new(Inner { - genesis_hash, - runtime_version, - metadata: metadata.into(), - }), - } - } - /// Return the genesis hash. - pub fn genesis_hash(&self) -> T::Hash { - self.inner.genesis_hash - } - /// Return the runtime version. - pub fn runtime_version(&self) -> RuntimeVersion { - self.inner.runtime_version.clone() - } - /// Return the [`Metadata`] used in this client. - pub fn metadata(&self) -> Metadata { - self.inner.metadata.clone() - } - /// Work with transactions. - pub fn tx(&self) -> TxClient { - >::tx(self) - } - /// Work with events. - pub fn events(&self) -> EventsClient { - >::events(self) - } - /// Work with storage. - pub fn storage(&self) -> StorageClient { - >::storage(self) - } - /// Access constants. - pub fn constants(&self) -> ConstantsClient { - >::constants(self) - } - /// Access custom types - pub fn custom_values(&self) -> CustomValuesClient { - >::custom_values(self) - } - } - impl OfflineClientT for OfflineClient { - fn genesis_hash(&self) -> T::Hash { - self.genesis_hash() - } - fn runtime_version(&self) -> RuntimeVersion { - self.runtime_version() - } - fn metadata(&self) -> Metadata { - self.metadata() - } - } - impl<'a, T: Config> From<&'a OfflineClient> for OfflineClient { - fn from(c: &'a OfflineClient) -> Self { - c.clone() - } - } - } - mod online_client { - use super::{OfflineClient, OfflineClientT}; - use crate::custom_values::CustomValuesClient; - use crate::{ - backend::{ - legacy::LegacyBackend, rpc::RpcClient, Backend, BackendExt, - RuntimeVersion, StreamOfResults, - }, - blocks::{BlockRef, BlocksClient}, - constants::ConstantsClient, error::Error, events::EventsClient, - runtime_api::RuntimeApiClient, storage::StorageClient, tx::TxClient, Config, - Metadata, - }; - use derivative::Derivative; - use futures::future; - use std::sync::{Arc, RwLock}; - /// A trait representing a client that can perform - /// online actions. - pub trait OnlineClientT: OfflineClientT { - /// Return a backend that can be used to communicate with a node. - fn backend(&self) -> &dyn Backend; - } - /// A client that can be used to perform API calls (that is, either those - /// requiring an [`OfflineClientT`] or those requiring an [`OnlineClientT`]). - #[derivative(Clone(bound = ""))] - pub struct OnlineClient { - inner: Arc>>, - backend: Arc>, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for OnlineClient { - fn clone(&self) -> Self { - match *self { - OnlineClient { inner: ref __arg_0, backend: ref __arg_1 } => { - OnlineClient { - inner: (*__arg_0).clone(), - backend: (*__arg_1).clone(), - } - } - } - } - } - #[derivative(Debug(bound = ""))] - struct Inner { - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: Metadata, - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Inner { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Inner { - genesis_hash: ref __arg_0, - runtime_version: ref __arg_1, - metadata: ref __arg_2, - } => { - let mut __debug_trait_builder = __f.debug_struct("Inner"); - let _ = __debug_trait_builder - .field("genesis_hash", &&(*__arg_0)); - let _ = __debug_trait_builder - .field("runtime_version", &&(*__arg_1)); - let _ = __debug_trait_builder.field("metadata", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - impl std::fmt::Debug for OnlineClient { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Client") - .field("rpc", &"RpcClient") - .field("inner", &self.inner) - .finish() - } - } - #[cfg(feature = "jsonrpsee")] - impl OnlineClient { - /// Construct a new [`OnlineClient`] using default settings which - /// point to a locally running node on `ws://127.0.0.1:9944`. - pub async fn new() -> Result, Error> { - let url = "ws://127.0.0.1:9944"; - OnlineClient::from_url(url).await - } - /// Construct a new [`OnlineClient`], providing a URL to connect to. - pub async fn from_url( - url: impl AsRef, - ) -> Result, Error> { - crate::utils::validate_url_is_secure(url.as_ref())?; - OnlineClient::from_insecure_url(url).await - } - /// Construct a new [`OnlineClient`], providing a URL to connect to. - /// - /// Allows insecure URLs without SSL encryption, e.g. (http:// and ws:// URLs). - pub async fn from_insecure_url( - url: impl AsRef, - ) -> Result, Error> { - let client = RpcClient::from_insecure_url(url).await?; - let backend = LegacyBackend::new(client); - OnlineClient::from_backend(Arc::new(backend)).await - } - } - impl OnlineClient { - /// Construct a new [`OnlineClient`] by providing an [`RpcClient`] to drive the connection. - /// This will use the current default [`Backend`], which may change in future releases. - pub async fn from_rpc_client( - rpc_client: RpcClient, - ) -> Result, Error> { - let backend = Arc::new(LegacyBackend::new(rpc_client)); - OnlineClient::from_backend(backend).await - } - /// Construct a new [`OnlineClient`] by providing an RPC client along with the other - /// necessary details. This will use the current default [`Backend`], which may change - /// in future releases. - /// - /// # Warning - /// - /// This is considered the most primitive and also error prone way to - /// instantiate a client; the genesis hash, metadata and runtime version provided will - /// entirely determine which node and blocks this client will be able to interact with, - /// and whether it will be able to successfully do things like submit transactions. - /// - /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate - /// a client. - pub fn from_rpc_client_with( - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: impl Into, - rpc_client: RpcClient, - ) -> Result, Error> { - let backend = Arc::new(LegacyBackend::new(rpc_client)); - OnlineClient::from_backend_with( - genesis_hash, - runtime_version, - metadata, - backend, - ) - } - /// Construct a new [`OnlineClient`] by providing an underlying [`Backend`] - /// implementation to power it. Other details will be obtained from the chain. - pub async fn from_backend>( - backend: Arc, - ) -> Result, Error> { - let latest_block = backend.latest_finalized_block_ref().await?; - let (genesis_hash, runtime_version, metadata) = future::join3( - backend.genesis_hash(), - backend.current_runtime_version(), - OnlineClient::fetch_metadata(&*backend, latest_block.hash()), - ) - .await; - OnlineClient::from_backend_with( - genesis_hash?, - runtime_version?, - metadata?, - backend, - ) - } - /// Construct a new [`OnlineClient`] by providing all of the underlying details needed - /// to make it work. - /// - /// # Warning - /// - /// This is considered the most primitive and also error prone way to - /// instantiate a client; the genesis hash, metadata and runtime version provided will - /// entirely determine which node and blocks this client will be able to interact with, - /// and whether it will be able to successfully do things like submit transactions. - /// - /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate - /// a client. - pub fn from_backend_with>( - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: impl Into, - backend: Arc, - ) -> Result, Error> { - Ok(OnlineClient { - inner: Arc::new( - RwLock::new(Inner { - genesis_hash, - runtime_version, - metadata: metadata.into(), - }), - ), - backend, - }) - } - /// Fetch the metadata from substrate using the runtime API. - async fn fetch_metadata( - backend: &dyn Backend, - block_hash: T::Hash, - ) -> Result { - #[cfg(not(feature = "unstable-metadata"))] - OnlineClient::fetch_latest_stable_metadata(backend, block_hash).await - } - /// Fetch the latest stable metadata from the node. - async fn fetch_latest_stable_metadata( - backend: &dyn Backend, - block_hash: T::Hash, - ) -> Result { - const V15_METADATA_VERSION: u32 = 15; - if let Ok(bytes) - = backend.metadata_at_version(V15_METADATA_VERSION, block_hash).await - { - return Ok(bytes); - } - backend.legacy_metadata(block_hash).await - } - /// Create an object which can be used to keep the runtime up to date - /// in a separate thread. - /// - /// # Example - /// - /// ```no_run - /// # #[tokio::main] - /// # async fn main() { - /// use subxt::{ OnlineClient, PolkadotConfig }; - /// - /// let client = OnlineClient::::new().await.unwrap(); - /// - /// // high level API. - /// - /// let update_task = client.updater(); - /// tokio::spawn(async move { - /// update_task.perform_runtime_updates().await; - /// }); - /// - /// - /// // low level API. - /// - /// let updater = client.updater(); - /// tokio::spawn(async move { - /// let mut update_stream = updater.runtime_updates().await.unwrap(); - /// - /// while let Some(Ok(update)) = update_stream.next().await { - /// let version = update.runtime_version().spec_version; - /// - /// match updater.apply_update(update) { - /// Ok(()) => { - /// println!("Upgrade to version: {} successful", version) - /// } - /// Err(e) => { - /// println!("Upgrade to version {} failed {:?}", version, e); - /// } - /// }; - /// } - /// }); - /// # } - /// ``` - pub fn updater(&self) -> ClientRuntimeUpdater { - ClientRuntimeUpdater(self.clone()) - } - /// Return the [`Metadata`] used in this client. - pub fn metadata(&self) -> Metadata { - let inner = self.inner.read().expect("shouldn't be poisoned"); - inner.metadata.clone() - } - /// Change the [`Metadata`] used in this client. - /// - /// # Warning - /// - /// Setting custom metadata may leave Subxt unable to work with certain blocks, - /// subscribe to latest blocks or submit valid transactions. - pub fn set_metadata(&self, metadata: impl Into) { - let mut inner = self.inner.write().expect("shouldn't be poisoned"); - inner.metadata = metadata.into(); - } - /// Return the genesis hash. - pub fn genesis_hash(&self) -> T::Hash { - let inner = self.inner.read().expect("shouldn't be poisoned"); - inner.genesis_hash - } - /// Change the genesis hash used in this client. - /// - /// # Warning - /// - /// Setting a custom genesis hash may leave Subxt unable to - /// submit valid transactions. - pub fn set_genesis_hash(&self, genesis_hash: T::Hash) { - let mut inner = self.inner.write().expect("shouldn't be poisoned"); - inner.genesis_hash = genesis_hash; - } - /// Return the runtime version. - pub fn runtime_version(&self) -> RuntimeVersion { - let inner = self.inner.read().expect("shouldn't be poisoned"); - inner.runtime_version.clone() - } - /// Change the [`RuntimeVersion`] used in this client. - /// - /// # Warning - /// - /// Setting a custom runtime version may leave Subxt unable to - /// submit valid transactions. - pub fn set_runtime_version(&self, runtime_version: RuntimeVersion) { - let mut inner = self.inner.write().expect("shouldn't be poisoned"); - inner.runtime_version = runtime_version; - } - /// Return an RPC client to make raw requests with. - pub fn backend(&self) -> &dyn Backend { - &*self.backend - } - /// Return an offline client with the same configuration as this. - pub fn offline(&self) -> OfflineClient { - let inner = self.inner.read().expect("shouldn't be poisoned"); - OfflineClient::new( - inner.genesis_hash, - inner.runtime_version.clone(), - inner.metadata.clone(), - ) - } - /// Work with transactions. - pub fn tx(&self) -> TxClient { - >::tx(self) - } - /// Work with events. - pub fn events(&self) -> EventsClient { - >::events(self) - } - /// Work with storage. - pub fn storage(&self) -> StorageClient { - >::storage(self) - } - /// Access constants. - pub fn constants(&self) -> ConstantsClient { - >::constants(self) - } - /// Access custom types. - pub fn custom_values(&self) -> CustomValuesClient { - >::custom_values(self) - } - /// Work with blocks. - pub fn blocks(&self) -> BlocksClient { - >::blocks(self) - } - /// Work with runtime API. - pub fn runtime_api(&self) -> RuntimeApiClient { - >::runtime_api(self) - } - } - impl OfflineClientT for OnlineClient { - fn metadata(&self) -> Metadata { - self.metadata() - } - fn genesis_hash(&self) -> T::Hash { - self.genesis_hash() - } - fn runtime_version(&self) -> RuntimeVersion { - self.runtime_version() - } - } - impl OnlineClientT for OnlineClient { - fn backend(&self) -> &dyn Backend { - &*self.backend - } - } - /// Client wrapper for performing runtime updates. See [`OnlineClient::updater()`] - /// for example usage. - pub struct ClientRuntimeUpdater(OnlineClient); - impl ClientRuntimeUpdater { - fn is_runtime_version_different(&self, new: &RuntimeVersion) -> bool { - let curr = self.0.inner.read().expect("shouldn't be poisoned"); - &curr.runtime_version != new - } - fn do_update(&self, update: Update) { - let mut writable = self.0.inner.write().expect("shouldn't be poisoned"); - writable.metadata = update.metadata; - writable.runtime_version = update.runtime_version; - } - /// Tries to apply a new update. - pub fn apply_update(&self, update: Update) -> Result<(), UpgradeError> { - if !self.is_runtime_version_different(&update.runtime_version) { - return Err(UpgradeError::SameVersion); - } - self.do_update(update); - Ok(()) - } - /// Performs runtime updates indefinitely unless encountering an error. - /// - /// *Note:* This will run indefinitely until it errors, so the typical usage - /// would be to run it in a separate background task. - pub async fn perform_runtime_updates(&self) -> Result<(), Error> { - let mut runtime_version_stream = self.runtime_updates().await?; - while let Some(update) = runtime_version_stream.next().await { - let update = update?; - let _ = self.apply_update(update); - } - Ok(()) - } - /// Low-level API to get runtime updates as a stream but it's doesn't check if the - /// runtime version is newer or updates the runtime. - /// - /// Instead that's up to the user of this API to decide when to update and - /// to perform the actual updating. - pub async fn runtime_updates( - &self, - ) -> Result, Error> { - let stream = self.0.backend().stream_runtime_version().await?; - Ok(RuntimeUpdaterStream { - stream, - client: self.0.clone(), - }) - } - } - /// Stream to perform runtime upgrades. - pub struct RuntimeUpdaterStream { - stream: StreamOfResults, - client: OnlineClient, - } - impl RuntimeUpdaterStream { - /// Wait for the next runtime update. - pub async fn next(&mut self) -> Option> { - let runtime_version = match self.stream.next().await? { - Ok(runtime_version) => runtime_version, - Err(err) => return Some(Err(err)), - }; - let at = match wait_runtime_upgrade_in_finalized_block( - &self.client, - &runtime_version, - ) - .await? - { - Ok(at) => at, - Err(err) => return Some(Err(err)), - }; - let metadata = match OnlineClient::fetch_metadata( - self.client.backend(), - at.hash(), - ) - .await - { - Ok(metadata) => metadata, - Err(err) => return Some(Err(err)), - }; - Some( - Ok(Update { - metadata, - runtime_version, - }), - ) - } - } - /// Error that can occur during upgrade. - #[non_exhaustive] - pub enum UpgradeError { - /// The version is the same as the current version. - SameVersion, - } - #[automatically_derived] - impl ::core::fmt::Debug for UpgradeError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "SameVersion") - } - } - #[automatically_derived] - impl ::core::clone::Clone for UpgradeError { - #[inline] - fn clone(&self) -> UpgradeError { - UpgradeError::SameVersion - } - } - /// Represents the state when a runtime upgrade occurred. - pub struct Update { - runtime_version: RuntimeVersion, - metadata: Metadata, - } - impl Update { - /// Get the runtime version. - pub fn runtime_version(&self) -> &RuntimeVersion { - &self.runtime_version - } - /// Get the metadata. - pub fn metadata(&self) -> &Metadata { - &self.metadata - } - } - /// Helper to wait until the runtime upgrade is applied on at finalized block. - async fn wait_runtime_upgrade_in_finalized_block( - client: &OnlineClient, - runtime_version: &RuntimeVersion, - ) -> Option, Error>> { - use scale_value::At; - let mut block_sub = match client - .backend() - .stream_finalized_block_headers() - .await - { - Ok(s) => s, - Err(err) => return Some(Err(err)), - }; - let block_ref = loop { - let (_, block_ref) = match block_sub.next().await? { - Ok(n) => n, - Err(err) => return Some(Err(err)), - }; - let key: Vec = ::alloc::vec::Vec::new(); - let addr = crate::dynamic::storage("System", "LastRuntimeUpgrade", key); - let chunk = match client - .storage() - .at(block_ref.hash()) - .fetch(&addr) - .await - { - Ok(Some(v)) => v, - Ok(None) => { - ::core::panicking::panic_fmt( - format_args!( - "internal error: entered unreachable code: {0}", - format_args!("The storage item `system::lastRuntimeUpgrade` should always exist") - ), - ); - } - Err(e) => return Some(Err(e)), - }; - let scale_val = match chunk.to_value() { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - let Some(Ok(spec_version)) = scale_val - .at("spec_version") - .and_then(|v| v.as_u128()) - .map(u32::try_from) else { - return Some( - Err( - Error::Other( - "Decoding `RuntimeVersion::spec_version` as u32 failed" - .to_string(), - ), - ), - ); - }; - if spec_version == runtime_version.spec_version { - break block_ref; - } - }; - Some(Ok(block_ref)) - } - } - pub use offline_client::{OfflineClient, OfflineClientT}; - pub use online_client::{ - ClientRuntimeUpdater, OnlineClient, OnlineClientT, RuntimeUpdaterStream, Update, - UpgradeError, - }; -} -pub mod config { - //! This module provides a [`Config`] type, which is used to define various - //! types that are important in order to speak to a particular chain. - //! [`SubstrateConfig`] provides a default set of these types suitable for the - //! default Substrate node implementation, and [`PolkadotConfig`] for a - //! Polkadot node. - mod default_extrinsic_params { - use super::{signed_extensions, ExtrinsicParams}; - use super::{Config, Header}; - /// The default [`super::ExtrinsicParams`] implementation understands common signed extensions - /// and how to apply them to a given chain. - pub type DefaultExtrinsicParams = signed_extensions::AnyOf< - T, - ( - signed_extensions::CheckSpecVersion, - signed_extensions::CheckTxVersion, - signed_extensions::CheckNonce, - signed_extensions::CheckGenesis, - signed_extensions::CheckMortality, - signed_extensions::ChargeAssetTxPayment, - signed_extensions::ChargeTransactionPayment, - ), - >; - /// A builder that outputs the set of [`super::ExtrinsicParams::OtherParams`] required for - /// [`DefaultExtrinsicParams`]. This may expose methods that aren't applicable to the current - /// chain; such values will simply be ignored if so. - pub struct DefaultExtrinsicParamsBuilder { - /// `None` means the tx will be immortal. - mortality: Option>, - /// `None` means we'll use the native token. - tip_of_asset_id: Option, - tip: u128, - tip_of: u128, - } - struct Mortality { - /// Block hash that mortality starts from - checkpoint_hash: Hash, - /// Block number that mortality starts from (must - checkpoint_number: u64, - /// How many blocks the tx is mortal for - period: u64, - } - impl Default for DefaultExtrinsicParamsBuilder { - fn default() -> Self { - Self { - mortality: None, - tip: 0, - tip_of: 0, - tip_of_asset_id: None, - } - } - } - impl DefaultExtrinsicParamsBuilder { - /// Configure new extrinsic params. We default to providing no tip - /// and using an immortal transaction unless otherwise configured - pub fn new() -> Self { - Default::default() - } - /// Make the transaction mortal, given a block header that it should be mortal from, - /// and the number of blocks (roughly; it'll be rounded to a power of two) that it will - /// be mortal for. - pub fn mortal(mut self, from_block: &T::Header, for_n_blocks: u64) -> Self { - self - .mortality = Some(Mortality { - checkpoint_hash: from_block.hash(), - checkpoint_number: from_block.number().into(), - period: for_n_blocks, - }); - self - } - /// Make the transaction mortal, given a block number and block hash (which must both point to - /// the same block) that it should be mortal from, and the number of blocks (roughly; it'll be - /// rounded to a power of two) that it will be mortal for. - /// - /// Prefer to use [`DefaultExtrinsicParamsBuilder::mortal()`], which ensures that the block hash - /// and number align. - pub fn mortal_unchecked( - mut self, - from_block_number: u64, - from_block_hash: T::Hash, - for_n_blocks: u64, - ) -> Self { - self - .mortality = Some(Mortality { - checkpoint_hash: from_block_hash, - checkpoint_number: from_block_number, - period: for_n_blocks, - }); - self - } - /// Provide a tip to the block author in the chain's native token. - pub fn tip(mut self, tip: u128) -> Self { - self.tip = tip; - self.tip_of = tip; - self.tip_of_asset_id = None; - self - } - /// Provide a tip to the block author using the token denominated by the `asset_id` provided. This - /// is not applicable on chains which don't use the `ChargeAssetTxPayment` signed extension; in this - /// case, no tip will be given. - pub fn tip_of(mut self, tip: u128, asset_id: T::AssetId) -> Self { - self.tip = 0; - self.tip_of = tip; - self.tip_of_asset_id = Some(asset_id); - self - } - /// Build the extrinsic parameters. - pub fn build( - self, - ) -> as ExtrinsicParams>::OtherParams { - let check_mortality_params = if let Some(mortality) = self.mortality { - signed_extensions::CheckMortalityParams::mortal( - mortality.period, - mortality.checkpoint_number, - mortality.checkpoint_hash, - ) - } else { - signed_extensions::CheckMortalityParams::immortal() - }; - let charge_asset_tx_params = if let Some(asset_id) = self.tip_of_asset_id - { - signed_extensions::ChargeAssetTxPaymentParams::tip_of( - self.tip, - asset_id, - ) - } else { - signed_extensions::ChargeAssetTxPaymentParams::tip(self.tip) - }; - let charge_transaction_params = signed_extensions::ChargeTransactionPaymentParams::tip( - self.tip, - ); - ( - (), - (), - (), - (), - check_mortality_params, - charge_asset_tx_params, - charge_transaction_params, - ) - } - } - } - mod extrinsic_params { - //! This module contains a trait which controls the parameters that must - //! be provided in order to successfully construct an extrinsic. - //! [`crate::config::DefaultExtrinsicParams`] provides a general-purpose - //! implementation of this that will work in many cases. - use crate::{client::OfflineClientT, Config}; - use core::fmt::Debug; - /// An error that can be emitted when trying to construct an instance of [`ExtrinsicParams`], - /// encode data from the instance, or match on signed extensions. - #[non_exhaustive] - pub enum ExtrinsicParamsError { - /// Cannot find a type id in the metadata. The context provides some additional - /// information about the source of the error (eg the signed extension name). - #[error( - "Cannot find type id '{type_id} in the metadata (context: {context})" - )] - MissingTypeId { - /// Type ID. - type_id: u32, - /// Some arbitrary context to help narrow the source of the error. - context: &'static str, - }, - /// A signed extension in use on some chain was not provided. - #[error( - "The chain expects a signed extension with the name {0}, but we did not provide one" - )] - UnknownSignedExtension(String), - /// Some custom error. - #[error("Error constructing extrinsic parameters: {0}")] - Custom(CustomExtrinsicParamsError), - } - #[allow(unused_qualifications)] - impl std::error::Error for ExtrinsicParamsError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for ExtrinsicParamsError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - ExtrinsicParamsError::MissingTypeId { type_id, context } => { - __formatter - .write_fmt( - format_args!( - "Cannot find type id \'{0} in the metadata (context: {1})", - type_id.as_display(), context.as_display() - ), - ) - } - ExtrinsicParamsError::UnknownSignedExtension(_0) => { - __formatter - .write_fmt( - format_args!( - "The chain expects a signed extension with the name {0}, but we did not provide one", - _0.as_display() - ), - ) - } - ExtrinsicParamsError::Custom(_0) => { - __formatter - .write_fmt( - format_args!( - "Error constructing extrinsic parameters: {0}", _0 - .as_display() - ), - ) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ExtrinsicParamsError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - ExtrinsicParamsError::MissingTypeId { - type_id: __self_0, - context: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "MissingTypeId", - "type_id", - __self_0, - "context", - &__self_1, - ) - } - ExtrinsicParamsError::UnknownSignedExtension(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "UnknownSignedExtension", - &__self_0, - ) - } - ExtrinsicParamsError::Custom(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Custom", - &__self_0, - ) - } - } - } - } - /// A custom error. - pub type CustomExtrinsicParamsError = Box< - dyn std::error::Error + Send + Sync + 'static, - >; - impl From for ExtrinsicParamsError { - fn from(value: std::convert::Infallible) -> Self { - match value {} - } - } - impl From for ExtrinsicParamsError { - fn from(value: CustomExtrinsicParamsError) -> Self { - ExtrinsicParamsError::Custom(value) - } - } - /// This trait allows you to configure the "signed extra" and - /// "additional" parameters that are a part of the transaction payload - /// or the signer payload respectively. - pub trait ExtrinsicParams: ExtrinsicParamsEncoder + Sized + 'static { - /// These parameters can be provided to the constructor along with - /// some default parameters that `subxt` understands, in order to - /// help construct your [`ExtrinsicParams`] object. - type OtherParams; - /// Construct a new instance of our [`ExtrinsicParams`]. - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result; - } - /// This trait is expected to be implemented for any [`ExtrinsicParams`], and - /// defines how to encode the "additional" and "extra" params. Both functions - /// are optional and will encode nothing by default. - pub trait ExtrinsicParamsEncoder: 'static { - /// This is expected to SCALE encode the "signed extra" parameters - /// to some buffer that has been provided. These are the parameters - /// which are sent along with the transaction, as well as taken into - /// account when signing the transaction. - fn encode_extra_to(&self, _v: &mut Vec) {} - /// This is expected to SCALE encode the "additional" parameters - /// to some buffer that has been provided. These parameters are _not_ - /// sent along with the transaction, but are taken into account when - /// signing it, meaning the client and node must agree on their values. - fn encode_additional_to(&self, _v: &mut Vec) {} - } - } - pub mod polkadot { - //! Polkadot specific configuration - use super::{Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder}; - pub use crate::utils::{AccountId32, MultiAddress, MultiSignature}; - use crate::SubstrateConfig; - pub use primitive_types::{H256, U256}; - /// Default set of commonly used types by Polkadot nodes. - pub enum PolkadotConfig {} - impl Config for PolkadotConfig { - type Hash = ::Hash; - type AccountId = ::AccountId; - type Address = MultiAddress; - type Signature = ::Signature; - type Hasher = ::Hasher; - type Header = ::Header; - type ExtrinsicParams = PolkadotExtrinsicParams; - type AssetId = u32; - } - /// A struct representing the signed extra and additional parameters required - /// to construct a transaction for a polkadot node. - pub type PolkadotExtrinsicParams = DefaultExtrinsicParams; - /// A builder which leads to [`PolkadotExtrinsicParams`] being constructed. - /// This is what you provide to methods like `sign_and_submit()`. - pub type PolkadotExtrinsicParamsBuilder = DefaultExtrinsicParamsBuilder; - } - pub mod signed_extensions { - //! This module contains implementations for common signed extensions, each - //! of which implements [`SignedExtension`], and can be used in conjunction with - //! [`AnyOf`] to configure the set of signed extensions which are known about - //! when interacting with a chain. - use super::extrinsic_params::{ - ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, - }; - use crate::utils::Era; - use crate::{client::OfflineClientT, Config}; - use codec::{Compact, Encode}; - use core::fmt::Debug; - use derivative::Derivative; - use scale_decode::DecodeAsType; - use scale_info::PortableRegistry; - use std::collections::HashMap; - /// A single [`SignedExtension`] has a unique name, but is otherwise the - /// same as [`ExtrinsicParams`] in describing how to encode the extra and - /// additional data. - pub trait SignedExtension: ExtrinsicParams { - /// The type representing the `extra` bytes of a signed extension. - /// Decoding from this type should be symmetrical to the respective - /// `ExtrinsicParamsEncoder::encode_extra_to()` implementation of this signed extension. - type Decoded: DecodeAsType; - /// This should return true if the signed extension matches the details given. - /// Often, this will involve just checking that the identifier given matches that of the - /// extension in question. - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool; - } - /// The [`CheckSpecVersion`] signed extension. - pub struct CheckSpecVersion(u32); - impl ExtrinsicParams for CheckSpecVersion { - type OtherParams = (); - fn new>( - _nonce: u64, - client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CheckSpecVersion(client.runtime_version().spec_version)) - } - } - impl ExtrinsicParamsEncoder for CheckSpecVersion { - fn encode_additional_to(&self, v: &mut Vec) { - self.0.encode_to(v); - } - } - impl SignedExtension for CheckSpecVersion { - type Decoded = (); - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckSpecVersion" - } - } - /// The [`CheckNonce`] signed extension. - pub struct CheckNonce(Compact); - impl ExtrinsicParams for CheckNonce { - type OtherParams = (); - fn new>( - nonce: u64, - _client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CheckNonce(Compact(nonce))) - } - } - impl ExtrinsicParamsEncoder for CheckNonce { - fn encode_extra_to(&self, v: &mut Vec) { - self.0.encode_to(v); - } - } - impl SignedExtension for CheckNonce { - type Decoded = u64; - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckNonce" - } - } - /// The [`CheckTxVersion`] signed extension. - pub struct CheckTxVersion(u32); - impl ExtrinsicParams for CheckTxVersion { - type OtherParams = (); - fn new>( - _nonce: u64, - client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CheckTxVersion(client.runtime_version().transaction_version)) - } - } - impl ExtrinsicParamsEncoder for CheckTxVersion { - fn encode_additional_to(&self, v: &mut Vec) { - self.0.encode_to(v); - } - } - impl SignedExtension for CheckTxVersion { - type Decoded = (); - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckTxVersion" - } - } - /// The [`CheckGenesis`] signed extension. - pub struct CheckGenesis(T::Hash); - impl ExtrinsicParams for CheckGenesis { - type OtherParams = (); - fn new>( - _nonce: u64, - client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CheckGenesis(client.genesis_hash())) - } - } - impl ExtrinsicParamsEncoder for CheckGenesis { - fn encode_additional_to(&self, v: &mut Vec) { - self.0.encode_to(v); - } - } - impl SignedExtension for CheckGenesis { - type Decoded = (); - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckGenesis" - } - } - /// The [`CheckMortality`] signed extension. - pub struct CheckMortality { - era: Era, - checkpoint: T::Hash, - } - /// Parameters to configure the [`CheckMortality`] signed extension. - pub struct CheckMortalityParams { - era: Era, - checkpoint: Option, - } - impl Default for CheckMortalityParams { - fn default() -> Self { - Self { - era: Default::default(), - checkpoint: Default::default(), - } - } - } - impl CheckMortalityParams { - /// Configure a mortal transaction. The `period` is (roughly) how many - /// blocks the transaction will be valid for. The `block_number` and - /// `block_hash` should both point to the same block, and are the block that - /// the transaction is mortal from. - pub fn mortal(period: u64, block_number: u64, block_hash: T::Hash) -> Self { - CheckMortalityParams { - era: Era::mortal(period, block_number), - checkpoint: Some(block_hash), - } - } - /// An immortal transaction. - pub fn immortal() -> Self { - CheckMortalityParams { - era: Era::Immortal, - checkpoint: None, - } - } - } - impl ExtrinsicParams for CheckMortality { - type OtherParams = CheckMortalityParams; - fn new>( - _nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - Ok(CheckMortality { - era: other_params.era, - checkpoint: other_params.checkpoint.unwrap_or(client.genesis_hash()), - }) - } - } - impl ExtrinsicParamsEncoder for CheckMortality { - fn encode_extra_to(&self, v: &mut Vec) { - self.era.encode_to(v); - } - fn encode_additional_to(&self, v: &mut Vec) { - self.checkpoint.encode_to(v); - } - } - impl SignedExtension for CheckMortality { - type Decoded = Era; - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckMortality" - } - } - /// The [`ChargeAssetTxPayment`] signed extension. - #[derivative( - Clone(bound = "T::AssetId: Clone"), - Debug(bound = "T::AssetId: Debug") - )] - #[decode_as_type(trait_bounds = "T::AssetId: DecodeAsType")] - pub struct ChargeAssetTxPayment { - tip: Compact, - asset_id: Option, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for ChargeAssetTxPayment - where - T::AssetId: Clone, - { - fn clone(&self) -> Self { - match *self { - ChargeAssetTxPayment { tip: ref __arg_0, asset_id: ref __arg_1 } => { - ChargeAssetTxPayment { - tip: (*__arg_0).clone(), - asset_id: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for ChargeAssetTxPayment - where - T::AssetId: Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - ChargeAssetTxPayment { tip: ref __arg_0, asset_id: ref __arg_1 } => { - let mut __debug_trait_builder = __f - .debug_struct("ChargeAssetTxPayment"); - let _ = __debug_trait_builder.field("tip", &&(*__arg_0)); - let _ = __debug_trait_builder.field("asset_id", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<(T,)>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for ChargeAssetTxPayment - where - T::AssetId: DecodeAsType, - { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor - where - T::AssetId: DecodeAsType, - { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = ChargeAssetTxPayment; - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.has_unnamed_fields() { - return self.visit_tuple(&mut value.as_tuple(), type_id); - } - let vals: ::scale_decode::BTreeMap, _> = value - .map(|res| res.map(|item| (item.name(), item))) - .collect::>()?; - Ok(ChargeAssetTxPayment { - tip: { - let val = *vals - .get(&Some("tip")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "tip".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("tip"))? - }, - asset_id: { - let val = *vals - .get(&Some("asset_id")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "asset_id".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("asset_id"))? - }, - }) - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 2usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: value.remaining(), - expected_len: 2usize, - }), - ); - } - let vals = value; - Ok(ChargeAssetTxPayment { - tip: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("tip"))? - }, - asset_id: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("asset_id"))? - }, - }) - } - } - impl ::scale_decode::DecodeAsFields for ChargeAssetTxPayment - where - T::AssetId: DecodeAsType, - { - fn decode_as_fields<'info>( - input: &mut &[u8], - fields: &mut dyn ::scale_decode::FieldIter<'info>, - types: &'info ::scale_decode::PortableRegistry, - ) -> Result { - let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; - let mut composite = ::scale_decode::visitor::types::Composite::new( - input, - path, - fields, - types, - false, - ); - use ::scale_decode::{Visitor, IntoVisitor}; - let val = >::into_visitor() - .visit_composite( - &mut composite, - ::scale_decode::visitor::TypeId(0), - ); - composite.skip_decoding()?; - *input = composite.bytes_from_undecoded(); - val.map_err(From::from) - } - } - }; - impl ChargeAssetTxPayment { - /// Tip to the extrinsic author in the native chain token. - pub fn tip(&self) -> u128 { - self.tip.0 - } - /// Tip to the extrinsic author using the asset ID given. - pub fn asset_id(&self) -> Option<&T::AssetId> { - self.asset_id.as_ref() - } - } - /// Parameters to configure the [`ChargeAssetTxPayment`] signed extension. - pub struct ChargeAssetTxPaymentParams { - tip: u128, - asset_id: Option, - } - impl Default for ChargeAssetTxPaymentParams { - fn default() -> Self { - ChargeAssetTxPaymentParams { - tip: Default::default(), - asset_id: Default::default(), - } - } - } - impl ChargeAssetTxPaymentParams { - /// Don't provide a tip to the extrinsic author. - pub fn no_tip() -> Self { - ChargeAssetTxPaymentParams { - tip: 0, - asset_id: None, - } - } - /// Tip the extrinsic author in the native chain token. - pub fn tip(tip: u128) -> Self { - ChargeAssetTxPaymentParams { - tip, - asset_id: None, - } - } - /// Tip the extrinsic author using the asset ID given. - pub fn tip_of(tip: u128, asset_id: T::AssetId) -> Self { - ChargeAssetTxPaymentParams { - tip, - asset_id: Some(asset_id), - } - } - } - impl ExtrinsicParams for ChargeAssetTxPayment { - type OtherParams = ChargeAssetTxPaymentParams; - fn new>( - _nonce: u64, - _client: Client, - other_params: Self::OtherParams, - ) -> Result { - Ok(ChargeAssetTxPayment { - tip: Compact(other_params.tip), - asset_id: other_params.asset_id, - }) - } - } - impl ExtrinsicParamsEncoder for ChargeAssetTxPayment { - fn encode_extra_to(&self, v: &mut Vec) { - (self.tip, &self.asset_id).encode_to(v); - } - } - impl SignedExtension for ChargeAssetTxPayment { - type Decoded = Self; - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "ChargeAssetTxPayment" - } - } - /// The [`ChargeTransactionPayment`] signed extension. - pub struct ChargeTransactionPayment { - tip: Compact, - } - #[automatically_derived] - impl ::core::clone::Clone for ChargeTransactionPayment { - #[inline] - fn clone(&self) -> ChargeTransactionPayment { - ChargeTransactionPayment { - tip: ::core::clone::Clone::clone(&self.tip), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ChargeTransactionPayment { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "ChargeTransactionPayment", - "tip", - &&self.tip, - ) - } - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for ChargeTransactionPayment { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = ChargeTransactionPayment; - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.has_unnamed_fields() { - return self.visit_tuple(&mut value.as_tuple(), type_id); - } - let vals: ::scale_decode::BTreeMap, _> = value - .map(|res| res.map(|item| (item.name(), item))) - .collect::>()?; - Ok(ChargeTransactionPayment { - tip: { - let val = *vals - .get(&Some("tip")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "tip".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("tip"))? - }, - }) - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: value.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = value; - Ok(ChargeTransactionPayment { - tip: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("tip"))? - }, - }) - } - } - impl ::scale_decode::DecodeAsFields for ChargeTransactionPayment { - fn decode_as_fields<'info>( - input: &mut &[u8], - fields: &mut dyn ::scale_decode::FieldIter<'info>, - types: &'info ::scale_decode::PortableRegistry, - ) -> Result { - let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; - let mut composite = ::scale_decode::visitor::types::Composite::new( - input, - path, - fields, - types, - false, - ); - use ::scale_decode::{Visitor, IntoVisitor}; - let val = ::into_visitor() - .visit_composite( - &mut composite, - ::scale_decode::visitor::TypeId(0), - ); - composite.skip_decoding()?; - *input = composite.bytes_from_undecoded(); - val.map_err(From::from) - } - } - }; - impl ChargeTransactionPayment { - /// Tip to the extrinsic author in the native chain token. - pub fn tip(&self) -> u128 { - self.tip.0 - } - } - /// Parameters to configure the [`ChargeTransactionPayment`] signed extension. - pub struct ChargeTransactionPaymentParams { - tip: u128, - } - #[automatically_derived] - impl ::core::default::Default for ChargeTransactionPaymentParams { - #[inline] - fn default() -> ChargeTransactionPaymentParams { - ChargeTransactionPaymentParams { - tip: ::core::default::Default::default(), - } - } - } - impl ChargeTransactionPaymentParams { - /// Don't provide a tip to the extrinsic author. - pub fn no_tip() -> Self { - ChargeTransactionPaymentParams { - tip: 0, - } - } - /// Tip the extrinsic author in the native chain token. - pub fn tip(tip: u128) -> Self { - ChargeTransactionPaymentParams { - tip, - } - } - } - impl ExtrinsicParams for ChargeTransactionPayment { - type OtherParams = ChargeTransactionPaymentParams; - fn new>( - _nonce: u64, - _client: Client, - other_params: Self::OtherParams, - ) -> Result { - Ok(ChargeTransactionPayment { - tip: Compact(other_params.tip), - }) - } - } - impl ExtrinsicParamsEncoder for ChargeTransactionPayment { - fn encode_extra_to(&self, v: &mut Vec) { - self.tip.encode_to(v); - } - } - impl SignedExtension for ChargeTransactionPayment { - type Decoded = Self; - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "ChargeTransactionPayment" - } - } - /// This accepts a tuple of [`SignedExtension`]s, and will dynamically make use of whichever - /// ones are actually required for the chain in the correct order, ignoring the rest. This - /// is a sensible default, and allows for a single configuration to work across multiple chains. - pub struct AnyOf { - params: Vec>, - _marker: std::marker::PhantomData<(T, Params)>, - } - #[rustfmt::skip] - const _: () = { - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - { - type OtherParams = (A::OtherParams,); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - { - type OtherParams = (A::OtherParams, B::OtherParams); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - { - type OtherParams = (A::OtherParams, B::OtherParams, C::OtherParams); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - > ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - R::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if R::matches(e.identifier(), e.extra_ty(), types) { - let ext = R::new(nonce, client.clone(), other_params.17)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - > ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - R::OtherParams, - S::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if R::matches(e.identifier(), e.extra_ty(), types) { - let ext = R::new(nonce, client.clone(), other_params.17)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if S::matches(e.identifier(), e.extra_ty(), types) { - let ext = S::new(nonce, client.clone(), other_params.18)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - U, - > ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - U: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - R::OtherParams, - S::OtherParams, - U::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if R::matches(e.identifier(), e.extra_ty(), types) { - let ext = R::new(nonce, client.clone(), other_params.17)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if S::matches(e.identifier(), e.extra_ty(), types) { - let ext = S::new(nonce, client.clone(), other_params.18)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if U::matches(e.identifier(), e.extra_ty(), types) { - let ext = U::new(nonce, client.clone(), other_params.19)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - U, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - U: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - U, - V, - > ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - U: SignedExtension, - V: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - R::OtherParams, - S::OtherParams, - U::OtherParams, - V::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if R::matches(e.identifier(), e.extra_ty(), types) { - let ext = R::new(nonce, client.clone(), other_params.17)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if S::matches(e.identifier(), e.extra_ty(), types) { - let ext = S::new(nonce, client.clone(), other_params.18)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if U::matches(e.identifier(), e.extra_ty(), types) { - let ext = U::new(nonce, client.clone(), other_params.19)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if V::matches(e.identifier(), e.extra_ty(), types) { - let ext = V::new(nonce, client.clone(), other_params.20)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - U, - V, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - U: SignedExtension, - V: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - }; - /// Checks to see whether the type being given is empty, ie would require - /// 0 bytes to encode. - fn is_type_empty(type_id: u32, types: &scale_info::PortableRegistry) -> bool { - let Some(ty) = types.resolve(type_id) else { return false; - }; - use scale_info::TypeDef; - match &ty.type_def { - TypeDef::Composite(c) => { - c.fields.iter().all(|f| is_type_empty(f.ty.id, types)) - } - TypeDef::Array(a) => a.len == 0 || is_type_empty(a.type_param.id, types), - TypeDef::Tuple(t) => t.fields.iter().all(|f| is_type_empty(f.id, types)), - TypeDef::BitSequence(_) - | TypeDef::Variant(_) - | TypeDef::Sequence(_) - | TypeDef::Compact(_) - | TypeDef::Primitive(_) => false, - } - } - } - pub mod substrate { - //! Substrate specific configuration - use super::{ - Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, Hasher, Header, - }; - use codec::{Decode, Encode}; - use serde::{Deserialize, Serialize}; - pub use crate::utils::{AccountId32, MultiAddress, MultiSignature}; - pub use primitive_types::{H256, U256}; - /// Default set of commonly used types by Substrate runtimes. - pub enum SubstrateConfig {} - impl Config for SubstrateConfig { - type Hash = H256; - type AccountId = AccountId32; - type Address = MultiAddress; - type Signature = MultiSignature; - type Hasher = BlakeTwo256; - type Header = SubstrateHeader; - type ExtrinsicParams = SubstrateExtrinsicParams; - type AssetId = u32; - } - /// A struct representing the signed extra and additional parameters required - /// to construct a transaction for the default substrate node. - pub type SubstrateExtrinsicParams = DefaultExtrinsicParams; - /// A builder which leads to [`SubstrateExtrinsicParams`] being constructed. - /// This is what you provide to methods like `sign_and_submit()`. - pub type SubstrateExtrinsicParamsBuilder = DefaultExtrinsicParamsBuilder; - /// A type that can hash values using the blaks2_256 algorithm. - pub struct BlakeTwo256; - #[automatically_derived] - impl ::core::fmt::Debug for BlakeTwo256 { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "BlakeTwo256") - } - } - #[automatically_derived] - impl ::core::clone::Clone for BlakeTwo256 { - #[inline] - fn clone(&self) -> BlakeTwo256 { - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for BlakeTwo256 {} - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BlakeTwo256 {} - #[automatically_derived] - impl ::core::cmp::PartialEq for BlakeTwo256 { - #[inline] - fn eq(&self, other: &BlakeTwo256) -> bool { - true - } - } - #[automatically_derived] - impl ::core::cmp::Eq for BlakeTwo256 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for BlakeTwo256 { - fn size_hint(&self) -> usize { - 0_usize - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) {} - } - #[automatically_derived] - impl ::codec::EncodeLike for BlakeTwo256 {} - }; - impl Hasher for BlakeTwo256 { - type Output = H256; - fn hash(s: &[u8]) -> Self::Output { - sp_core_hashing::blake2_256(s).into() - } - } - /// A generic Substrate header type, adapted from `sp_runtime::generic::Header`. - /// The block number and hasher can be configured to adapt this for other nodes. - #[serde(rename_all = "camelCase")] - pub struct SubstrateHeader + TryFrom, H: Hasher> { - /// The parent hash. - pub parent_hash: H::Output, - /// The block number. - #[serde( - serialize_with = "serialize_number", - deserialize_with = "deserialize_number" - )] - #[codec(compact)] - pub number: N, - /// The state trie merkle root - pub state_root: H::Output, - /// The merkle root of the extrinsics. - pub extrinsics_root: H::Output, - /// A chain-specific digest of data useful for light clients or referencing auxiliary data. - pub digest: Digest, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl + TryFrom, H: Hasher> ::codec::Encode - for SubstrateHeader - where - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - N: ::codec::HasCompact, - { - fn size_hint(&self) -> usize { - 0_usize - .saturating_add(::codec::Encode::size_hint(&self.parent_hash)) - .saturating_add( - ::codec::Encode::size_hint( - &<::Type as ::codec::EncodeAsRef< - '_, - N, - >>::RefType::from(&self.number), - ), - ) - .saturating_add(::codec::Encode::size_hint(&self.state_root)) - .saturating_add( - ::codec::Encode::size_hint(&self.extrinsics_root), - ) - .saturating_add(::codec::Encode::size_hint(&self.digest)) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&self.parent_hash, __codec_dest_edqy); - { - ::codec::Encode::encode_to( - &<::Type as ::codec::EncodeAsRef< - '_, - N, - >>::RefType::from(&self.number), - __codec_dest_edqy, - ); - } - ::codec::Encode::encode_to(&self.state_root, __codec_dest_edqy); - ::codec::Encode::encode_to(&self.extrinsics_root, __codec_dest_edqy); - ::codec::Encode::encode_to(&self.digest, __codec_dest_edqy); - } - } - #[automatically_derived] - impl + TryFrom, H: Hasher> ::codec::EncodeLike - for SubstrateHeader - where - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - N: ::codec::HasCompact, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl + TryFrom, H: Hasher> ::codec::Decode - for SubstrateHeader - where - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - N: ::codec::HasCompact, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(SubstrateHeader:: { - parent_hash: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `SubstrateHeader::parent_hash`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - number: { - let __codec_res_edqy = <::Type as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `SubstrateHeader::number`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy.into() - } - } - }, - state_root: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `SubstrateHeader::state_root`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - extrinsics_root: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e - .chain( - "Could not decode `SubstrateHeader::extrinsics_root`", - ), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - digest: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `SubstrateHeader::digest`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - #[automatically_derived] - impl< - N: ::core::fmt::Debug + Copy + Into + TryFrom, - H: ::core::fmt::Debug + Hasher, - > ::core::fmt::Debug for SubstrateHeader - where - H::Output: ::core::fmt::Debug, - H::Output: ::core::fmt::Debug, - H::Output: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "SubstrateHeader", - "parent_hash", - &self.parent_hash, - "number", - &self.number, - "state_root", - &self.state_root, - "extrinsics_root", - &self.extrinsics_root, - "digest", - &&self.digest, - ) - } - } - #[automatically_derived] - impl< - N: Copy + Into + TryFrom, - H: Hasher, - > ::core::marker::StructuralPartialEq for SubstrateHeader {} - #[automatically_derived] - impl< - N: ::core::cmp::PartialEq + Copy + Into + TryFrom, - H: ::core::cmp::PartialEq + Hasher, - > ::core::cmp::PartialEq for SubstrateHeader - where - H::Output: ::core::cmp::PartialEq, - H::Output: ::core::cmp::PartialEq, - H::Output: ::core::cmp::PartialEq, - { - #[inline] - fn eq(&self, other: &SubstrateHeader) -> bool { - self.parent_hash == other.parent_hash && self.number == other.number - && self.state_root == other.state_root - && self.extrinsics_root == other.extrinsics_root - && self.digest == other.digest - } - } - #[automatically_derived] - impl< - N: ::core::cmp::Eq + Copy + Into + TryFrom, - H: ::core::cmp::Eq + Hasher, - > ::core::cmp::Eq for SubstrateHeader - where - H::Output: ::core::cmp::Eq, - H::Output: ::core::cmp::Eq, - H::Output: ::core::cmp::Eq, - { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl< - N: ::core::clone::Clone + Copy + Into + TryFrom, - H: ::core::clone::Clone + Hasher, - > ::core::clone::Clone for SubstrateHeader - where - H::Output: ::core::clone::Clone, - H::Output: ::core::clone::Clone, - H::Output: ::core::clone::Clone, - { - #[inline] - fn clone(&self) -> SubstrateHeader { - SubstrateHeader { - parent_hash: ::core::clone::Clone::clone(&self.parent_hash), - number: ::core::clone::Clone::clone(&self.number), - state_root: ::core::clone::Clone::clone(&self.state_root), - extrinsics_root: ::core::clone::Clone::clone(&self.extrinsics_root), - digest: ::core::clone::Clone::clone(&self.digest), - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl + TryFrom, H: Hasher> _serde::Serialize - for SubstrateHeader - where - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "SubstrateHeader", - false as usize + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "parentHash", - &self.parent_hash, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "number", - { - #[doc(hidden)] - struct __SerializeWith< - '__a, - N: Copy + Into + TryFrom + '__a, - H: Hasher + '__a, - > - where - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - { - values: (&'__a N,), - phantom: _serde::__private::PhantomData< - SubstrateHeader, - >, - } - impl< - '__a, - N: Copy + Into + TryFrom + '__a, - H: Hasher + '__a, - > _serde::Serialize for __SerializeWith<'__a, N, H> - where - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - { - fn serialize<__S>( - &self, - __s: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - serialize_number(self.values.0, __s) - } - } - &__SerializeWith { - values: (&self.number,), - phantom: _serde::__private::PhantomData::< - SubstrateHeader, - >, - } - }, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "stateRoot", - &self.state_root, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "extrinsicsRoot", - &self.extrinsics_root, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "digest", - &self.digest, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > _serde::Deserialize<'de> for SubstrateHeader - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "parentHash" => _serde::__private::Ok(__Field::__field0), - "number" => _serde::__private::Ok(__Field::__field1), - "stateRoot" => _serde::__private::Ok(__Field::__field2), - "extrinsicsRoot" => _serde::__private::Ok(__Field::__field3), - "digest" => _serde::__private::Ok(__Field::__field4), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"parentHash" => _serde::__private::Ok(__Field::__field0), - b"number" => _serde::__private::Ok(__Field::__field1), - b"stateRoot" => _serde::__private::Ok(__Field::__field2), - b"extrinsicsRoot" => { - _serde::__private::Ok(__Field::__field3) - } - b"digest" => _serde::__private::Ok(__Field::__field4), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > _serde::de::Visitor<'de> for __Visitor<'de, N, H> - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - type Value = SubstrateHeader; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct SubstrateHeader", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - H::Output, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - let __field1 = match { - #[doc(hidden)] - struct __DeserializeWith< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - value: N, - phantom: _serde::__private::PhantomData< - SubstrateHeader, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > _serde::Deserialize<'de> for __DeserializeWith<'de, N, H> - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: deserialize_number(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de, N, H>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - H::Output, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - H::Output, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - Digest, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - _serde::__private::Ok(SubstrateHeader { - parent_hash: __field0, - number: __field1, - state_root: __field2, - extrinsics_root: __field3, - digest: __field4, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option = _serde::__private::None; - let mut __field3: _serde::__private::Option = _serde::__private::None; - let mut __field4: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "parentHash", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("number"), - ); - } - __field1 = _serde::__private::Some({ - #[doc(hidden)] - struct __DeserializeWith< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - value: N, - phantom: _serde::__private::PhantomData< - SubstrateHeader, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > _serde::Deserialize<'de> for __DeserializeWith<'de, N, H> - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: deserialize_number(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - match _serde::de::MapAccess::next_value::< - __DeserializeWith<'de, N, H>, - >(&mut __map) { - _serde::__private::Ok(__wrapper) => __wrapper.value, - _serde::__private::Err(__err) => { - return _serde::__private::Err(__err); - } - } - }); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "stateRoot", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private::Option::is_some(&__field3) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "extrinsicsRoot", - ), - ); - } - __field3 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private::Option::is_some(&__field4) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("digest"), - ); - } - __field4 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("parentHash")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::missing_field("number"), - ); - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("stateRoot")? - } - }; - let __field3 = match __field3 { - _serde::__private::Some(__field3) => __field3, - _serde::__private::None => { - _serde::__private::de::missing_field("extrinsicsRoot")? - } - }; - let __field4 = match __field4 { - _serde::__private::Some(__field4) => __field4, - _serde::__private::None => { - _serde::__private::de::missing_field("digest")? - } - }; - _serde::__private::Ok(SubstrateHeader { - parent_hash: __field0, - number: __field1, - state_root: __field2, - extrinsics_root: __field3, - digest: __field4, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "parentHash", - "number", - "stateRoot", - "extrinsicsRoot", - "digest", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SubstrateHeader", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - SubstrateHeader, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - impl Header for SubstrateHeader - where - N: Copy + Into + Into + TryFrom + Encode, - H: Hasher + Encode, - SubstrateHeader: Encode + Decode, - { - type Number = N; - type Hasher = H; - fn number(&self) -> Self::Number { - self.number - } - } - /// Generic header digest. From `sp_runtime::generic::digest`. - pub struct Digest { - /// A list of digest items. - pub logs: Vec, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for Digest { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.logs) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&&self.logs, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.logs) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.logs, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike for Digest {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for Digest { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(Digest { - logs: { - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `Digest::logs`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for Digest { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Digest", - "logs", - &&self.logs, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Digest {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Digest { - #[inline] - fn eq(&self, other: &Digest) -> bool { - self.logs == other.logs - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Digest { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Digest { - #[inline] - fn clone(&self) -> Digest { - Digest { - logs: ::core::clone::Clone::clone(&self.logs), - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Digest { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Digest", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "logs", - &self.logs, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Digest { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "logs" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"logs" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Digest; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct Digest", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Digest with 1 element", - ), - ); - } - }; - _serde::__private::Ok(Digest { logs: __field0 }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option< - Vec, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("logs"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Vec, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("logs")? - } - }; - _serde::__private::Ok(Digest { logs: __field0 }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["logs"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Digest", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::default::Default for Digest { - #[inline] - fn default() -> Digest { - Digest { - logs: ::core::default::Default::default(), - } - } - } - /// Digest item that is able to encode/decode 'system' digest items and - /// provide opaque access to other items. From `sp_runtime::generic::digest`. - pub enum DigestItem { - /// A pre-runtime digest. - /// - /// These are messages from the consensus engine to the runtime, although - /// the consensus engine can (and should) read them itself to avoid - /// code and state duplication. It is erroneous for a runtime to produce - /// these, but this is not (yet) checked. - /// - /// NOTE: the runtime is not allowed to panic or fail in an `on_initialize` - /// call if an expected `PreRuntime` digest is not present. It is the - /// responsibility of a external block verifier to check this. Runtime API calls - /// will initialize the block without pre-runtime digests, so initialization - /// cannot fail when they are missing. - PreRuntime(ConsensusEngineId, Vec), - /// A message from the runtime to the consensus engine. This should *never* - /// be generated by the native code of any consensus engine, but this is not - /// checked (yet). - Consensus(ConsensusEngineId, Vec), - /// Put a Seal on it. This is only used by native code, and is never seen - /// by runtimes. - Seal(ConsensusEngineId, Vec), - /// Some other thing. Unsupported and experimental. - Other(Vec), - /// An indication for the light clients that the runtime execution - /// environment is updated. - /// - /// Currently this is triggered when: - /// 1. Runtime code blob is changed or - /// 2. `heap_pages` value is changed. - RuntimeEnvironmentUpdated, - } - #[automatically_derived] - impl ::core::fmt::Debug for DigestItem { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - DigestItem::PreRuntime(__self_0, __self_1) => { - ::core::fmt::Formatter::debug_tuple_field2_finish( - f, - "PreRuntime", - __self_0, - &__self_1, - ) - } - DigestItem::Consensus(__self_0, __self_1) => { - ::core::fmt::Formatter::debug_tuple_field2_finish( - f, - "Consensus", - __self_0, - &__self_1, - ) - } - DigestItem::Seal(__self_0, __self_1) => { - ::core::fmt::Formatter::debug_tuple_field2_finish( - f, - "Seal", - __self_0, - &__self_1, - ) - } - DigestItem::Other(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Other", - &__self_0, - ) - } - DigestItem::RuntimeEnvironmentUpdated => { - ::core::fmt::Formatter::write_str(f, "RuntimeEnvironmentUpdated") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DigestItem {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DigestItem { - #[inline] - fn eq(&self, other: &DigestItem) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - DigestItem::PreRuntime(__self_0, __self_1), - DigestItem::PreRuntime(__arg1_0, __arg1_1), - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - ( - DigestItem::Consensus(__self_0, __self_1), - DigestItem::Consensus(__arg1_0, __arg1_1), - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - ( - DigestItem::Seal(__self_0, __self_1), - DigestItem::Seal(__arg1_0, __arg1_1), - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - (DigestItem::Other(__self_0), DigestItem::Other(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DigestItem { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for DigestItem { - #[inline] - fn clone(&self) -> DigestItem { - match self { - DigestItem::PreRuntime(__self_0, __self_1) => { - DigestItem::PreRuntime( - ::core::clone::Clone::clone(__self_0), - ::core::clone::Clone::clone(__self_1), - ) - } - DigestItem::Consensus(__self_0, __self_1) => { - DigestItem::Consensus( - ::core::clone::Clone::clone(__self_0), - ::core::clone::Clone::clone(__self_1), - ) - } - DigestItem::Seal(__self_0, __self_1) => { - DigestItem::Seal( - ::core::clone::Clone::clone(__self_0), - ::core::clone::Clone::clone(__self_1), - ) - } - DigestItem::Other(__self_0) => { - DigestItem::Other(::core::clone::Clone::clone(__self_0)) - } - DigestItem::RuntimeEnvironmentUpdated => { - DigestItem::RuntimeEnvironmentUpdated - } - } - } - } - #[repr(u32)] - enum DigestItemType { - Other = 0u32, - Consensus = 4u32, - Seal = 5u32, - PreRuntime = 6u32, - RuntimeEnvironmentUpdated = 8u32, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for DigestItemType { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - DigestItemType::Other => 0_usize, - DigestItemType::Consensus => 0_usize, - DigestItemType::Seal => 0_usize, - DigestItemType::PreRuntime => 0_usize, - DigestItemType::RuntimeEnvironmentUpdated => 0_usize, - _ => 0_usize, - } - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - match *self { - DigestItemType::Other => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(0u32 as ::core::primitive::u8); - } - DigestItemType::Consensus => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(4u32 as ::core::primitive::u8); - } - DigestItemType::Seal => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(5u32 as ::core::primitive::u8); - } - DigestItemType::PreRuntime => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(6u32 as ::core::primitive::u8); - } - DigestItemType::RuntimeEnvironmentUpdated => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(8u32 as ::core::primitive::u8); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::codec::EncodeLike for DigestItemType {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for DigestItemType { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `DigestItemType`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(DigestItemType::Other) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 4u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(DigestItemType::Consensus) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 5u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(DigestItemType::Seal) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 6u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(DigestItemType::PreRuntime) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 8u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - DigestItemType::RuntimeEnvironmentUpdated, - ) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `DigestItemType`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - impl Encode for DigestItem { - fn encode(&self) -> Vec { - let mut v = Vec::new(); - match self { - Self::Consensus(val, data) => { - DigestItemType::Consensus.encode_to(&mut v); - (val, data).encode_to(&mut v); - } - Self::Seal(val, sig) => { - DigestItemType::Seal.encode_to(&mut v); - (val, sig).encode_to(&mut v); - } - Self::PreRuntime(val, data) => { - DigestItemType::PreRuntime.encode_to(&mut v); - (val, data).encode_to(&mut v); - } - Self::Other(val) => { - DigestItemType::Other.encode_to(&mut v); - val.encode_to(&mut v); - } - Self::RuntimeEnvironmentUpdated => { - DigestItemType::RuntimeEnvironmentUpdated.encode_to(&mut v); - } - } - v - } - } - impl Decode for DigestItem { - fn decode(input: &mut I) -> Result { - let item_type: DigestItemType = Decode::decode(input)?; - match item_type { - DigestItemType::PreRuntime => { - let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; - Ok(Self::PreRuntime(vals.0, vals.1)) - } - DigestItemType::Consensus => { - let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; - Ok(Self::Consensus(vals.0, vals.1)) - } - DigestItemType::Seal => { - let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; - Ok(Self::Seal(vals.0, vals.1)) - } - DigestItemType::Other => Ok(Self::Other(Decode::decode(input)?)), - DigestItemType::RuntimeEnvironmentUpdated => { - Ok(Self::RuntimeEnvironmentUpdated) - } - } - } - } - /// Consensus engine unique ID. From `sp_runtime::ConsensusEngineId`. - pub type ConsensusEngineId = [u8; 4]; - impl serde::Serialize for DigestItem { - fn serialize(&self, seq: S) -> Result - where - S: serde::Serializer, - { - self.using_encoded(|bytes| impl_serde::serialize::serialize(bytes, seq)) - } - } - impl<'a> serde::Deserialize<'a> for DigestItem { - fn deserialize(de: D) -> Result - where - D: serde::Deserializer<'a>, - { - let r = impl_serde::serialize::deserialize(de)?; - Decode::decode(&mut &r[..]) - .map_err(|e| serde::de::Error::custom({ - let res = ::alloc::fmt::format( - format_args!("Decode error: {0}", e), - ); - res - })) - } - } - fn serialize_number>( - val: &T, - s: S, - ) -> Result - where - S: serde::Serializer, - { - let u256: U256 = (*val).into(); - serde::Serialize::serialize(&u256, s) - } - fn deserialize_number<'a, D, T: TryFrom>(d: D) -> Result - where - D: serde::Deserializer<'a>, - { - use crate::backend::legacy::rpc_methods::NumberOrHex; - let number_or_hex = NumberOrHex::deserialize(d)?; - let u256 = number_or_hex.into_u256(); - TryFrom::try_from(u256) - .map_err(|_| serde::de::Error::custom("Try from failed")) - } - } - use crate::macros::cfg_substrate_compat; - use codec::{Decode, Encode}; - use core::fmt::Debug; - use scale_decode::DecodeAsType; - use scale_encode::EncodeAsType; - use serde::{de::DeserializeOwned, Serialize}; - pub use default_extrinsic_params::{ - DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, - }; - pub use extrinsic_params::{ - ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, - }; - pub use polkadot::{ - PolkadotConfig, PolkadotExtrinsicParams, PolkadotExtrinsicParamsBuilder, - }; - pub use signed_extensions::SignedExtension; - pub use substrate::{ - SubstrateConfig, SubstrateExtrinsicParams, SubstrateExtrinsicParamsBuilder, - }; - /// Runtime types. - pub trait Config: Sized + Send + Sync + 'static { - /// The output of the `Hasher` function. - type Hash: BlockHash; - /// The account ID type. - type AccountId: Debug + Clone + Encode; - /// The address type. - type Address: Debug + Encode + From; - /// The signature type. - type Signature: Debug + Encode; - /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). - type Hasher: Debug + Hasher; - /// The block header. - type Header: Debug - + Header - + Sync - + Send - + DeserializeOwned; - /// This type defines the extrinsic extra and additional parameters. - type ExtrinsicParams: ExtrinsicParams; - /// This is used to identify an asset in the `ChargeAssetTxPayment` signed extension. - type AssetId: Debug + Clone + Encode + DecodeAsType + EncodeAsType; - } - /// given some [`Config`], this return the other params needed for its `ExtrinsicParams`. - pub type OtherParamsFor = <::ExtrinsicParams as ExtrinsicParams< - T, - >>::OtherParams; - /// Block hashes must conform to a bunch of things to be used in Subxt. - pub trait BlockHash: Debug + Copy + Send + Sync + Decode + AsRef< - [u8], - > + Serialize + DeserializeOwned + Encode + PartialEq + Eq + std::hash::Hash {} - impl BlockHash for T - where - T: Debug + Copy + Send + Sync + Decode + AsRef<[u8]> + Serialize - + DeserializeOwned + Encode + PartialEq + Eq + std::hash::Hash, - {} - /// This represents the hasher used by a node to hash things like block headers - /// and extrinsics. - pub trait Hasher { - /// The type given back from the hash operation - type Output; - /// Hash some bytes to the given output type. - fn hash(s: &[u8]) -> Self::Output; - /// Hash some SCALE encodable type to the given output type. - fn hash_of(s: &S) -> Self::Output { - let out = s.encode(); - Self::hash(&out) - } - } - /// This represents the block header type used by a node. - pub trait Header: Sized + Encode + Decode { - /// The block number type for this header. - type Number: Into; - /// The hasher used to hash this header. - type Hasher: Hasher; - /// Return the block number of this header. - fn number(&self) -> Self::Number; - /// Hash this header. - fn hash(&self) -> ::Output { - Self::Hasher::hash_of(self) - } - } -} -pub mod constants { - //! Types associated with accessing constants. - mod constant_address { - use crate::{dynamic::DecodedValueThunk, metadata::DecodeWithMetadata}; - use derivative::Derivative; - use std::borrow::Cow; - /// This represents a constant address. Anything implementing this trait - /// can be used to fetch constants. - pub trait ConstantAddress { - /// The target type of the value that lives at this address. - type Target: DecodeWithMetadata; - /// The name of the pallet that the constant lives under. - fn pallet_name(&self) -> &str; - /// The name of the constant in a given pallet. - fn constant_name(&self) -> &str; - /// An optional hash which, if present, will be checked against - /// the node metadata to confirm that the return type matches what - /// we are expecting. - fn validation_hash(&self) -> Option<[u8; 32]> { - None - } - } - /// This represents the address of a constant. - #[derivative( - Clone(bound = ""), - Debug(bound = ""), - Eq(bound = ""), - Ord(bound = ""), - PartialEq(bound = "") - )] - pub struct Address { - pallet_name: Cow<'static, str>, - constant_name: Cow<'static, str>, - constant_hash: Option<[u8; 32]>, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Address { - fn clone(&self) -> Self { - match *self { - Address { - pallet_name: ref __arg_0, - constant_name: ref __arg_1, - constant_hash: ref __arg_2, - _marker: ref __arg_3, - } => { - Address { - pallet_name: (*__arg_0).clone(), - constant_name: (*__arg_1).clone(), - constant_hash: (*__arg_2).clone(), - _marker: (*__arg_3).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Address { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Address { - pallet_name: ref __arg_0, - constant_name: ref __arg_1, - constant_hash: ref __arg_2, - _marker: ref __arg_3, - } => { - let mut __debug_trait_builder = __f.debug_struct("Address"); - let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); - let _ = __debug_trait_builder - .field("constant_name", &&(*__arg_1)); - let _ = __debug_trait_builder - .field("constant_hash", &&(*__arg_2)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_3)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for Address {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for Address { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - Address { - pallet_name: ref __self_0, - constant_name: ref __self_1, - constant_hash: ref __self_2, - _marker: ref __self_3, - } => { - match *other { - Address { - pallet_name: ref __other_0, - constant_name: ref __other_1, - constant_hash: ref __other_2, - _marker: ref __other_3, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - && &(*__self_3) == &(*__other_3) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::Ord for Address { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - Address { - pallet_name: ref __self_0, - constant_name: ref __self_1, - constant_hash: ref __self_2, - _marker: ref __self_3, - } => { - match *other { - Address { - pallet_name: ref __other_0, - constant_name: ref __other_1, - constant_hash: ref __other_2, - _marker: ref __other_3, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - impl PartialOrd for Address { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - /// The type of address typically used to return dynamic constant values. - pub type DynamicAddress = Address; - impl Address { - /// Create a new [`Address`] to use to look up a constant. - pub fn new( - pallet_name: impl Into, - constant_name: impl Into, - ) -> Self { - Self { - pallet_name: Cow::Owned(pallet_name.into()), - constant_name: Cow::Owned(constant_name.into()), - constant_hash: None, - _marker: std::marker::PhantomData, - } - } - /// Create a new [`Address`] that will be validated - /// against node metadata using the hash given. - #[doc(hidden)] - pub fn new_static( - pallet_name: &'static str, - constant_name: &'static str, - hash: [u8; 32], - ) -> Self { - Self { - pallet_name: Cow::Borrowed(pallet_name), - constant_name: Cow::Borrowed(constant_name), - constant_hash: Some(hash), - _marker: std::marker::PhantomData, - } - } - /// Do not validate this constant prior to accessing it. - pub fn unvalidated(self) -> Self { - Self { - pallet_name: self.pallet_name, - constant_name: self.constant_name, - constant_hash: None, - _marker: self._marker, - } - } - } - impl ConstantAddress for Address { - type Target = ReturnTy; - fn pallet_name(&self) -> &str { - &self.pallet_name - } - fn constant_name(&self) -> &str { - &self.constant_name - } - fn validation_hash(&self) -> Option<[u8; 32]> { - self.constant_hash - } - } - /// Construct a new dynamic constant lookup. - pub fn dynamic( - pallet_name: impl Into, - constant_name: impl Into, - ) -> DynamicAddress { - DynamicAddress::new(pallet_name, constant_name) - } - } - mod constants_client { - use super::ConstantAddress; - use crate::{ - client::OfflineClientT, error::{Error, MetadataError}, - metadata::DecodeWithMetadata, Config, - }; - use derivative::Derivative; - /// A client for accessing constants. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct ConstantsClient { - client: Client, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for ConstantsClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - ConstantsClient { client: ref __arg_0, _marker: ref __arg_1 } => { - ConstantsClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl ConstantsClient { - /// Create a new [`ConstantsClient`]. - pub fn new(client: Client) -> Self { - Self { - client, - _marker: std::marker::PhantomData, - } - } - } - impl> ConstantsClient { - /// Run the validation logic against some constant address you'd like to access. Returns `Ok(())` - /// if the address is valid (or if it's not possible to check since the address has no validation hash). - /// Return an error if the address was not valid or something went wrong trying to validate it (ie - /// the pallet or constant in question do not exist at all). - pub fn validate( - &self, - address: &Address, - ) -> Result<(), Error> { - if let Some(actual_hash) = address.validation_hash() { - let expected_hash = self - .client - .metadata() - .pallet_by_name_err(address.pallet_name())? - .constant_hash(address.constant_name()) - .ok_or_else(|| { - MetadataError::ConstantNameNotFound( - address.constant_name().to_owned(), - ) - })?; - if actual_hash != expected_hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - } - Ok(()) - } - /// Access the constant at the address given, returning the type defined by this address. - /// This is probably used with addresses given from static codegen, although you can manually - /// construct your own, too. - pub fn at( - &self, - address: &Address, - ) -> Result { - let metadata = self.client.metadata(); - self.validate(address)?; - let constant = metadata - .pallet_by_name_err(address.pallet_name())? - .constant_by_name(address.constant_name()) - .ok_or_else(|| { - MetadataError::ConstantNameNotFound( - address.constant_name().to_owned(), - ) - })?; - let value = ::decode_with_metadata( - &mut constant.value(), - constant.ty(), - &metadata, - )?; - Ok(value) - } - } - } - pub use constant_address::{dynamic, Address, ConstantAddress, DynamicAddress}; - pub use constants_client::ConstantsClient; -} -pub mod custom_values { - //! Types associated with accessing custom types - mod custom_value_address { - use derivative::Derivative; - use std::marker::PhantomData; - use crate::dynamic::DecodedValueThunk; - use crate::metadata::DecodeWithMetadata; - /// This represents the address of a custom value in in the metadata. - /// Anything, that implements the [CustomValueAddress] trait can be used, to fetch - /// custom values from the metadata. - /// The trait is implemented by [str] for dynamic loopup and [StaticAddress] for static queries. - pub trait CustomValueAddress { - /// The type of the custom value. - type Target: DecodeWithMetadata; - /// Should be set to `Yes` for Dynamic values and static values that have a valid type. - /// Should be `()` for custom values, that have an invalid type id. - type IsDecodable; - /// the name (key) by which the custom value can be accessed in the metadata. - fn name(&self) -> &str; - /// An optional hash which, if present, can be checked against node metadata. - fn validation_hash(&self) -> Option<[u8; 32]> { - None - } - } - impl CustomValueAddress for str { - type Target = DecodedValueThunk; - type IsDecodable = Yes; - fn name(&self) -> &str { - self - } - } - /// Used to signal whether a [`CustomValueAddress`] can be decoded. - pub struct Yes; - /// A static address to a custom value. - #[derivative( - Clone(bound = ""), - Debug(bound = ""), - Eq(bound = ""), - Ord(bound = ""), - PartialEq(bound = "") - )] - pub struct StaticAddress { - name: &'static str, - hash: Option<[u8; 32]>, - phantom: PhantomData<(ReturnTy, IsDecodable)>, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone - for StaticAddress { - fn clone(&self) -> Self { - match *self { - StaticAddress { - name: ref __arg_0, - hash: ref __arg_1, - phantom: ref __arg_2, - } => { - StaticAddress { - name: (*__arg_0).clone(), - hash: (*__arg_1).clone(), - phantom: (*__arg_2).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug - for StaticAddress { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - StaticAddress { - name: ref __arg_0, - hash: ref __arg_1, - phantom: ref __arg_2, - } => { - let mut __debug_trait_builder = __f - .debug_struct("StaticAddress"); - let _ = __debug_trait_builder.field("name", &&(*__arg_0)); - let _ = __debug_trait_builder.field("hash", &&(*__arg_1)); - let _ = __debug_trait_builder.field("phantom", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq - for StaticAddress {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq - for StaticAddress { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - StaticAddress { - name: ref __self_0, - hash: ref __self_1, - phantom: ref __self_2, - } => { - match *other { - StaticAddress { - name: ref __other_0, - hash: ref __other_1, - phantom: ref __other_2, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::Ord - for StaticAddress { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - StaticAddress { - name: ref __self_0, - hash: ref __self_1, - phantom: ref __self_2, - } => { - match *other { - StaticAddress { - name: ref __other_0, - hash: ref __other_1, - phantom: ref __other_2, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - impl PartialOrd for StaticAddress { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - impl StaticAddress { - #[doc(hidden)] - /// Creates a new StaticAddress. - pub fn new_static( - name: &'static str, - hash: [u8; 32], - ) -> StaticAddress { - StaticAddress:: { - name, - hash: Some(hash), - phantom: PhantomData, - } - } - /// Do not validate this custom value prior to accessing it. - pub fn unvalidated(self) -> Self { - Self { - name: self.name, - hash: None, - phantom: self.phantom, - } - } - } - impl CustomValueAddress for StaticAddress { - type Target = R; - type IsDecodable = Y; - fn name(&self) -> &str { - self.name - } - fn validation_hash(&self) -> Option<[u8; 32]> { - self.hash - } - } - } - mod custom_values_client { - use crate::client::OfflineClientT; - use crate::custom_values::custom_value_address::{CustomValueAddress, Yes}; - use crate::error::MetadataError; - use crate::metadata::DecodeWithMetadata; - use crate::{Config, Error}; - use derivative::Derivative; - /// A client for accessing custom values stored in the metadata. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct CustomValuesClient { - client: Client, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for CustomValuesClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - CustomValuesClient { client: ref __arg_0, _marker: ref __arg_1 } => { - CustomValuesClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl CustomValuesClient { - /// Create a new [`CustomValuesClient`]. - pub fn new(client: Client) -> Self { - Self { - client, - _marker: std::marker::PhantomData, - } - } - } - impl> CustomValuesClient { - /// Access a custom value by the address it is registered under. This can be just a [str] to get back a dynamic value, - /// or a static address from the generated static interface to get a value of a static type returned. - pub fn at + ?Sized>( - &self, - address: &Address, - ) -> Result { - self.validate(address)?; - let metadata = self.client.metadata(); - let custom = metadata.custom(); - let custom_value = custom - .get(address.name()) - .ok_or_else(|| MetadataError::CustomValueNameNotFound( - address.name().to_string(), - ))?; - let value = ::decode_with_metadata( - &mut custom_value.bytes(), - custom_value.type_id(), - &metadata, - )?; - Ok(value) - } - /// Access the bytes of a custom value by the address it is registered under. - pub fn bytes_at( - &self, - address: &Address, - ) -> Result, Error> { - self.validate(address)?; - let metadata = self.client.metadata(); - let custom = metadata.custom(); - let custom_value = custom - .get(address.name()) - .ok_or_else(|| MetadataError::CustomValueNameNotFound( - address.name().to_string(), - ))?; - Ok(custom_value.bytes().to_vec()) - } - /// Run the validation logic against some custom value address you'd like to access. Returns `Ok(())` - /// if the address is valid (or if it's not possible to check since the address has no validation hash). - /// Returns an error if the address was not valid (wrong name, type or raw bytes) - pub fn validate( - &self, - address: &Address, - ) -> Result<(), Error> { - let metadata = self.client.metadata(); - if let Some(actual_hash) = address.validation_hash() { - let custom = metadata.custom(); - let custom_value = custom - .get(address.name()) - .ok_or_else(|| MetadataError::CustomValueNameNotFound( - address.name().into(), - ))?; - let expected_hash = custom_value.hash(); - if actual_hash != expected_hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - } - if metadata.custom().get(address.name()).is_none() { - return Err(MetadataError::IncompatibleCodegen.into()); - } - Ok(()) - } - } - } - pub use custom_value_address::{CustomValueAddress, StaticAddress, Yes}; - pub use custom_values_client::CustomValuesClient; -} -pub mod dynamic { - //! This module provides the entry points to create dynamic - //! transactions, storage and constant lookups. - use crate::{error::Error, metadata::{DecodeWithMetadata, Metadata}}; - use scale_decode::DecodeAsType; - pub use scale_value::{At, Value}; - /// A [`scale_value::Value`] type endowed with contextual information - /// regarding what type was used to decode each part of it. This implements - /// [`crate::metadata::DecodeWithMetadata`], and is used as a return type - /// for dynamic requests. - pub type DecodedValue = scale_value::Value; - pub use crate::tx::dynamic as tx; - pub use crate::constants::dynamic as constant; - pub use crate::storage::dynamic as storage; - pub use crate::runtime_api::dynamic as runtime_api_call; - /// This is the result of making a dynamic request to a node. From this, - /// we can return the raw SCALE bytes that we were handed back, or we can - /// complete the decoding of the bytes into a [`DecodedValue`] type. - pub struct DecodedValueThunk { - type_id: u32, - metadata: Metadata, - scale_bytes: Vec, - } - impl DecodeWithMetadata for DecodedValueThunk { - fn decode_with_metadata( - bytes: &mut &[u8], - type_id: u32, - metadata: &Metadata, - ) -> Result { - let mut v = Vec::with_capacity(bytes.len()); - v.extend_from_slice(bytes); - *bytes = &[]; - Ok(DecodedValueThunk { - type_id, - metadata: metadata.clone(), - scale_bytes: v, - }) - } - } - impl DecodedValueThunk { - /// Return the SCALE encoded bytes handed back from the node. - pub fn into_encoded(self) -> Vec { - self.scale_bytes - } - /// Return the SCALE encoded bytes handed back from the node without taking ownership of them. - pub fn encoded(&self) -> &[u8] { - &self.scale_bytes - } - /// Decode the SCALE encoded storage entry into a dynamic [`DecodedValue`] type. - pub fn to_value(&self) -> Result { - let val = DecodedValue::decode_as_type( - &mut &*self.scale_bytes, - self.type_id, - self.metadata.types(), - )?; - Ok(val) - } - /// decode the `DecodedValueThunk` into a concrete type. - pub fn as_type(&self) -> Result { - T::decode_as_type( - &mut &self.scale_bytes[..], - self.type_id, - self.metadata.types(), - ) - } - } -} -pub mod error { - //! Types representing the errors that can be returned. - mod dispatch_error { - //! A representation of the dispatch error; an error returned when - //! something fails in trying to submit/execute a transaction. - use crate::metadata::{DecodeWithMetadata, Metadata}; - use core::fmt::Debug; - use scale_decode::{visitor::DecodeAsTypeResult, DecodeAsType}; - use std::borrow::Cow; - use super::{Error, MetadataError}; - /// An error dispatching a transaction. - #[non_exhaustive] - pub enum DispatchError { - /// Some error occurred. - #[error("Some unknown error occurred.")] - Other, - /// Failed to lookup some data. - #[error("Failed to lookup some data.")] - CannotLookup, - /// A bad origin. - #[error("Bad origin.")] - BadOrigin, - /// A custom error in a module. - #[error("Pallet error: {0}")] - Module(ModuleError), - /// At least one consumer is remaining so the account cannot be destroyed. - #[error( - "At least one consumer is remaining so the account cannot be destroyed." - )] - ConsumerRemaining, - /// There are no providers so the account cannot be created. - #[error("There are no providers so the account cannot be created.")] - NoProviders, - /// There are too many consumers so the account cannot be created. - #[error("There are too many consumers so the account cannot be created.")] - TooManyConsumers, - /// An error to do with tokens. - #[error("Token error: {0}")] - Token(TokenError), - /// An arithmetic error. - #[error("Arithmetic error: {0}")] - Arithmetic(ArithmeticError), - /// The number of transactional layers has been reached, or we are not in a transactional layer. - #[error("Transactional error: {0}")] - Transactional(TransactionalError), - /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. - #[error( - "Resources exhausted, e.g. attempt to read/write data which is too large to manipulate." - )] - Exhausted, - /// The state is corrupt; this is generally not going to fix itself. - #[error("The state is corrupt; this is generally not going to fix itself.")] - Corruption, - /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. - #[error( - "Some resource (e.g. a preimage) is unavailable right now. This might fix itself later." - )] - Unavailable, - } - #[automatically_derived] - impl ::core::fmt::Debug for DispatchError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - DispatchError::Other => ::core::fmt::Formatter::write_str(f, "Other"), - DispatchError::CannotLookup => { - ::core::fmt::Formatter::write_str(f, "CannotLookup") - } - DispatchError::BadOrigin => { - ::core::fmt::Formatter::write_str(f, "BadOrigin") - } - DispatchError::Module(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Module", - &__self_0, - ) - } - DispatchError::ConsumerRemaining => { - ::core::fmt::Formatter::write_str(f, "ConsumerRemaining") - } - DispatchError::NoProviders => { - ::core::fmt::Formatter::write_str(f, "NoProviders") - } - DispatchError::TooManyConsumers => { - ::core::fmt::Formatter::write_str(f, "TooManyConsumers") - } - DispatchError::Token(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Token", - &__self_0, - ) - } - DispatchError::Arithmetic(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Arithmetic", - &__self_0, - ) - } - DispatchError::Transactional(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Transactional", - &__self_0, - ) - } - DispatchError::Exhausted => { - ::core::fmt::Formatter::write_str(f, "Exhausted") - } - DispatchError::Corruption => { - ::core::fmt::Formatter::write_str(f, "Corruption") - } - DispatchError::Unavailable => { - ::core::fmt::Formatter::write_str(f, "Unavailable") - } - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for DispatchError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for DispatchError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - DispatchError::Other {} => { - __formatter.write_str("Some unknown error occurred.") - } - DispatchError::CannotLookup {} => { - __formatter.write_str("Failed to lookup some data.") - } - DispatchError::BadOrigin {} => __formatter.write_str("Bad origin."), - DispatchError::Module(_0) => { - __formatter - .write_fmt( - format_args!("Pallet error: {0}", _0.as_display()), - ) - } - DispatchError::ConsumerRemaining {} => { - __formatter - .write_str( - "At least one consumer is remaining so the account cannot be destroyed.", - ) - } - DispatchError::NoProviders {} => { - __formatter - .write_str( - "There are no providers so the account cannot be created.", - ) - } - DispatchError::TooManyConsumers {} => { - __formatter - .write_str( - "There are too many consumers so the account cannot be created.", - ) - } - DispatchError::Token(_0) => { - __formatter - .write_fmt(format_args!("Token error: {0}", _0.as_display())) - } - DispatchError::Arithmetic(_0) => { - __formatter - .write_fmt( - format_args!("Arithmetic error: {0}", _0.as_display()), - ) - } - DispatchError::Transactional(_0) => { - __formatter - .write_fmt( - format_args!("Transactional error: {0}", _0.as_display()), - ) - } - DispatchError::Exhausted {} => { - __formatter - .write_str( - "Resources exhausted, e.g. attempt to read/write data which is too large to manipulate.", - ) - } - DispatchError::Corruption {} => { - __formatter - .write_str( - "The state is corrupt; this is generally not going to fix itself.", - ) - } - DispatchError::Unavailable {} => { - __formatter - .write_str( - "Some resource (e.g. a preimage) is unavailable right now. This might fix itself later.", - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DispatchError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DispatchError { - #[inline] - fn eq(&self, other: &DispatchError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - DispatchError::Module(__self_0), - DispatchError::Module(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - DispatchError::Token(__self_0), - DispatchError::Token(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - DispatchError::Arithmetic(__self_0), - DispatchError::Arithmetic(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - DispatchError::Transactional(__self_0), - DispatchError::Transactional(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DispatchError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - /// An error relating to tokens when dispatching a transaction. - #[non_exhaustive] - pub enum TokenError { - /// Funds are unavailable. - #[error("Funds are unavailable.")] - FundsUnavailable, - /// Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved. - #[error( - "Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved." - )] - OnlyProvider, - /// Account cannot exist with the funds that would be given. - #[error("Account cannot exist with the funds that would be given.")] - BelowMinimum, - /// Account cannot be created. - #[error("Account cannot be created.")] - CannotCreate, - /// The asset in question is unknown. - #[error("The asset in question is unknown.")] - UnknownAsset, - /// Funds exist but are frozen. - #[error("Funds exist but are frozen.")] - Frozen, - /// Operation is not supported by the asset. - #[error("Operation is not supported by the asset.")] - Unsupported, - /// Account cannot be created for a held balance. - #[error("Account cannot be created for a held balance.")] - CannotCreateHold, - /// Withdrawal would cause unwanted loss of account. - #[error("Withdrawal would cause unwanted loss of account.")] - NotExpendable, - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for TokenError { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = TokenError; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "FundsUnavailable" { - return Ok(TokenError::FundsUnavailable); - } - if value.name() == "OnlyProvider" { - return Ok(TokenError::OnlyProvider); - } - if value.name() == "BelowMinimum" { - return Ok(TokenError::BelowMinimum); - } - if value.name() == "CannotCreate" { - return Ok(TokenError::CannotCreate); - } - if value.name() == "UnknownAsset" { - return Ok(TokenError::UnknownAsset); - } - if value.name() == "Frozen" { - return Ok(TokenError::Frozen); - } - if value.name() == "Unsupported" { - return Ok(TokenError::Unsupported); - } - if value.name() == "CannotCreateHold" { - return Ok(TokenError::CannotCreateHold); - } - if value.name() == "NotExpendable" { - return Ok(TokenError::NotExpendable); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - "FundsUnavailable", - "OnlyProvider", - "BelowMinimum", - "CannotCreate", - "UnknownAsset", - "Frozen", - "Unsupported", - "CannotCreateHold", - "NotExpendable", - ]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for TokenError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - TokenError::FundsUnavailable => "FundsUnavailable", - TokenError::OnlyProvider => "OnlyProvider", - TokenError::BelowMinimum => "BelowMinimum", - TokenError::CannotCreate => "CannotCreate", - TokenError::UnknownAsset => "UnknownAsset", - TokenError::Frozen => "Frozen", - TokenError::Unsupported => "Unsupported", - TokenError::CannotCreateHold => "CannotCreateHold", - TokenError::NotExpendable => "NotExpendable", - }, - ) - } - } - #[allow(unused_qualifications)] - impl std::error::Error for TokenError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for TokenError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - TokenError::FundsUnavailable {} => { - __formatter.write_str("Funds are unavailable.") - } - TokenError::OnlyProvider {} => { - __formatter - .write_str( - "Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved.", - ) - } - TokenError::BelowMinimum {} => { - __formatter - .write_str( - "Account cannot exist with the funds that would be given.", - ) - } - TokenError::CannotCreate {} => { - __formatter.write_str("Account cannot be created.") - } - TokenError::UnknownAsset {} => { - __formatter.write_str("The asset in question is unknown.") - } - TokenError::Frozen {} => { - __formatter.write_str("Funds exist but are frozen.") - } - TokenError::Unsupported {} => { - __formatter.write_str("Operation is not supported by the asset.") - } - TokenError::CannotCreateHold {} => { - __formatter - .write_str("Account cannot be created for a held balance.") - } - TokenError::NotExpendable {} => { - __formatter - .write_str( - "Withdrawal would cause unwanted loss of account.", - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TokenError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TokenError { - #[inline] - fn eq(&self, other: &TokenError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TokenError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - /// An error relating to arithmetic when dispatching a transaction. - #[non_exhaustive] - pub enum ArithmeticError { - /// Underflow. - #[error("Underflow.")] - Underflow, - /// Overflow. - #[error("Overflow.")] - Overflow, - /// Division by zero. - #[error("Division by zero.")] - DivisionByZero, - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for ArithmeticError { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = ArithmeticError; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "Underflow" { - return Ok(ArithmeticError::Underflow); - } - if value.name() == "Overflow" { - return Ok(ArithmeticError::Overflow); - } - if value.name() == "DivisionByZero" { - return Ok(ArithmeticError::DivisionByZero); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - "Underflow", - "Overflow", - "DivisionByZero", - ]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for ArithmeticError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - ArithmeticError::Underflow => "Underflow", - ArithmeticError::Overflow => "Overflow", - ArithmeticError::DivisionByZero => "DivisionByZero", - }, - ) - } - } - #[allow(unused_qualifications)] - impl std::error::Error for ArithmeticError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for ArithmeticError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - ArithmeticError::Underflow {} => __formatter.write_str("Underflow."), - ArithmeticError::Overflow {} => __formatter.write_str("Overflow."), - ArithmeticError::DivisionByZero {} => { - __formatter.write_str("Division by zero.") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ArithmeticError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ArithmeticError { - #[inline] - fn eq(&self, other: &ArithmeticError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ArithmeticError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - /// An error relating to thr transactional layers when dispatching a transaction. - #[non_exhaustive] - pub enum TransactionalError { - /// Too many transactional layers have been spawned. - #[error("Too many transactional layers have been spawned.")] - LimitReached, - /// A transactional layer was expected, but does not exist. - #[error("A transactional layer was expected, but does not exist.")] - NoLayer, - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for TransactionalError { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = TransactionalError; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "LimitReached" { - return Ok(TransactionalError::LimitReached); - } - if value.name() == "NoLayer" { - return Ok(TransactionalError::NoLayer); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new(["LimitReached", "NoLayer"]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for TransactionalError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - TransactionalError::LimitReached => "LimitReached", - TransactionalError::NoLayer => "NoLayer", - }, - ) - } - } - #[allow(unused_qualifications)] - impl std::error::Error for TransactionalError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for TransactionalError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - TransactionalError::LimitReached {} => { - __formatter - .write_str( - "Too many transactional layers have been spawned.", - ) - } - TransactionalError::NoLayer {} => { - __formatter - .write_str( - "A transactional layer was expected, but does not exist.", - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionalError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionalError { - #[inline] - fn eq(&self, other: &TransactionalError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TransactionalError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - /// Details about a module error that has occurred. - #[non_exhaustive] - pub struct ModuleError { - metadata: Metadata, - /// Bytes representation: - /// - `bytes[0]`: pallet index - /// - `bytes[1]`: error index - /// - `bytes[2..]`: 3 bytes specific for the module error - bytes: [u8; 5], - } - #[automatically_derived] - impl ::core::clone::Clone for ModuleError { - #[inline] - fn clone(&self) -> ModuleError { - ModuleError { - metadata: ::core::clone::Clone::clone(&self.metadata), - bytes: ::core::clone::Clone::clone(&self.bytes), - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for ModuleError {} - impl PartialEq for ModuleError { - fn eq(&self, other: &Self) -> bool { - self.bytes == other.bytes - } - } - impl Eq for ModuleError {} - /// Custom `Debug` implementation, ignores the very large `metadata` field, using it instead (as - /// intended) to resolve the actual pallet and error names. This is much more useful for debugging. - impl Debug for ModuleError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let details = self.details_string(); - f.write_fmt(format_args!("ModuleError(<{0}>)", details)) - } - } - impl std::fmt::Display for ModuleError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let details = self.details_string(); - f.write_fmt(format_args!("{0}", details)) - } - } - impl ModuleError { - /// Return more details about this error. - pub fn details(&self) -> Result { - let pallet = self.metadata.pallet_by_index_err(self.pallet_index())?; - let variant = pallet - .error_variant_by_index(self.error_index()) - .ok_or_else(|| MetadataError::VariantIndexNotFound( - self.error_index(), - ))?; - Ok(ModuleErrorDetails { - pallet, - variant, - }) - } - /// Return a formatted string of the resolved error details for debugging/display purposes. - pub fn details_string(&self) -> String { - match self.details() { - Ok(details) => { - let res = ::alloc::fmt::format( - format_args!( - "{0}::{1}", details.pallet.name(), details.variant.name - ), - ); - res - } - Err(_) => { - let res = ::alloc::fmt::format( - format_args!( - "Unknown pallet error \'{0:?}\' (pallet and error details cannot be retrieved)", - self.bytes - ), - ); - res - } - } - } - /// Return the underlying module error data that was decoded. - pub fn bytes(&self) -> [u8; 5] { - self.bytes - } - /// Obtain the pallet index from the underlying byte data. - pub fn pallet_index(&self) -> u8 { - self.bytes[0] - } - /// Obtain the error index from the underlying byte data. - pub fn error_index(&self) -> u8 { - self.bytes[1] - } - /// Attempts to decode the ModuleError into the top outer Error enum. - pub fn as_root_error(&self) -> Result { - let decoded = E::decode_as_type( - &mut &self.bytes[..], - self.metadata.outer_enums().error_enum_ty(), - self.metadata.types(), - )?; - Ok(decoded) - } - } - /// Details about the module error. - pub struct ModuleErrorDetails<'a> { - /// The pallet that the error is in - pub pallet: crate::metadata::types::PalletMetadata<'a>, - /// The variant representing the error - pub variant: &'a scale_info::Variant, - } - impl DispatchError { - /// Attempt to decode a runtime [`DispatchError`]. - #[doc(hidden)] - pub fn decode_from<'a>( - bytes: impl Into>, - metadata: Metadata, - ) -> Result { - let bytes = bytes.into(); - let dispatch_error_ty_id = metadata - .dispatch_error_ty() - .ok_or(MetadataError::DispatchErrorNotFound)?; - enum DecodedDispatchError { - Other, - CannotLookup, - BadOrigin, - Module(DecodedModuleErrorBytes), - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Token(TokenError), - Arithmetic(ArithmeticError), - Transactional(TransactionalError), - Exhausted, - Corruption, - Unavailable, - } - const _: () = { - struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for DecodedDispatchError { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = DecodedDispatchError; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant< - 'scale, - 'info, - >, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "Other" { - return Ok(DecodedDispatchError::Other); - } - if value.name() == "CannotLookup" { - return Ok(DecodedDispatchError::CannotLookup); - } - if value.name() == "BadOrigin" { - return Ok(DecodedDispatchError::BadOrigin); - } - if value.name() == "Module" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - DecodedDispatchError::Module({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "ConsumerRemaining" { - return Ok(DecodedDispatchError::ConsumerRemaining); - } - if value.name() == "NoProviders" { - return Ok(DecodedDispatchError::NoProviders); - } - if value.name() == "TooManyConsumers" { - return Ok(DecodedDispatchError::TooManyConsumers); - } - if value.name() == "Token" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - DecodedDispatchError::Token({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Arithmetic" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - DecodedDispatchError::Arithmetic({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Transactional" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - DecodedDispatchError::Transactional({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Exhausted" { - return Ok(DecodedDispatchError::Exhausted); - } - if value.name() == "Corruption" { - return Ok(DecodedDispatchError::Corruption); - } - if value.name() == "Unavailable" { - return Ok(DecodedDispatchError::Unavailable); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - "Other", - "CannotLookup", - "BadOrigin", - "Module", - "ConsumerRemaining", - "NoProviders", - "TooManyConsumers", - "Token", - "Arithmetic", - "Transactional", - "Exhausted", - "Corruption", - "Unavailable", - ]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite< - 'scale, - 'info, - >, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple< - 'scale, - 'info, - >, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - struct DecodedModuleErrorBytes(Vec); - struct DecodedModuleErrorBytesVisitor; - impl scale_decode::Visitor for DecodedModuleErrorBytesVisitor { - type Error = scale_decode::Error; - type Value<'scale, 'info> = DecodedModuleErrorBytes; - fn unchecked_decode_as_type<'scale, 'info>( - self, - input: &mut &'scale [u8], - _type_id: scale_decode::visitor::TypeId, - _types: &'info scale_info::PortableRegistry, - ) -> DecodeAsTypeResult< - Self, - Result, Self::Error>, - > { - DecodeAsTypeResult::Decoded( - Ok(DecodedModuleErrorBytes(input.to_vec())), - ) - } - } - impl scale_decode::IntoVisitor for DecodedModuleErrorBytes { - type Visitor = DecodedModuleErrorBytesVisitor; - fn into_visitor() -> Self::Visitor { - DecodedModuleErrorBytesVisitor - } - } - let decoded_dispatch_err = DecodedDispatchError::decode_with_metadata( - &mut &*bytes, - dispatch_error_ty_id, - &metadata, - )?; - let dispatch_error = match decoded_dispatch_err { - DecodedDispatchError::Other => DispatchError::Other, - DecodedDispatchError::CannotLookup => DispatchError::CannotLookup, - DecodedDispatchError::BadOrigin => DispatchError::BadOrigin, - DecodedDispatchError::ConsumerRemaining => { - DispatchError::ConsumerRemaining - } - DecodedDispatchError::NoProviders => DispatchError::NoProviders, - DecodedDispatchError::TooManyConsumers => { - DispatchError::TooManyConsumers - } - DecodedDispatchError::Token(val) => DispatchError::Token(val), - DecodedDispatchError::Arithmetic(val) => { - DispatchError::Arithmetic(val) - } - DecodedDispatchError::Transactional(val) => { - DispatchError::Transactional(val) - } - DecodedDispatchError::Exhausted => DispatchError::Exhausted, - DecodedDispatchError::Corruption => DispatchError::Corruption, - DecodedDispatchError::Unavailable => DispatchError::Unavailable, - DecodedDispatchError::Module(module_bytes) => { - let module_bytes = module_bytes.0; - let bytes = if module_bytes.len() == 2 { - [module_bytes[0], module_bytes[1], 0, 0, 0] - } else if module_bytes.len() == 5 { - [ - module_bytes[0], - module_bytes[1], - module_bytes[2], - module_bytes[3], - module_bytes[4], - ] - } else { - { - use ::tracing::__macro_support::Callsite as _; - static __CALLSITE: ::tracing::callsite::DefaultCallsite = { - static META: ::tracing::Metadata<'static> = { - ::tracing_core::metadata::Metadata::new( - "event subxt/src/error/dispatch_error.rs:318", - "subxt::error::dispatch_error", - ::tracing::Level::WARN, - ::core::option::Option::Some( - "subxt/src/error/dispatch_error.rs", - ), - ::core::option::Option::Some(318u32), - ::core::option::Option::Some( - "subxt::error::dispatch_error", - ), - ::tracing_core::field::FieldSet::new( - &["message"], - ::tracing_core::callsite::Identifier(&__CALLSITE), - ), - ::tracing::metadata::Kind::EVENT, - ) - }; - ::tracing::callsite::DefaultCallsite::new(&META) - }; - let enabled = ::tracing::Level::WARN - <= ::tracing::level_filters::STATIC_MAX_LEVEL - && ::tracing::Level::WARN - <= ::tracing::level_filters::LevelFilter::current() - && { - let interest = __CALLSITE.interest(); - !interest.is_never() - && ::tracing::__macro_support::__is_enabled( - __CALLSITE.metadata(), - interest, - ) - }; - if enabled { - (|value_set: ::tracing::field::ValueSet| { - let meta = __CALLSITE.metadata(); - ::tracing::Event::dispatch(meta, &value_set); - })({ - #[allow(unused_imports)] - use ::tracing::field::{debug, display, Value}; - let mut iter = __CALLSITE.metadata().fields().iter(); - __CALLSITE - .metadata() - .fields() - .value_set( - &[ - ( - &::core::iter::Iterator::next(&mut iter) - .expect("FieldSet corrupted (this is a bug)"), - ::core::option::Option::Some( - &format_args!( - "Can\'t decode error sp_runtime::DispatchError: bytes do not match known shapes" - ) as &dyn Value, - ), - ), - ], - ) - }); - } else { - } - }; - return Err(super::Error::Unknown(bytes.to_vec())); - }; - DispatchError::Module(ModuleError { metadata, bytes }) - } - }; - Ok(dispatch_error) - } - } - } - pub use dispatch_error::{ - ArithmeticError, DispatchError, ModuleError, TokenError, TransactionalError, - }; - use subxt_metadata::StorageHasher; - pub use crate::config::ExtrinsicParamsError; - pub use crate::metadata::Metadata; - pub use scale_decode::Error as DecodeError; - pub use scale_encode::Error as EncodeError; - pub use subxt_metadata::TryFromError as MetadataTryFromError; - /// The underlying error enum, generic over the type held by the `Runtime` - /// variant. Prefer to use the [`Error`] and [`Error`] aliases over - /// using this type directly. - #[non_exhaustive] - pub enum Error { - /// Io error. - #[error("Io error: {0}")] - Io(#[from] std::io::Error), - /// Codec error. - #[error("Scale codec error: {0}")] - Codec(#[from] codec::Error), - /// Rpc error. - #[error("Rpc error: {0}")] - Rpc(#[from] RpcError), - /// Serde serialization error - #[error("Serde json error: {0}")] - Serialization(#[from] serde_json::error::Error), - /// Error working with metadata. - #[error("Metadata error: {0}")] - Metadata(#[from] MetadataError), - /// Error decoding metadata. - #[error("Metadata Decoding error: {0}")] - MetadataDecoding(#[from] MetadataTryFromError), - /// Runtime error. - #[error("Runtime error: {0}")] - Runtime(#[from] DispatchError), - /// Error decoding to a [`crate::dynamic::Value`]. - #[error("Error decoding into dynamic value: {0}")] - Decode(#[from] DecodeError), - /// Error encoding from a [`crate::dynamic::Value`]. - #[error("Error encoding from dynamic value: {0}")] - Encode(#[from] EncodeError), - /// Transaction progress error. - #[error("Transaction error: {0}")] - Transaction(#[from] TransactionError), - /// Error constructing the appropriate extrinsic params. - #[error("Extrinsic params error: {0}")] - ExtrinsicParams(#[from] ExtrinsicParamsError), - /// Block related error. - #[error("Block error: {0}")] - Block(#[from] BlockError), - /// An error encoding a storage address. - #[error("Error encoding storage address: {0}")] - StorageAddress(#[from] StorageAddressError), - /// The bytes representing an error that we were unable to decode. - #[error("An error occurred but it could not be decoded: {0:?}")] - Unknown(Vec), - /// Other error. - #[error("Other error: {0}")] - Other(String), - } - #[automatically_derived] - impl ::core::fmt::Debug for Error { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - Error::Io(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Io", &__self_0) - } - Error::Codec(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Codec", - &__self_0, - ) - } - Error::Rpc(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Rpc", - &__self_0, - ) - } - Error::Serialization(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Serialization", - &__self_0, - ) - } - Error::Metadata(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Metadata", - &__self_0, - ) - } - Error::MetadataDecoding(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "MetadataDecoding", - &__self_0, - ) - } - Error::Runtime(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Runtime", - &__self_0, - ) - } - Error::Decode(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Decode", - &__self_0, - ) - } - Error::Encode(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Encode", - &__self_0, - ) - } - Error::Transaction(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Transaction", - &__self_0, - ) - } - Error::ExtrinsicParams(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ExtrinsicParams", - &__self_0, - ) - } - Error::Block(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Block", - &__self_0, - ) - } - Error::StorageAddress(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "StorageAddress", - &__self_0, - ) - } - Error::Unknown(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Unknown", - &__self_0, - ) - } - Error::Other(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Other", - &__self_0, - ) - } - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for Error { - fn source(&self) -> ::core::option::Option<&(dyn std::error::Error + 'static)> { - use thiserror::__private::AsDynError as _; - #[allow(deprecated)] - match self { - Error::Io { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Codec { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Rpc { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Serialization { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Metadata { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::MetadataDecoding { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Runtime { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Decode { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Encode { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Transaction { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::ExtrinsicParams { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Block { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::StorageAddress { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Unknown { .. } => ::core::option::Option::None, - Error::Other { .. } => ::core::option::Option::None, - } - } - } - #[allow(unused_qualifications)] - impl ::core::fmt::Display for Error { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - Error::Io(_0) => { - __formatter.write_fmt(format_args!("Io error: {0}", _0.as_display())) - } - Error::Codec(_0) => { - __formatter - .write_fmt( - format_args!("Scale codec error: {0}", _0.as_display()), - ) - } - Error::Rpc(_0) => { - __formatter - .write_fmt(format_args!("Rpc error: {0}", _0.as_display())) - } - Error::Serialization(_0) => { - __formatter - .write_fmt( - format_args!("Serde json error: {0}", _0.as_display()), - ) - } - Error::Metadata(_0) => { - __formatter - .write_fmt(format_args!("Metadata error: {0}", _0.as_display())) - } - Error::MetadataDecoding(_0) => { - __formatter - .write_fmt( - format_args!("Metadata Decoding error: {0}", _0.as_display()), - ) - } - Error::Runtime(_0) => { - __formatter - .write_fmt(format_args!("Runtime error: {0}", _0.as_display())) - } - Error::Decode(_0) => { - __formatter - .write_fmt( - format_args!( - "Error decoding into dynamic value: {0}", _0.as_display() - ), - ) - } - Error::Encode(_0) => { - __formatter - .write_fmt( - format_args!( - "Error encoding from dynamic value: {0}", _0.as_display() - ), - ) - } - Error::Transaction(_0) => { - __formatter - .write_fmt( - format_args!("Transaction error: {0}", _0.as_display()), - ) - } - Error::ExtrinsicParams(_0) => { - __formatter - .write_fmt( - format_args!("Extrinsic params error: {0}", _0.as_display()), - ) - } - Error::Block(_0) => { - __formatter - .write_fmt(format_args!("Block error: {0}", _0.as_display())) - } - Error::StorageAddress(_0) => { - __formatter - .write_fmt( - format_args!( - "Error encoding storage address: {0}", _0.as_display() - ), - ) - } - Error::Unknown(_0) => { - __formatter - .write_fmt( - format_args!( - "An error occurred but it could not be decoded: {0:?}", _0 - ), - ) - } - Error::Other(_0) => { - __formatter - .write_fmt(format_args!("Other error: {0}", _0.as_display())) - } - } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: std::io::Error) -> Self { - Error::Io { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: codec::Error) -> Self { - Error::Codec { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: RpcError) -> Self { - Error::Rpc { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: serde_json::error::Error) -> Self { - Error::Serialization { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: MetadataError) -> Self { - Error::Metadata { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: MetadataTryFromError) -> Self { - Error::MetadataDecoding { - 0: source, - } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: DispatchError) -> Self { - Error::Runtime { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: DecodeError) -> Self { - Error::Decode { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: EncodeError) -> Self { - Error::Encode { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: TransactionError) -> Self { - Error::Transaction { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: ExtrinsicParamsError) -> Self { - Error::ExtrinsicParams { - 0: source, - } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: BlockError) -> Self { - Error::Block { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: StorageAddressError) -> Self { - Error::StorageAddress { 0: source } - } - } - impl<'a> From<&'a str> for Error { - fn from(error: &'a str) -> Self { - Error::Other(error.into()) - } - } - impl From for Error { - fn from(error: String) -> Self { - Error::Other(error) - } - } - impl From for Error { - fn from(value: std::convert::Infallible) -> Self { - match value {} - } - } - impl Error { - /// Checks whether the error was caused by a RPC re-connection. - pub fn is_disconnected_will_reconnect(&self) -> bool { - match self { - Error::Rpc(RpcError::DisconnectedWillReconnect(_)) => true, - _ => false, - } - } - } - /// An RPC error. Since we are generic over the RPC client that is used, - /// the error is boxed and could be casted. - #[non_exhaustive] - pub enum RpcError { - /// Error related to the RPC client. - #[error("RPC error: {0}")] - ClientError(Box), - /// This error signals that the request was rejected for some reason. - /// The specific reason is provided. - #[error("RPC error: request rejected: {0}")] - RequestRejected(String), - /// The RPC subscription dropped. - #[error("RPC error: subscription dropped.")] - SubscriptionDropped, - /// The requested URL is insecure. - #[error("RPC error: insecure URL: {0}")] - InsecureUrl(String), - /// The connection was lost and automatically reconnected. - #[error( - "RPC error: the connection was lost `{0}`; reconnect automatically initiated" - )] - DisconnectedWillReconnect(String), - } - #[automatically_derived] - impl ::core::fmt::Debug for RpcError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - RpcError::ClientError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ClientError", - &__self_0, - ) - } - RpcError::RequestRejected(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "RequestRejected", - &__self_0, - ) - } - RpcError::SubscriptionDropped => { - ::core::fmt::Formatter::write_str(f, "SubscriptionDropped") - } - RpcError::InsecureUrl(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InsecureUrl", - &__self_0, - ) - } - RpcError::DisconnectedWillReconnect(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "DisconnectedWillReconnect", - &__self_0, - ) - } - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for RpcError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for RpcError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - RpcError::ClientError(_0) => { - __formatter - .write_fmt(format_args!("RPC error: {0}", _0.as_display())) - } - RpcError::RequestRejected(_0) => { - __formatter - .write_fmt( - format_args!( - "RPC error: request rejected: {0}", _0.as_display() - ), - ) - } - RpcError::SubscriptionDropped {} => { - __formatter.write_str("RPC error: subscription dropped.") - } - RpcError::InsecureUrl(_0) => { - __formatter - .write_fmt( - format_args!("RPC error: insecure URL: {0}", _0.as_display()), - ) - } - RpcError::DisconnectedWillReconnect(_0) => { - __formatter - .write_fmt( - format_args!( - "RPC error: the connection was lost `{0}`; reconnect automatically initiated", - _0.as_display() - ), - ) - } - } - } - } - impl RpcError { - /// Create a `RequestRejected` error from anything that can be turned into a string. - pub fn request_rejected>(s: S) -> RpcError { - RpcError::RequestRejected(s.into()) - } - } - /// Block error - #[non_exhaustive] - pub enum BlockError { - /// An error containing the hash of the block that was not found. - #[error( - "Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)" - )] - NotFound(String), - /// Extrinsic type ID cannot be resolved with the provided metadata. - #[error( - "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata" - )] - MissingType, - /// Unsupported signature. - #[error("Unsupported extrinsic version, only version 4 is supported currently")] - /// The extrinsic has an unsupported version. - UnsupportedVersion(u8), - /// Decoding error. - #[error("Cannot decode extrinsic: {0}")] - DecodingError(codec::Error), - } - #[automatically_derived] - impl ::core::clone::Clone for BlockError { - #[inline] - fn clone(&self) -> BlockError { - match self { - BlockError::NotFound(__self_0) => { - BlockError::NotFound(::core::clone::Clone::clone(__self_0)) - } - BlockError::MissingType => BlockError::MissingType, - BlockError::UnsupportedVersion(__self_0) => { - BlockError::UnsupportedVersion(::core::clone::Clone::clone(__self_0)) - } - BlockError::DecodingError(__self_0) => { - BlockError::DecodingError(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for BlockError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - BlockError::NotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "NotFound", - &__self_0, - ) - } - BlockError::MissingType => { - ::core::fmt::Formatter::write_str(f, "MissingType") - } - BlockError::UnsupportedVersion(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "UnsupportedVersion", - &__self_0, - ) - } - BlockError::DecodingError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "DecodingError", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for BlockError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[allow(unused_qualifications)] - impl std::error::Error for BlockError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for BlockError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - BlockError::NotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)", - _0.as_display() - ), - ) - } - BlockError::MissingType {} => { - __formatter - .write_str( - "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata", - ) - } - BlockError::UnsupportedVersion(_0) => { - __formatter - .write_str( - "Unsupported extrinsic version, only version 4 is supported currently", - ) - } - BlockError::DecodingError(_0) => { - __formatter - .write_fmt( - format_args!("Cannot decode extrinsic: {0}", _0.as_display()), - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BlockError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for BlockError { - #[inline] - fn eq(&self, other: &BlockError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - (BlockError::NotFound(__self_0), BlockError::NotFound(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - ( - BlockError::UnsupportedVersion(__self_0), - BlockError::UnsupportedVersion(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - BlockError::DecodingError(__self_0), - BlockError::DecodingError(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - impl BlockError { - /// Produce an error that a block with the given hash cannot be found. - pub fn not_found(hash: impl AsRef<[u8]>) -> BlockError { - let hash = { - let res = ::alloc::fmt::format(format_args!("0x{0}", hex::encode(hash))); - res - }; - BlockError::NotFound(hash) - } - } - /// Transaction error. - #[non_exhaustive] - pub enum TransactionError { - /// The block hash that the transaction was added to could not be found. - /// This is probably because the block was retracted before being finalized. - #[error( - "The block containing the transaction can no longer be found (perhaps it was on a non-finalized fork?)" - )] - BlockNotFound, - /// An error happened on the node that the transaction was submitted to. - #[error("Error handling transaction: {0}")] - Error(String), - /// The transaction was deemed invalid. - #[error("The transaction is not valid: {0}")] - Invalid(String), - /// The transaction was dropped. - #[error("The transaction was dropped: {0}")] - Dropped(String), - } - #[automatically_derived] - impl ::core::clone::Clone for TransactionError { - #[inline] - fn clone(&self) -> TransactionError { - match self { - TransactionError::BlockNotFound => TransactionError::BlockNotFound, - TransactionError::Error(__self_0) => { - TransactionError::Error(::core::clone::Clone::clone(__self_0)) - } - TransactionError::Invalid(__self_0) => { - TransactionError::Invalid(::core::clone::Clone::clone(__self_0)) - } - TransactionError::Dropped(__self_0) => { - TransactionError::Dropped(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionError::BlockNotFound => { - ::core::fmt::Formatter::write_str(f, "BlockNotFound") - } - TransactionError::Error(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Error", - &__self_0, - ) - } - TransactionError::Invalid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Invalid", - &__self_0, - ) - } - TransactionError::Dropped(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Dropped", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TransactionError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[allow(unused_qualifications)] - impl std::error::Error for TransactionError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for TransactionError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - TransactionError::BlockNotFound {} => { - __formatter - .write_str( - "The block containing the transaction can no longer be found (perhaps it was on a non-finalized fork?)", - ) - } - TransactionError::Error(_0) => { - __formatter - .write_fmt( - format_args!( - "Error handling transaction: {0}", _0.as_display() - ), - ) - } - TransactionError::Invalid(_0) => { - __formatter - .write_fmt( - format_args!( - "The transaction is not valid: {0}", _0.as_display() - ), - ) - } - TransactionError::Dropped(_0) => { - __formatter - .write_fmt( - format_args!( - "The transaction was dropped: {0}", _0.as_display() - ), - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionError { - #[inline] - fn eq(&self, other: &TransactionError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionError::Error(__self_0), - TransactionError::Error(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - TransactionError::Invalid(__self_0), - TransactionError::Invalid(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - TransactionError::Dropped(__self_0), - TransactionError::Dropped(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - /// Something went wrong trying to encode a storage address. - #[non_exhaustive] - pub enum StorageAddressError { - /// Storage map type must be a composite type. - #[error("Storage map type must be a composite type")] - MapTypeMustBeTuple, - /// Storage lookup does not have the expected number of keys. - #[error("Storage lookup requires {expected} keys but got {actual} keys")] - WrongNumberOfKeys { - /// The actual number of keys needed, based on the metadata. - actual: usize, - /// The number of keys provided in the storage address. - expected: usize, - }, - /// This storage entry in the metadata does not have the correct number of hashers to fields. - #[error( - "Storage entry in metadata does not have the correct number of hashers to fields" - )] - WrongNumberOfHashers { - /// The number of hashers in the metadata for this storage entry. - hashers: usize, - /// The number of fields in the metadata for this storage entry. - fields: usize, - }, - /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. - #[error( - "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata." - )] - UnexpectedAddressBytes, - /// An invalid hasher was used to reconstruct a value from a chunk of bytes that is part of a storage address. Hashers where the hash does not contain the original value are invalid for this purpose. - #[error( - "An invalid hasher was used to reconstruct a value of type {ty_name} (id={ty_id}) from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher" - )] - HasherCannotReconstructKey { - /// Type id of the key's type. - ty_id: u32, - /// Type name of the key's type. - ty_name: String, - /// The invalid hasher that caused this error. - hasher: StorageHasher, - }, - } - #[automatically_derived] - impl ::core::clone::Clone for StorageAddressError { - #[inline] - fn clone(&self) -> StorageAddressError { - match self { - StorageAddressError::MapTypeMustBeTuple => { - StorageAddressError::MapTypeMustBeTuple - } - StorageAddressError::WrongNumberOfKeys { - actual: __self_0, - expected: __self_1, - } => { - StorageAddressError::WrongNumberOfKeys { - actual: ::core::clone::Clone::clone(__self_0), - expected: ::core::clone::Clone::clone(__self_1), - } - } - StorageAddressError::WrongNumberOfHashers { - hashers: __self_0, - fields: __self_1, - } => { - StorageAddressError::WrongNumberOfHashers { - hashers: ::core::clone::Clone::clone(__self_0), - fields: ::core::clone::Clone::clone(__self_1), - } - } - StorageAddressError::UnexpectedAddressBytes => { - StorageAddressError::UnexpectedAddressBytes - } - StorageAddressError::HasherCannotReconstructKey { - ty_id: __self_0, - ty_name: __self_1, - hasher: __self_2, - } => { - StorageAddressError::HasherCannotReconstructKey { - ty_id: ::core::clone::Clone::clone(__self_0), - ty_name: ::core::clone::Clone::clone(__self_1), - hasher: ::core::clone::Clone::clone(__self_2), - } - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageAddressError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - StorageAddressError::MapTypeMustBeTuple => { - ::core::fmt::Formatter::write_str(f, "MapTypeMustBeTuple") - } - StorageAddressError::WrongNumberOfKeys { - actual: __self_0, - expected: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "WrongNumberOfKeys", - "actual", - __self_0, - "expected", - &__self_1, - ) - } - StorageAddressError::WrongNumberOfHashers { - hashers: __self_0, - fields: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "WrongNumberOfHashers", - "hashers", - __self_0, - "fields", - &__self_1, - ) - } - StorageAddressError::UnexpectedAddressBytes => { - ::core::fmt::Formatter::write_str(f, "UnexpectedAddressBytes") - } - StorageAddressError::HasherCannotReconstructKey { - ty_id: __self_0, - ty_name: __self_1, - hasher: __self_2, - } => { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "HasherCannotReconstructKey", - "ty_id", - __self_0, - "ty_name", - __self_1, - "hasher", - &__self_2, - ) - } - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for StorageAddressError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for StorageAddressError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - StorageAddressError::MapTypeMustBeTuple {} => { - __formatter.write_str("Storage map type must be a composite type") - } - StorageAddressError::WrongNumberOfKeys { actual, expected } => { - __formatter - .write_fmt( - format_args!( - "Storage lookup requires {0} keys but got {1} keys", - expected.as_display(), actual.as_display() - ), - ) - } - StorageAddressError::WrongNumberOfHashers { hashers, fields } => { - __formatter - .write_str( - "Storage entry in metadata does not have the correct number of hashers to fields", - ) - } - StorageAddressError::UnexpectedAddressBytes {} => { - __formatter - .write_str( - "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata.", - ) - } - StorageAddressError::HasherCannotReconstructKey { - ty_id, - ty_name, - hasher, - } => { - __formatter - .write_fmt( - format_args!( - "An invalid hasher was used to reconstruct a value of type {0} (id={1}) from a hash formed by a {2:?} hasher. This is only possible for concat-style hashers or the identity hasher", - ty_name.as_display(), ty_id.as_display(), hasher - ), - ) - } - } - } - } - /// Something went wrong trying to access details in the metadata. - #[non_exhaustive] - pub enum MetadataError { - /// The DispatchError type isn't available in the metadata - #[error("The DispatchError type isn't available")] - DispatchErrorNotFound, - /// Type not found in metadata. - #[error("Type with ID {0} not found")] - TypeNotFound(u32), - /// Pallet not found (index). - #[error("Pallet with index {0} not found")] - PalletIndexNotFound(u8), - /// Pallet not found (name). - #[error("Pallet with name {0} not found")] - PalletNameNotFound(String), - /// Variant not found. - #[error("Variant with index {0} not found")] - VariantIndexNotFound(u8), - /// Constant not found. - #[error("Constant with name {0} not found")] - ConstantNameNotFound(String), - /// Call not found. - #[error("Call with name {0} not found")] - CallNameNotFound(String), - /// Runtime trait not found. - #[error("Runtime trait with name {0} not found")] - RuntimeTraitNotFound(String), - /// Runtime method not found. - #[error("Runtime method with name {0} not found")] - RuntimeMethodNotFound(String), - /// Call type not found in metadata. - #[error("Call type not found in pallet with index {0}")] - CallTypeNotFoundInPallet(u8), - /// Event type not found in metadata. - #[error("Event type not found in pallet with index {0}")] - EventTypeNotFoundInPallet(u8), - /// Storage details not found in metadata. - #[error("Storage details not found in pallet with name {0}")] - StorageNotFoundInPallet(String), - /// Storage entry not found. - #[error("Storage entry {0} not found")] - StorageEntryNotFound(String), - /// The generated interface used is not compatible with the node. - #[error("The generated code is not compatible with the node")] - IncompatibleCodegen, - /// Custom value not found. - #[error("Custom value with name {0} not found")] - CustomValueNameNotFound(String), - } - #[automatically_derived] - impl ::core::clone::Clone for MetadataError { - #[inline] - fn clone(&self) -> MetadataError { - match self { - MetadataError::DispatchErrorNotFound => { - MetadataError::DispatchErrorNotFound - } - MetadataError::TypeNotFound(__self_0) => { - MetadataError::TypeNotFound(::core::clone::Clone::clone(__self_0)) - } - MetadataError::PalletIndexNotFound(__self_0) => { - MetadataError::PalletIndexNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::PalletNameNotFound(__self_0) => { - MetadataError::PalletNameNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::VariantIndexNotFound(__self_0) => { - MetadataError::VariantIndexNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::ConstantNameNotFound(__self_0) => { - MetadataError::ConstantNameNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::CallNameNotFound(__self_0) => { - MetadataError::CallNameNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::RuntimeTraitNotFound(__self_0) => { - MetadataError::RuntimeTraitNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::RuntimeMethodNotFound(__self_0) => { - MetadataError::RuntimeMethodNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::CallTypeNotFoundInPallet(__self_0) => { - MetadataError::CallTypeNotFoundInPallet( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::EventTypeNotFoundInPallet(__self_0) => { - MetadataError::EventTypeNotFoundInPallet( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::StorageNotFoundInPallet(__self_0) => { - MetadataError::StorageNotFoundInPallet( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::StorageEntryNotFound(__self_0) => { - MetadataError::StorageEntryNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::IncompatibleCodegen => MetadataError::IncompatibleCodegen, - MetadataError::CustomValueNameNotFound(__self_0) => { - MetadataError::CustomValueNameNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for MetadataError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - MetadataError::DispatchErrorNotFound => { - ::core::fmt::Formatter::write_str(f, "DispatchErrorNotFound") - } - MetadataError::TypeNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "TypeNotFound", - &__self_0, - ) - } - MetadataError::PalletIndexNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "PalletIndexNotFound", - &__self_0, - ) - } - MetadataError::PalletNameNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "PalletNameNotFound", - &__self_0, - ) - } - MetadataError::VariantIndexNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "VariantIndexNotFound", - &__self_0, - ) - } - MetadataError::ConstantNameNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ConstantNameNotFound", - &__self_0, - ) - } - MetadataError::CallNameNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "CallNameNotFound", - &__self_0, - ) - } - MetadataError::RuntimeTraitNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "RuntimeTraitNotFound", - &__self_0, - ) - } - MetadataError::RuntimeMethodNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "RuntimeMethodNotFound", - &__self_0, - ) - } - MetadataError::CallTypeNotFoundInPallet(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "CallTypeNotFoundInPallet", - &__self_0, - ) - } - MetadataError::EventTypeNotFoundInPallet(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "EventTypeNotFoundInPallet", - &__self_0, - ) - } - MetadataError::StorageNotFoundInPallet(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "StorageNotFoundInPallet", - &__self_0, - ) - } - MetadataError::StorageEntryNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "StorageEntryNotFound", - &__self_0, - ) - } - MetadataError::IncompatibleCodegen => { - ::core::fmt::Formatter::write_str(f, "IncompatibleCodegen") - } - MetadataError::CustomValueNameNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "CustomValueNameNotFound", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for MetadataError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for MetadataError { - #[inline] - fn eq(&self, other: &MetadataError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - MetadataError::TypeNotFound(__self_0), - MetadataError::TypeNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::PalletIndexNotFound(__self_0), - MetadataError::PalletIndexNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::PalletNameNotFound(__self_0), - MetadataError::PalletNameNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::VariantIndexNotFound(__self_0), - MetadataError::VariantIndexNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::ConstantNameNotFound(__self_0), - MetadataError::ConstantNameNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::CallNameNotFound(__self_0), - MetadataError::CallNameNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::RuntimeTraitNotFound(__self_0), - MetadataError::RuntimeTraitNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::RuntimeMethodNotFound(__self_0), - MetadataError::RuntimeMethodNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::CallTypeNotFoundInPallet(__self_0), - MetadataError::CallTypeNotFoundInPallet(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::EventTypeNotFoundInPallet(__self_0), - MetadataError::EventTypeNotFoundInPallet(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::StorageNotFoundInPallet(__self_0), - MetadataError::StorageNotFoundInPallet(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::StorageEntryNotFound(__self_0), - MetadataError::StorageEntryNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::CustomValueNameNotFound(__self_0), - MetadataError::CustomValueNameNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for MetadataError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for MetadataError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - MetadataError::DispatchErrorNotFound {} => { - __formatter.write_str("The DispatchError type isn't available") - } - MetadataError::TypeNotFound(_0) => { - __formatter - .write_fmt( - format_args!("Type with ID {0} not found", _0.as_display()), - ) - } - MetadataError::PalletIndexNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Pallet with index {0} not found", _0.as_display() - ), - ) - } - MetadataError::PalletNameNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Pallet with name {0} not found", _0.as_display() - ), - ) - } - MetadataError::VariantIndexNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Variant with index {0} not found", _0.as_display() - ), - ) - } - MetadataError::ConstantNameNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Constant with name {0} not found", _0.as_display() - ), - ) - } - MetadataError::CallNameNotFound(_0) => { - __formatter - .write_fmt( - format_args!("Call with name {0} not found", _0.as_display()), - ) - } - MetadataError::RuntimeTraitNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Runtime trait with name {0} not found", _0.as_display() - ), - ) - } - MetadataError::RuntimeMethodNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Runtime method with name {0} not found", _0.as_display() - ), - ) - } - MetadataError::CallTypeNotFoundInPallet(_0) => { - __formatter - .write_fmt( - format_args!( - "Call type not found in pallet with index {0}", _0 - .as_display() - ), - ) - } - MetadataError::EventTypeNotFoundInPallet(_0) => { - __formatter - .write_fmt( - format_args!( - "Event type not found in pallet with index {0}", _0 - .as_display() - ), - ) - } - MetadataError::StorageNotFoundInPallet(_0) => { - __formatter - .write_fmt( - format_args!( - "Storage details not found in pallet with name {0}", _0 - .as_display() - ), - ) - } - MetadataError::StorageEntryNotFound(_0) => { - __formatter - .write_fmt( - format_args!("Storage entry {0} not found", _0.as_display()), - ) - } - MetadataError::IncompatibleCodegen {} => { - __formatter - .write_str("The generated code is not compatible with the node") - } - MetadataError::CustomValueNameNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Custom value with name {0} not found", _0.as_display() - ), - ) - } - } - } - } -} -pub mod events { - //! This module exposes the types and such necessary for working with events. - //! The two main entry points into events are [`crate::OnlineClient::events()`] - //! and calls like [crate::tx::TxProgress::wait_for_finalized_success()]. - mod events_client { - use crate::backend::{Backend, BackendExt, BlockRef}; - use crate::{client::OnlineClientT, error::Error, events::Events, Config}; - use derivative::Derivative; - use std::future::Future; - /// A client for working with events. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct EventsClient { - client: Client, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for EventsClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - EventsClient { client: ref __arg_0, _marker: ref __arg_1 } => { - EventsClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl EventsClient { - /// Create a new [`EventsClient`]. - pub fn new(client: Client) -> Self { - Self { - client, - _marker: std::marker::PhantomData, - } - } - } - impl EventsClient - where - T: Config, - Client: OnlineClientT, - { - /// Obtain events at some block hash. - /// - /// # Warning - /// - /// This call only supports blocks produced since the most recent - /// runtime upgrade. You can attempt to retrieve events from older blocks, - /// but may run into errors attempting to work with them. - pub fn at( - &self, - block_ref: impl Into>, - ) -> impl Future, Error>> + Send + 'static { - self.at_or_latest(Some(block_ref.into())) - } - /// Obtain events for the latest block. - pub fn at_latest( - &self, - ) -> impl Future, Error>> + Send + 'static { - self.at_or_latest(None) - } - /// Obtain events at some block hash. - fn at_or_latest( - &self, - block_ref: Option>, - ) -> impl Future, Error>> + Send + 'static { - let client = self.client.clone(); - async move { - let block_ref = match block_ref { - Some(r) => r, - None => client.backend().latest_finalized_block_ref().await?, - }; - let event_bytes = get_event_bytes(client.backend(), block_ref.hash()) - .await?; - Ok(Events::new(client.metadata(), block_ref.hash(), event_bytes)) - } - } - } - fn system_events_key() -> [u8; 32] { - let a = sp_core_hashing::twox_128(b"System"); - let b = sp_core_hashing::twox_128(b"Events"); - let mut res = [0; 32]; - res[0..16].clone_from_slice(&a); - res[16..32].clone_from_slice(&b); - res - } - pub(crate) async fn get_event_bytes( - backend: &dyn Backend, - block_hash: T::Hash, - ) -> Result, Error> { - Ok( - backend - .storage_fetch_value(system_events_key().to_vec(), block_hash) - .await? - .unwrap_or_default(), - ) - } - } - mod events_type { - //! A representation of a block of events. - use super::{Phase, StaticEvent}; - use crate::{ - client::OnlineClientT, error::{Error, MetadataError}, - events::events_client::get_event_bytes, metadata::types::PalletMetadata, - Config, Metadata, - }; - use codec::{Compact, Decode}; - use derivative::Derivative; - use scale_decode::DecodeAsType; - use std::sync::Arc; - /// A collection of events obtained from a block, bundled with the necessary - /// information needed to decode and iterate over them. - #[derivative(Clone(bound = ""))] - pub struct Events { - metadata: Metadata, - block_hash: T::Hash, - event_bytes: Arc<[u8]>, - start_idx: usize, - num_events: u32, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Events { - fn clone(&self) -> Self { - match *self { - Events { - metadata: ref __arg_0, - block_hash: ref __arg_1, - event_bytes: ref __arg_2, - start_idx: ref __arg_3, - num_events: ref __arg_4, - } => { - Events { - metadata: (*__arg_0).clone(), - block_hash: (*__arg_1).clone(), - event_bytes: (*__arg_2).clone(), - start_idx: (*__arg_3).clone(), - num_events: (*__arg_4).clone(), - } - } - } - } - } - impl std::fmt::Debug for Events { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Events") - .field("block_hash", &self.block_hash) - .field("event_bytes", &self.event_bytes) - .field("start_idx", &self.start_idx) - .field("num_events", &self.num_events) - .finish() - } - } - impl Events { - pub(crate) fn new( - metadata: Metadata, - block_hash: T::Hash, - event_bytes: Vec, - ) -> Self { - let cursor = &mut &*event_bytes; - let num_events = >::decode(cursor).unwrap_or(Compact(0)).0; - let start_idx = event_bytes.len() - cursor.len(); - Self { - metadata, - block_hash, - event_bytes: event_bytes.into(), - start_idx, - num_events, - } - } - /// Obtain the events from a block hash given custom metadata and a client. - /// - /// # Notes - /// - /// - Prefer to use [`crate::events::EventsClient::at`] to obtain the events. - /// - Subxt may fail to decode things that aren't from a runtime using the - /// latest metadata version. - /// - The client may not be able to obtain the block at the given hash. Only - /// archive nodes keep hold of all past block information. - pub async fn new_from_client( - metadata: Metadata, - block_hash: T::Hash, - client: Client, - ) -> Result - where - Client: OnlineClientT, - { - let event_bytes = get_event_bytes(client.backend(), block_hash).await?; - Ok(Events::new(metadata, block_hash, event_bytes)) - } - /// The number of events. - pub fn len(&self) -> u32 { - self.num_events - } - /// Are there no events in this block? - pub fn is_empty(&self) -> bool { - self.num_events == 0 - } - /// Return the block hash that these events are from. - pub fn block_hash(&self) -> T::Hash { - self.block_hash - } - /// Iterate over all of the events, using metadata to dynamically - /// decode them as we go, and returning the raw bytes and other associated - /// details. If an error occurs, all subsequent iterations return `None`. - pub fn iter( - &self, - ) -> impl Iterator< - Item = Result, Error>, - > + Send + Sync + 'static { - let event_bytes = self.event_bytes.clone(); - let metadata = self.metadata.clone(); - let num_events = self.num_events; - let mut pos = self.start_idx; - let mut index = 0; - std::iter::from_fn(move || { - if event_bytes.len() <= pos || num_events == index { - None - } else { - match EventDetails::decode_from( - metadata.clone(), - event_bytes.clone(), - pos, - index, - ) { - Ok(event_details) => { - pos += event_details.bytes().len(); - index += 1; - Some(Ok(event_details)) - } - Err(e) => { - pos = event_bytes.len(); - Some(Err(e)) - } - } - } - }) - } - /// Iterate through the events using metadata to dynamically decode and skip - /// them, and return only those which should decode to the provided `Ev` type. - /// If an error occurs, all subsequent iterations return `None`. - pub fn find( - &self, - ) -> impl Iterator> + '_ { - self.iter() - .filter_map(|ev| { - ev.and_then(|ev| ev.as_event::().map_err(Into::into)) - .transpose() - }) - } - /// Iterate through the events using metadata to dynamically decode and skip - /// them, and return the first event found which decodes to the provided `Ev` type. - pub fn find_first(&self) -> Result, Error> { - self.find::().next().transpose() - } - /// Iterate through the events using metadata to dynamically decode and skip - /// them, and return the last event found which decodes to the provided `Ev` type. - pub fn find_last(&self) -> Result, Error> { - self.find::().last().transpose() - } - /// Find an event that decodes to the type provided. Returns true if it was found. - pub fn has(&self) -> Result { - Ok(self.find::().next().transpose()?.is_some()) - } - } - /// The event details. - pub struct EventDetails { - phase: Phase, - /// The index of the event in the list of events in a given block. - index: u32, - all_bytes: Arc<[u8]>, - start_idx: usize, - event_start_idx: usize, - event_fields_start_idx: usize, - event_fields_end_idx: usize, - end_idx: usize, - metadata: Metadata, - topics: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for EventDetails - where - T::Hash: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "phase", - "index", - "all_bytes", - "start_idx", - "event_start_idx", - "event_fields_start_idx", - "event_fields_end_idx", - "end_idx", - "metadata", - "topics", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.phase, - &self.index, - &self.all_bytes, - &self.start_idx, - &self.event_start_idx, - &self.event_fields_start_idx, - &self.event_fields_end_idx, - &self.end_idx, - &self.metadata, - &&self.topics, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "EventDetails", - names, - values, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for EventDetails - where - T::Hash: ::core::clone::Clone, - { - #[inline] - fn clone(&self) -> EventDetails { - EventDetails { - phase: ::core::clone::Clone::clone(&self.phase), - index: ::core::clone::Clone::clone(&self.index), - all_bytes: ::core::clone::Clone::clone(&self.all_bytes), - start_idx: ::core::clone::Clone::clone(&self.start_idx), - event_start_idx: ::core::clone::Clone::clone(&self.event_start_idx), - event_fields_start_idx: ::core::clone::Clone::clone( - &self.event_fields_start_idx, - ), - event_fields_end_idx: ::core::clone::Clone::clone( - &self.event_fields_end_idx, - ), - end_idx: ::core::clone::Clone::clone(&self.end_idx), - metadata: ::core::clone::Clone::clone(&self.metadata), - topics: ::core::clone::Clone::clone(&self.topics), - } - } - } - impl EventDetails { - fn decode_from( - metadata: Metadata, - all_bytes: Arc<[u8]>, - start_idx: usize, - index: u32, - ) -> Result, Error> { - let input = &mut &all_bytes[start_idx..]; - let phase = Phase::decode(input)?; - let event_start_idx = all_bytes.len() - input.len(); - let pallet_index = u8::decode(input)?; - let variant_index = u8::decode(input)?; - let event_fields_start_idx = all_bytes.len() - input.len(); - let event_pallet = metadata.pallet_by_index_err(pallet_index)?; - let event_variant = event_pallet - .event_variant_by_index(variant_index) - .ok_or(MetadataError::VariantIndexNotFound(variant_index))?; - { - use ::tracing::__macro_support::Callsite as _; - static __CALLSITE: ::tracing::callsite::DefaultCallsite = { - static META: ::tracing::Metadata<'static> = { - ::tracing_core::metadata::Metadata::new( - "event subxt/src/events/events_type.rs:220", - "subxt::events::events_type", - ::tracing::Level::DEBUG, - ::core::option::Option::Some( - "subxt/src/events/events_type.rs", - ), - ::core::option::Option::Some(220u32), - ::core::option::Option::Some("subxt::events::events_type"), - ::tracing_core::field::FieldSet::new( - &["message"], - ::tracing_core::callsite::Identifier(&__CALLSITE), - ), - ::tracing::metadata::Kind::EVENT, - ) - }; - ::tracing::callsite::DefaultCallsite::new(&META) - }; - let enabled = ::tracing::Level::DEBUG - <= ::tracing::level_filters::STATIC_MAX_LEVEL - && ::tracing::Level::DEBUG - <= ::tracing::level_filters::LevelFilter::current() - && { - let interest = __CALLSITE.interest(); - !interest.is_never() - && ::tracing::__macro_support::__is_enabled( - __CALLSITE.metadata(), - interest, - ) - }; - if enabled { - (|value_set: ::tracing::field::ValueSet| { - let meta = __CALLSITE.metadata(); - ::tracing::Event::dispatch(meta, &value_set); - })({ - #[allow(unused_imports)] - use ::tracing::field::{debug, display, Value}; - let mut iter = __CALLSITE.metadata().fields().iter(); - __CALLSITE - .metadata() - .fields() - .value_set( - &[ - ( - &::core::iter::Iterator::next(&mut iter) - .expect("FieldSet corrupted (this is a bug)"), - ::core::option::Option::Some( - &format_args!( - "Decoding Event \'{0}::{1}\'", event_pallet.name(), & - event_variant.name - ) as &dyn Value, - ), - ), - ], - ) - }); - } else { - } - }; - for field_metadata in &event_variant.fields { - scale_decode::visitor::decode_with_visitor( - input, - field_metadata.ty.id, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(scale_decode::Error::from)?; - } - let event_fields_end_idx = all_bytes.len() - input.len(); - let topics = Vec::::decode(input)?; - let end_idx = all_bytes.len() - input.len(); - Ok(EventDetails { - phase, - index, - start_idx, - event_start_idx, - event_fields_start_idx, - event_fields_end_idx, - end_idx, - all_bytes, - metadata, - topics, - }) - } - /// When was the event produced? - pub fn phase(&self) -> Phase { - self.phase - } - /// What index is this event in the stored events for this block. - pub fn index(&self) -> u32 { - self.index - } - /// The index of the pallet that the event originated from. - pub fn pallet_index(&self) -> u8 { - self.all_bytes[self.event_fields_start_idx - 2] - } - /// The index of the event variant that the event originated from. - pub fn variant_index(&self) -> u8 { - self.all_bytes[self.event_fields_start_idx - 1] - } - /// The name of the pallet from whence the Event originated. - pub fn pallet_name(&self) -> &str { - self.event_metadata().pallet.name() - } - /// The name of the event (ie the name of the variant that it corresponds to). - pub fn variant_name(&self) -> &str { - &self.event_metadata().variant.name - } - /// Fetch details from the metadata for this event. - pub fn event_metadata(&self) -> EventMetadataDetails { - let pallet = self - .metadata - .pallet_by_index(self.pallet_index()) - .expect( - "event pallet to be found; we did this already during decoding", - ); - let variant = pallet - .event_variant_by_index(self.variant_index()) - .expect( - "event variant to be found; we did this already during decoding", - ); - EventMetadataDetails { - pallet, - variant, - } - } - /// Return _all_ of the bytes representing this event, which include, in order: - /// - The phase. - /// - Pallet and event index. - /// - Event fields. - /// - Event Topics. - pub fn bytes(&self) -> &[u8] { - &self.all_bytes[self.start_idx..self.end_idx] - } - /// Return the bytes representing the fields stored in this event. - pub fn field_bytes(&self) -> &[u8] { - &self.all_bytes[self.event_fields_start_idx..self.event_fields_end_idx] - } - /// Decode and provide the event fields back in the form of a [`scale_value::Composite`] - /// type which represents the named or unnamed fields that were present in the event. - pub fn field_values( - &self, - ) -> Result, Error> { - let bytes = &mut self.field_bytes(); - let event_metadata = self.event_metadata(); - let mut fields = event_metadata - .variant - .fields - .iter() - .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); - use scale_decode::DecodeAsFields; - let decoded = >::decode_as_fields(bytes, &mut fields, self.metadata.types())?; - Ok(decoded) - } - /// Attempt to decode these [`EventDetails`] into a type representing the event fields. - /// Such types are exposed in the codegen as `pallet_name::events::EventName` types. - pub fn as_event(&self) -> Result, Error> { - let ev_metadata = self.event_metadata(); - if ev_metadata.pallet.name() == E::PALLET - && ev_metadata.variant.name == E::EVENT - { - let mut fields = ev_metadata - .variant - .fields - .iter() - .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); - let decoded = E::decode_as_fields( - &mut self.field_bytes(), - &mut fields, - self.metadata.types(), - )?; - Ok(Some(decoded)) - } else { - Ok(None) - } - } - /// Attempt to decode these [`EventDetails`] into a root event type (which includes - /// the pallet and event enum variants as well as the event fields). A compatible - /// type for this is exposed via static codegen as a root level `Event` type. - pub fn as_root_event(&self) -> Result { - let bytes = &self - .all_bytes[self.event_start_idx..self.event_fields_end_idx]; - let decoded = E::decode_as_type( - &mut &bytes[..], - self.metadata.outer_enums().event_enum_ty(), - self.metadata.types(), - )?; - Ok(decoded) - } - /// Return the topics associated with this event. - pub fn topics(&self) -> &[T::Hash] { - &self.topics - } - } - /// Details for the given event plucked from the metadata. - pub struct EventMetadataDetails<'a> { - pub pallet: PalletMetadata<'a>, - pub variant: &'a scale_info::Variant, - } - } - use codec::{Decode, Encode}; - pub use events_client::EventsClient; - pub use events_type::{EventDetails, Events}; - use scale_decode::DecodeAsFields; - /// Trait to uniquely identify the events's identity from the runtime metadata. - /// - /// Generated API structures that represent an event implement this trait. - /// - /// The trait is utilized to decode emitted events from a block, via obtaining the - /// form of the `Event` from the metadata. - pub trait StaticEvent: DecodeAsFields { - /// Pallet name. - const PALLET: &'static str; - /// Event name. - const EVENT: &'static str; - /// Returns true if the given pallet and event names match this event. - fn is_event(pallet: &str, event: &str) -> bool { - Self::PALLET == pallet && Self::EVENT == event - } - } - /// A phase of a block's execution. - pub enum Phase { - /// Applying an extrinsic. - ApplyExtrinsic(u32), - /// Finalizing the block. - Finalization, - /// Initializing the block. - Initialization, - } - #[automatically_derived] - impl ::core::marker::Copy for Phase {} - #[automatically_derived] - impl ::core::clone::Clone for Phase { - #[inline] - fn clone(&self) -> Phase { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Phase { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - Phase::ApplyExtrinsic(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ApplyExtrinsic", - &__self_0, - ) - } - Phase::Finalization => { - ::core::fmt::Formatter::write_str(f, "Finalization") - } - Phase::Initialization => { - ::core::fmt::Formatter::write_str(f, "Initialization") - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Phase { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Phase {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Phase { - #[inline] - fn eq(&self, other: &Phase) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - Phase::ApplyExtrinsic(__self_0), - Phase::ApplyExtrinsic(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for Phase { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e.chain("Could not decode `Phase`, failed to read variant byte") - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - Phase::ApplyExtrinsic({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `Phase::ApplyExtrinsic.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(Phase::Finalization) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(Phase::Initialization) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into("Could not decode `Phase`, variant doesn't exist"), - ) - })(); - } - } - } - } - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for Phase { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - Phase::ApplyExtrinsic(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - Phase::Finalization => 0_usize, - Phase::Initialization => 0_usize, - _ => 0_usize, - } - } - fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>( - &self, - __codec_dest_edqy: &mut __CodecOutputEdqy, - ) { - match *self { - Phase::ApplyExtrinsic(ref aa) => { - __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - Phase::Finalization => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); - } - Phase::Initialization => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::codec::EncodeLike for Phase {} - }; -} -pub mod metadata { - //! Types representing the metadata obtained from a node. - mod decode_encode_traits { - use super::Metadata; - use crate::error::Error; - /// This trait is implemented for all types that also implement [`scale_decode::DecodeAsType`]. - pub trait DecodeWithMetadata: Sized { - /// Given some metadata and a type ID, attempt to SCALE decode the provided bytes into `Self`. - fn decode_with_metadata( - bytes: &mut &[u8], - type_id: u32, - metadata: &Metadata, - ) -> Result; - } - impl DecodeWithMetadata for T { - fn decode_with_metadata( - bytes: &mut &[u8], - type_id: u32, - metadata: &Metadata, - ) -> Result { - let val = T::decode_as_type(bytes, type_id, metadata.types())?; - Ok(val) - } - } - /// This trait is implemented for all types that also implement [`scale_encode::EncodeAsType`]. - pub trait EncodeWithMetadata { - /// SCALE encode this type to bytes, possibly with the help of metadata. - fn encode_with_metadata( - &self, - type_id: u32, - metadata: &Metadata, - bytes: &mut Vec, - ) -> Result<(), Error>; - } - impl EncodeWithMetadata for T { - /// SCALE encode this type to bytes, possibly with the help of metadata. - fn encode_with_metadata( - &self, - type_id: u32, - metadata: &Metadata, - bytes: &mut Vec, - ) -> Result<(), Error> { - self.encode_as_type_to(type_id, metadata.types(), bytes)?; - Ok(()) - } - } - } - mod metadata_type { - use crate::error::MetadataError; - use std::sync::Arc; - /// A cheaply clone-able representation of the runtime metadata received from a node. - pub struct Metadata { - inner: Arc, - } - #[automatically_derived] - impl ::core::clone::Clone for Metadata { - #[inline] - fn clone(&self) -> Metadata { - Metadata { - inner: ::core::clone::Clone::clone(&self.inner), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Metadata { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Metadata", - "inner", - &&self.inner, - ) - } - } - impl std::ops::Deref for Metadata { - type Target = subxt_metadata::Metadata; - fn deref(&self) -> &Self::Target { - &self.inner - } - } - impl Metadata { - pub(crate) fn new(md: subxt_metadata::Metadata) -> Self { - Metadata { inner: Arc::new(md) } - } - /// Identical to `metadata.pallet_by_name()`, but returns an error if the pallet is not found. - pub fn pallet_by_name_err( - &self, - name: &str, - ) -> Result { - self.pallet_by_name(name) - .ok_or_else(|| MetadataError::PalletNameNotFound(name.to_owned())) - } - /// Identical to `metadata.pallet_by_index()`, but returns an error if the pallet is not found. - pub fn pallet_by_index_err( - &self, - index: u8, - ) -> Result { - self.pallet_by_index(index) - .ok_or(MetadataError::PalletIndexNotFound(index)) - } - /// Identical to `metadata.runtime_api_trait_by_name()`, but returns an error if the trait is not found. - pub fn runtime_api_trait_by_name_err( - &self, - name: &str, - ) -> Result { - self.runtime_api_trait_by_name(name) - .ok_or_else(|| MetadataError::RuntimeTraitNotFound(name.to_owned())) - } - } - impl From for Metadata { - fn from(md: subxt_metadata::Metadata) -> Self { - Metadata::new(md) - } - } - impl TryFrom for Metadata { - type Error = subxt_metadata::TryFromError; - fn try_from( - value: frame_metadata::RuntimeMetadataPrefixed, - ) -> Result { - subxt_metadata::Metadata::try_from(value).map(Metadata::from) - } - } - impl codec::Decode for Metadata { - fn decode(input: &mut I) -> Result { - subxt_metadata::Metadata::decode(input).map(Metadata::new) - } - } - } - pub use decode_encode_traits::{DecodeWithMetadata, EncodeWithMetadata}; - pub use metadata_type::Metadata; - pub use subxt_metadata as types; -} -pub mod runtime_api { - //! Types associated with executing runtime API calls. - mod runtime_client { - use super::runtime_types::RuntimeApi; - use crate::{backend::BlockRef, client::OnlineClientT, error::Error, Config}; - use derivative::Derivative; - use std::{future::Future, marker::PhantomData}; - /// Execute runtime API calls. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct RuntimeApiClient { - client: Client, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for RuntimeApiClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - RuntimeApiClient { client: ref __arg_0, _marker: ref __arg_1 } => { - RuntimeApiClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl RuntimeApiClient { - /// Create a new [`RuntimeApiClient`] - pub fn new(client: Client) -> Self { - Self { - client, - _marker: PhantomData, - } - } - } - impl RuntimeApiClient - where - T: Config, - Client: OnlineClientT, - { - /// Obtain a runtime API interface at some block hash. - pub fn at( - &self, - block_ref: impl Into>, - ) -> RuntimeApi { - RuntimeApi::new(self.client.clone(), block_ref.into()) - } - /// Obtain a runtime API interface at the latest block hash. - pub fn at_latest( - &self, - ) -> impl Future< - Output = Result, Error>, - > + Send + 'static { - let client = self.client.clone(); - async move { - let block_ref = client.backend().latest_finalized_block_ref().await?; - Ok(RuntimeApi::new(client, block_ref)) - } - } - } - } - mod runtime_payload { - use core::marker::PhantomData; - use derivative::Derivative; - use scale_encode::EncodeAsFields; - use scale_value::Composite; - use std::borrow::Cow; - use crate::dynamic::DecodedValueThunk; - use crate::error::MetadataError; - use crate::{metadata::DecodeWithMetadata, Error, Metadata}; - /// This represents a runtime API payload that can call into the runtime of node. - /// - /// # Components - /// - /// - associated return type - /// - /// Resulting bytes of the call are interpreted into this type. - /// - /// - runtime function name - /// - /// The function name of the runtime API call. This is obtained by concatenating - /// the runtime trait name with the trait's method. - /// - /// For example, the substrate runtime trait [Metadata](https://github.com/paritytech/substrate/blob/cb954820a8d8d765ce75021e244223a3b4d5722d/primitives/api/src/lib.rs#L745) - /// contains the `metadata_at_version` function. The corresponding runtime function - /// is `Metadata_metadata_at_version`. - /// - /// - encoded arguments - /// - /// Each argument of the runtime function must be scale-encoded. - pub trait RuntimeApiPayload { - /// The return type of the function call. - type ReturnType: DecodeWithMetadata; - /// The runtime API trait name. - fn trait_name(&self) -> &str; - /// The runtime API method name. - fn method_name(&self) -> &str; - /// Scale encode the arguments data. - fn encode_args_to( - &self, - metadata: &Metadata, - out: &mut Vec, - ) -> Result<(), Error>; - /// Encode arguments data and return the output. This is a convenience - /// wrapper around [`RuntimeApiPayload::encode_args_to`]. - fn encode_args(&self, metadata: &Metadata) -> Result, Error> { - let mut v = Vec::new(); - self.encode_args_to(metadata, &mut v)?; - Ok(v) - } - /// Returns the statically generated validation hash. - fn validation_hash(&self) -> Option<[u8; 32]> { - None - } - } - /// A runtime API payload containing the generic argument data - /// and interpreting the result of the call as `ReturnTy`. - /// - /// This can be created from static values (ie those generated - /// via the `subxt` macro) or dynamic values via [`dynamic`]. - #[derivative( - Clone(bound = "ArgsData: Clone"), - Debug(bound = "ArgsData: std::fmt::Debug"), - Eq(bound = "ArgsData: std::cmp::Eq"), - Ord(bound = "ArgsData: std::cmp::Ord"), - PartialEq(bound = "ArgsData: std::cmp::PartialEq"), - PartialOrd(bound = "ArgsData: std::cmp::PartialOrd") - )] - pub struct Payload { - trait_name: Cow<'static, str>, - method_name: Cow<'static, str>, - args_data: ArgsData, - validation_hash: Option<[u8; 32]>, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Payload - where - ArgsData: Clone, - { - fn clone(&self) -> Self { - match *self { - Payload { - trait_name: ref __arg_0, - method_name: ref __arg_1, - args_data: ref __arg_2, - validation_hash: ref __arg_3, - _marker: ref __arg_4, - } => { - Payload { - trait_name: (*__arg_0).clone(), - method_name: (*__arg_1).clone(), - args_data: (*__arg_2).clone(), - validation_hash: (*__arg_3).clone(), - _marker: (*__arg_4).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Payload - where - ArgsData: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Payload { - trait_name: ref __arg_0, - method_name: ref __arg_1, - args_data: ref __arg_2, - validation_hash: ref __arg_3, - _marker: ref __arg_4, - } => { - let mut __debug_trait_builder = __f.debug_struct("Payload"); - let _ = __debug_trait_builder.field("trait_name", &&(*__arg_0)); - let _ = __debug_trait_builder.field("method_name", &&(*__arg_1)); - let _ = __debug_trait_builder.field("args_data", &&(*__arg_2)); - let _ = __debug_trait_builder - .field("validation_hash", &&(*__arg_3)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_4)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for Payload - where - ArgsData: std::cmp::Eq, - {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for Payload - where - ArgsData: std::cmp::PartialEq, - { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - Payload { - trait_name: ref __self_0, - method_name: ref __self_1, - args_data: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Payload { - trait_name: ref __other_0, - method_name: ref __other_1, - args_data: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - && &(*__self_3) == &(*__other_3) - && &(*__self_4) == &(*__other_4) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialOrd for Payload - where - ArgsData: std::cmp::PartialOrd, - { - fn partial_cmp( - &self, - other: &Self, - ) -> ::std::option::Option<::std::cmp::Ordering> { - match *self { - Payload { - trait_name: ref __self_0, - method_name: ref __self_1, - args_data: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Payload { - trait_name: ref __other_0, - method_name: ref __other_1, - args_data: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_0), - &(*__other_0), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_1), - &(*__other_1), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_2), - &(*__other_2), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_3), - &(*__other_3), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_4), - &(*__other_4), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::Ord for Payload - where - ArgsData: std::cmp::Ord, - { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - Payload { - trait_name: ref __self_0, - method_name: ref __self_1, - args_data: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Payload { - trait_name: ref __other_0, - method_name: ref __other_1, - args_data: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_4), &(*__other_4)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - impl RuntimeApiPayload - for Payload { - type ReturnType = ReturnTy; - fn trait_name(&self) -> &str { - &self.trait_name - } - fn method_name(&self) -> &str { - &self.method_name - } - fn encode_args_to( - &self, - metadata: &Metadata, - out: &mut Vec, - ) -> Result<(), Error> { - let api_method = metadata - .runtime_api_trait_by_name_err(&self.trait_name)? - .method_by_name(&self.method_name) - .ok_or_else(|| MetadataError::RuntimeMethodNotFound( - (*self.method_name).to_owned(), - ))?; - let mut fields = api_method - .inputs() - .map(|input| scale_encode::Field::named(input.ty, &input.name)); - self.args_data.encode_as_fields_to(&mut fields, metadata.types(), out)?; - Ok(()) - } - fn validation_hash(&self) -> Option<[u8; 32]> { - self.validation_hash - } - } - /// A dynamic runtime API payload. - pub type DynamicRuntimeApiPayload = Payload, DecodedValueThunk>; - impl Payload { - /// Create a new [`Payload`]. - pub fn new( - trait_name: impl Into, - method_name: impl Into, - args_data: ArgsData, - ) -> Self { - Payload { - trait_name: Cow::Owned(trait_name.into()), - method_name: Cow::Owned(method_name.into()), - args_data, - validation_hash: None, - _marker: PhantomData, - } - } - /// Create a new static [`Payload`] using static function name - /// and scale-encoded argument data. - /// - /// This is only expected to be used from codegen. - #[doc(hidden)] - pub fn new_static( - trait_name: &'static str, - method_name: &'static str, - args_data: ArgsData, - hash: [u8; 32], - ) -> Payload { - Payload { - trait_name: Cow::Borrowed(trait_name), - method_name: Cow::Borrowed(method_name), - args_data, - validation_hash: Some(hash), - _marker: std::marker::PhantomData, - } - } - /// Do not validate this call prior to submitting it. - pub fn unvalidated(self) -> Self { - Self { - validation_hash: None, - ..self - } - } - /// Returns the trait name. - pub fn trait_name(&self) -> &str { - &self.trait_name - } - /// Returns the method name. - pub fn method_name(&self) -> &str { - &self.method_name - } - /// Returns the arguments data. - pub fn args_data(&self) -> &ArgsData { - &self.args_data - } - } - /// Create a new [`DynamicRuntimeApiPayload`]. - pub fn dynamic( - trait_name: impl Into, - method_name: impl Into, - args_data: impl Into>, - ) -> DynamicRuntimeApiPayload { - Payload::new(trait_name, method_name, args_data.into()) - } - } - mod runtime_types { - use crate::{ - backend::{BackendExt, BlockRef}, - client::OnlineClientT, error::{Error, MetadataError}, - metadata::DecodeWithMetadata, Config, - }; - use codec::Decode; - use derivative::Derivative; - use std::{future::Future, marker::PhantomData}; - use super::RuntimeApiPayload; - /// Execute runtime API calls. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct RuntimeApi { - client: Client, - block_ref: BlockRef, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for RuntimeApi - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - RuntimeApi { - client: ref __arg_0, - block_ref: ref __arg_1, - _marker: ref __arg_2, - } => { - RuntimeApi { - client: (*__arg_0).clone(), - block_ref: (*__arg_1).clone(), - _marker: (*__arg_2).clone(), - } - } - } - } - } - impl RuntimeApi { - /// Create a new [`RuntimeApi`] - pub(crate) fn new(client: Client, block_ref: BlockRef) -> Self { - Self { - client, - block_ref, - _marker: PhantomData, - } - } - } - impl RuntimeApi - where - T: Config, - Client: OnlineClientT, - { - /// Execute a raw runtime API call. - pub fn call_raw<'a, Res: Decode>( - &self, - function: &'a str, - call_parameters: Option<&'a [u8]>, - ) -> impl Future> + 'a { - let client = self.client.clone(); - let block_hash = self.block_ref.hash(); - async move { - let data: Res = client - .backend() - .call_decoding(function, call_parameters, block_hash) - .await?; - Ok(data) - } - } - /// Execute a runtime API call. - pub fn call( - &self, - payload: Call, - ) -> impl Future> { - let client = self.client.clone(); - let block_hash = self.block_ref.hash(); - async move { - let metadata = client.metadata(); - let api_trait = metadata - .runtime_api_trait_by_name_err(payload.trait_name())?; - let api_method = api_trait - .method_by_name(payload.method_name()) - .ok_or_else(|| { - MetadataError::RuntimeMethodNotFound( - payload.method_name().to_owned(), - ) - })?; - if let Some(static_hash) = payload.validation_hash() { - let Some(runtime_hash) = api_trait - .method_hash(payload.method_name()) else { - return Err(MetadataError::IncompatibleCodegen.into()); - }; - if static_hash != runtime_hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - } - let params = payload.encode_args(&metadata)?; - let call_name = { - let res = ::alloc::fmt::format( - format_args!( - "{0}_{1}", payload.trait_name(), payload.method_name() - ), - ); - res - }; - let bytes = client - .backend() - .call(&call_name, Some(params.as_slice()), block_hash) - .await?; - let value = ::decode_with_metadata( - &mut &bytes[..], - api_method.output_ty(), - &metadata, - )?; - Ok(value) - } - } - } - } - pub use runtime_client::RuntimeApiClient; - pub use runtime_payload::{ - dynamic, DynamicRuntimeApiPayload, Payload, RuntimeApiPayload, - }; - pub use runtime_types::RuntimeApi; -} -pub mod storage { - //! Types associated with accessing and working with storage items. - mod storage_address { - use crate::{ - dynamic::DecodedValueThunk, - error::{Error, MetadataError, StorageAddressError}, - metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, - utils::{Encoded, Static}, - }; - use derivative::Derivative; - use scale_info::TypeDef; - use std::borrow::Cow; - use subxt_metadata::{StorageEntryType, StorageHasher}; - use super::StorageKey; - /// This represents a storage address. Anything implementing this trait - /// can be used to fetch and iterate over storage entries. - pub trait StorageAddress { - /// The target type of the value that lives at this address. - type Target: DecodeWithMetadata; - /// The keys type used to construct this address. - type Keys: StorageKey; - /// Can an entry be fetched from this address? - /// Set this type to [`Yes`] to enable the corresponding calls to be made. - type IsFetchable; - /// Can a default entry be obtained from this address? - /// Set this type to [`Yes`] to enable the corresponding calls to be made. - type IsDefaultable; - /// Can this address be iterated over? - /// Set this type to [`Yes`] to enable the corresponding calls to be made. - type IsIterable; - /// The name of the pallet that the entry lives under. - fn pallet_name(&self) -> &str; - /// The name of the entry in a given pallet that the item is at. - fn entry_name(&self) -> &str; - /// Output the non-prefix bytes; that is, any additional bytes that need - /// to be appended to the key to dig into maps. - fn append_entry_bytes( - &self, - metadata: &Metadata, - bytes: &mut Vec, - ) -> Result<(), Error>; - /// An optional hash which, if present, will be checked against - /// the node metadata to confirm that the return type matches what - /// we are expecting. - fn validation_hash(&self) -> Option<[u8; 32]> { - None - } - } - /// Used to signal whether a [`StorageAddress`] can be iterated, - /// fetched and returned with a default value in the type system. - pub struct Yes; - /// A concrete storage address. This can be created from static values (ie those generated - /// via the `subxt` macro) or dynamic values via [`dynamic`]. - #[derivative( - Clone(bound = "Keys: Clone"), - Debug(bound = "Keys: std::fmt::Debug"), - Eq(bound = "Keys: std::cmp::Eq"), - Ord(bound = "Keys: std::cmp::Ord"), - PartialEq(bound = "Keys: std::cmp::PartialEq"), - PartialOrd(bound = "Keys: std::cmp::PartialOrd") - )] - pub struct Address< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > { - pallet_name: Cow<'static, str>, - entry_name: Cow<'static, str>, - keys: Keys, - validation_hash: Option<[u8; 32]>, - _marker: std::marker::PhantomData< - (ReturnTy, Fetchable, Defaultable, Iterable), - >, - } - #[allow(unused_qualifications)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::clone::Clone - for Address - where - Keys: Clone, - { - fn clone(&self) -> Self { - match *self { - Address { - pallet_name: ref __arg_0, - entry_name: ref __arg_1, - keys: ref __arg_2, - validation_hash: ref __arg_3, - _marker: ref __arg_4, - } => { - Address { - pallet_name: (*__arg_0).clone(), - entry_name: (*__arg_1).clone(), - keys: (*__arg_2).clone(), - validation_hash: (*__arg_3).clone(), - _marker: (*__arg_4).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::fmt::Debug for Address - where - Keys: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Address { - pallet_name: ref __arg_0, - entry_name: ref __arg_1, - keys: ref __arg_2, - validation_hash: ref __arg_3, - _marker: ref __arg_4, - } => { - let mut __debug_trait_builder = __f.debug_struct("Address"); - let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); - let _ = __debug_trait_builder.field("entry_name", &&(*__arg_1)); - let _ = __debug_trait_builder.field("keys", &&(*__arg_2)); - let _ = __debug_trait_builder - .field("validation_hash", &&(*__arg_3)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_4)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq - for Address - where - Keys: std::cmp::Eq, - {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::cmp::PartialEq - for Address - where - Keys: std::cmp::PartialEq, - { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - Address { - pallet_name: ref __self_0, - entry_name: ref __self_1, - keys: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Address { - pallet_name: ref __other_0, - entry_name: ref __other_1, - keys: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - && &(*__self_3) == &(*__other_3) - && &(*__self_4) == &(*__other_4) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::cmp::PartialOrd - for Address - where - Keys: std::cmp::PartialOrd, - { - fn partial_cmp( - &self, - other: &Self, - ) -> ::std::option::Option<::std::cmp::Ordering> { - match *self { - Address { - pallet_name: ref __self_0, - entry_name: ref __self_1, - keys: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Address { - pallet_name: ref __other_0, - entry_name: ref __other_1, - keys: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_0), - &(*__other_0), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_1), - &(*__other_1), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_2), - &(*__other_2), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_3), - &(*__other_3), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_4), - &(*__other_4), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::cmp::Ord for Address - where - Keys: std::cmp::Ord, - { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - Address { - pallet_name: ref __self_0, - entry_name: ref __self_1, - keys: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Address { - pallet_name: ref __other_0, - entry_name: ref __other_1, - keys: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_4), &(*__other_4)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - /// A storage key for static encoded values. - /// The original value is only present at construction, but can be decoded from the contained bytes. - #[derivative(Clone(bound = ""), Debug(bound = ""))] - pub struct StaticStorageKey { - pub(super) bytes: Static, - pub(super) _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for StaticStorageKey { - fn clone(&self) -> Self { - match *self { - StaticStorageKey { bytes: ref __arg_0, _marker: ref __arg_1 } => { - StaticStorageKey { - bytes: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for StaticStorageKey { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - StaticStorageKey { bytes: ref __arg_0, _marker: ref __arg_1 } => { - let mut __debug_trait_builder = __f - .debug_struct("StaticStorageKey"); - let _ = __debug_trait_builder.field("bytes", &&(*__arg_0)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - impl StaticStorageKey { - /// Creates a new static storage key - pub fn new(key: &K) -> Self { - StaticStorageKey { - bytes: Static(Encoded(key.encode())), - _marker: std::marker::PhantomData, - } - } - /// Returns the scale-encoded bytes that make up this key - pub fn bytes(&self) -> &[u8] { - &self.bytes.0.0 - } - } - /// A typical storage address constructed at runtime rather than via the `subxt` macro; this - /// has no restriction on what it can be used for (since we don't statically know). - pub type DynamicAddress = Address; - impl DynamicAddress { - /// Creates a new dynamic address. As `Keys` you can use a `Vec` - pub fn new( - pallet_name: impl Into, - entry_name: impl Into, - keys: Keys, - ) -> Self { - Self { - pallet_name: Cow::Owned(pallet_name.into()), - entry_name: Cow::Owned(entry_name.into()), - keys, - validation_hash: None, - _marker: std::marker::PhantomData, - } - } - } - impl< - Keys, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > Address - where - Keys: StorageKey, - ReturnTy: DecodeWithMetadata, - { - /// Create a new [`Address`] using static strings for the pallet and call name. - /// This is only expected to be used from codegen. - #[doc(hidden)] - pub fn new_static( - pallet_name: &'static str, - entry_name: &'static str, - keys: Keys, - hash: [u8; 32], - ) -> Self { - Self { - pallet_name: Cow::Borrowed(pallet_name), - entry_name: Cow::Borrowed(entry_name), - keys, - validation_hash: Some(hash), - _marker: std::marker::PhantomData, - } - } - } - impl< - Keys, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > Address - where - Keys: StorageKey, - ReturnTy: DecodeWithMetadata, - { - /// Do not validate this storage entry prior to accessing it. - pub fn unvalidated(self) -> Self { - Self { - validation_hash: None, - ..self - } - } - /// Return bytes representing the root of this storage entry (ie a hash of - /// the pallet and entry name). Use [`crate::storage::StorageClient::address_bytes()`] - /// to obtain the bytes representing the entire address. - pub fn to_root_bytes(&self) -> Vec { - super::utils::storage_address_root_bytes(self) - } - } - impl StorageAddress - for Address - where - Keys: StorageKey, - ReturnTy: DecodeWithMetadata, - { - type Target = ReturnTy; - type Keys = Keys; - type IsFetchable = Fetchable; - type IsDefaultable = Defaultable; - type IsIterable = Iterable; - fn pallet_name(&self) -> &str { - &self.pallet_name - } - fn entry_name(&self) -> &str { - &self.entry_name - } - fn append_entry_bytes( - &self, - metadata: &Metadata, - bytes: &mut Vec, - ) -> Result<(), Error> { - let pallet = metadata.pallet_by_name_err(self.pallet_name())?; - let storage = pallet - .storage() - .ok_or_else(|| MetadataError::StorageNotFoundInPallet( - self.pallet_name().to_owned(), - ))?; - let entry = storage - .entry_by_name(self.entry_name()) - .ok_or_else(|| MetadataError::StorageEntryNotFound( - self.entry_name().to_owned(), - ))?; - let keys_iter = self.keys.keys_iter(); - let keys_len = self.keys.keys_len(); - if keys_len == 0 { - return Ok(()); - } - let StorageEntryType::Map { hashers, key_ty, .. } = entry - .entry_type() else { - return Err( - StorageAddressError::WrongNumberOfKeys { - expected: 0, - actual: keys_len, - } - .into(), - ); - }; - let ty = metadata - .types() - .resolve(*key_ty) - .ok_or(MetadataError::TypeNotFound(*key_ty))?; - let type_ids = match &ty.type_def { - TypeDef::Tuple(tuple) => { - either::Either::Left(tuple.fields.iter().map(|f| f.id)) - } - _other => either::Either::Right(std::iter::once(*key_ty)), - }; - if hashers.len() == 1 { - let mut input = Vec::new(); - let iter = keys_iter.zip(type_ids); - for (key, type_id) in iter { - key.encode_with_metadata(type_id, metadata, &mut input)?; - } - hash_bytes(&input, &hashers[0], bytes); - } else if hashers.len() >= type_ids.len() { - let iter = keys_iter.zip(type_ids).zip(hashers); - for ((key, type_id), hasher) in iter { - let mut input = Vec::new(); - key.encode_with_metadata(type_id, metadata, &mut input)?; - hash_bytes(&input, hasher, bytes); - } - } else { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: hashers.len(), - fields: type_ids.len(), - } - .into(), - ); - } - Ok(()) - } - fn validation_hash(&self) -> Option<[u8; 32]> { - self.validation_hash - } - } - /// Construct a new dynamic storage lookup. - pub fn dynamic( - pallet_name: impl Into, - entry_name: impl Into, - storage_entry_keys: Keys, - ) -> DynamicAddress { - DynamicAddress::new(pallet_name, entry_name, storage_entry_keys) - } - /// Take some SCALE encoded bytes and a [`StorageHasher`] and hash the bytes accordingly. - fn hash_bytes(input: &[u8], hasher: &StorageHasher, bytes: &mut Vec) { - match hasher { - StorageHasher::Identity => bytes.extend(input), - StorageHasher::Blake2_128 => { - bytes.extend(sp_core_hashing::blake2_128(input)) - } - StorageHasher::Blake2_128Concat => { - bytes.extend(sp_core_hashing::blake2_128(input)); - bytes.extend(input); - } - StorageHasher::Blake2_256 => { - bytes.extend(sp_core_hashing::blake2_256(input)) - } - StorageHasher::Twox128 => bytes.extend(sp_core_hashing::twox_128(input)), - StorageHasher::Twox256 => bytes.extend(sp_core_hashing::twox_256(input)), - StorageHasher::Twox64Concat => { - bytes.extend(sp_core_hashing::twox_64(input)); - bytes.extend(input); - } - } - } - } - mod storage_client { - use super::{ - storage_type::{validate_storage_address, Storage}, - utils, StorageAddress, - }; - use crate::{ - backend::BlockRef, client::{OfflineClientT, OnlineClientT}, - error::Error, Config, - }; - use derivative::Derivative; - use std::{future::Future, marker::PhantomData}; - /// Query the runtime storage. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct StorageClient { - client: Client, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for StorageClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - StorageClient { client: ref __arg_0, _marker: ref __arg_1 } => { - StorageClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl StorageClient { - /// Create a new [`StorageClient`] - pub fn new(client: Client) -> Self { - Self { - client, - _marker: PhantomData, - } - } - } - impl StorageClient - where - T: Config, - Client: OfflineClientT, - { - /// Run the validation logic against some storage address you'd like to access. Returns `Ok(())` - /// if the address is valid (or if it's not possible to check since the address has no validation hash). - /// Return an error if the address was not valid or something went wrong trying to validate it (ie - /// the pallet or storage entry in question do not exist at all). - pub fn validate( - &self, - address: &Address, - ) -> Result<(), Error> { - let metadata = self.client.metadata(); - let pallet_metadata = metadata - .pallet_by_name_err(address.pallet_name())?; - validate_storage_address(address, pallet_metadata) - } - /// Convert some storage address into the raw bytes that would be submitted to the node in order - /// to retrieve the entries at the root of the associated address. - pub fn address_root_bytes( - &self, - address: &Address, - ) -> Vec { - utils::storage_address_root_bytes(address) - } - /// Convert some storage address into the raw bytes that would be submitted to the node in order - /// to retrieve an entry. This fails if [`StorageAddress::append_entry_bytes`] does; in the built-in - /// implementation this would be if the pallet and storage entry being asked for is not available on the - /// node you're communicating with, or if the metadata is missing some type information (which should not - /// happen). - pub fn address_bytes( - &self, - address: &Address, - ) -> Result, Error> { - utils::storage_address_bytes(address, &self.client.metadata()) - } - } - impl StorageClient - where - T: Config, - Client: OnlineClientT, - { - /// Obtain storage at some block hash. - pub fn at( - &self, - block_ref: impl Into>, - ) -> Storage { - Storage::new(self.client.clone(), block_ref.into()) - } - /// Obtain storage at the latest block hash. - pub fn at_latest( - &self, - ) -> impl Future< - Output = Result, Error>, - > + Send + 'static { - let client = self.client.clone(); - async move { - let block_ref = client.backend().latest_finalized_block_ref().await?; - Ok(Storage::new(client, block_ref)) - } - } - } - } - mod storage_key { - use super::{ - storage_address::StaticStorageKey, - utils::{ - hash_contains_unhashed_value, strip_storage_addess_root_bytes, - strip_storage_hash_bytes, - }, - }; - use crate::{ - dynamic::DecodedValueThunk, error::{Error, StorageAddressError}, - metadata::{DecodeWithMetadata, Metadata}, - utils::{Encoded, Static}, - }; - use scale_encode::EncodeAsType; - use subxt_metadata::StorageHasher; - /// This trait should be implemented by anything that can be used as one or multiple storage keys. - pub trait StorageKey { - /// Iterator over the storage keys, each key implements EncodeAsType to - /// give the corresponding bytes to a `StorageHasher`. - fn keys_iter(&self) -> impl Iterator; - /// How many keys are there in total? Each key is an element that needs to be individually hashed. - fn keys_len(&self) -> usize; - /// Attempts to decode the StorageKey from a storage address that has been stripped of its root bytes. - /// - /// Example: Imagine The `StorageKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. - /// Then the memory layout of the storage address is: - /// ```txt - /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | - /// ``` - /// `cursor` should point into a region after those first 16 bytes, at the start of a new hash. - /// `hashers_and_ty_ids` should consume all the hashers that have been used for decoding, such that there are less hashers coming to the next key. - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static; - } - /// Implement `StorageKey` for `()` which can be used for keyless storage entries. - impl StorageKey for () { - fn keys_iter(&self) -> impl Iterator { - std::iter::empty() - } - fn keys_len(&self) -> usize { - 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - _metadata: &Metadata, - ) -> Result { - if hashers_and_ty_ids.is_empty() { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into(), - ); - } - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; - Ok(()) - } - } - impl StorageKey - for StaticStorageKey { - fn keys_iter(&self) -> impl Iterator { - std::iter::once(&self.bytes as &dyn EncodeAsType) - } - fn keys_len(&self) -> usize { - 1 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into(), - ); - }; - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; - decode_storage_key_from_hash(cursor, hasher, *ty_id, metadata) - } - } - pub fn decode_storage_key_from_hash( - cursor: &mut &[u8], - hasher: &StorageHasher, - ty_id: u32, - metadata: &Metadata, - ) -> Result, Error> { - strip_storage_hash_bytes(cursor, hasher)?; - let bytes = *cursor; - if let Err(err) - = scale_decode::visitor::decode_with_visitor( - cursor, - ty_id, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) { - return Err(scale_decode::Error::from(err).into()); - } - let bytes_decoded = bytes.len() - cursor.len(); - if !hash_contains_unhashed_value(hasher) && bytes_decoded > 0 { - let ty_name = metadata - .types() - .resolve(ty_id) - .expect( - "ty_id is in metadata, because decode_with_visitor did not fail above; qed", - ) - .path - .to_string(); - return Err( - StorageAddressError::HasherCannotReconstructKey { - ty_id, - ty_name, - hasher: *hasher, - } - .into(), - ); - } - let key_bytes = bytes[..bytes_decoded].to_vec(); - let key = StaticStorageKey { - bytes: Static(Encoded(key_bytes)), - _marker: std::marker::PhantomData::, - }; - Ok(key) - } - impl StorageKey for Vec { - fn keys_iter(&self) -> impl Iterator { - self.iter().map(|e| e as &dyn EncodeAsType) - } - fn keys_len(&self) -> usize { - self.len() - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); - let mut result: Vec = ::alloc::vec::Vec::new(); - let mut n = 0; - while !cursor.is_empty() { - let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { - return Err(StorageAddressError::UnexpectedAddressBytes.into()); - }; - strip_storage_hash_bytes(cursor, hasher)?; - let decoded = DecodedValueThunk::decode_with_metadata( - cursor, - *ty_id, - metadata, - )?; - let value = decoded.to_value()?; - result.push(value.remove_context()); - n += 1; - } - *hashers_and_ty_ids = &hashers_and_ty_ids[n..]; - Ok(result) - } - } - #[rustfmt::skip] - const _: () = { - { - impl StorageKey for (A, B) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl StorageKey - for (A, B, C) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - > StorageKey for (A, B, C, D) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - E: StorageKey, - > StorageKey for (A, B, C, D, E) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + (self.4.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + (0 * 4 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[4]; - let key = E::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - E: StorageKey, - F: StorageKey, - > StorageKey for (A, B, C, D, E, F) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + (self.4.keys_len()) - + (self.5.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[4]; - let key = E::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[5]; - let key = F::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - E: StorageKey, - F: StorageKey, - G: StorageKey, - > StorageKey for (A, B, C, D, E, F, G) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + (self.4.keys_len()) - + (self.5.keys_len()) + (self.6.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + (0 * 6 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[4]; - let key = E::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[5]; - let key = F::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[6]; - let key = G::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - E: StorageKey, - F: StorageKey, - G: StorageKey, - H: StorageKey, - > StorageKey for (A, B, C, D, E, F, G, H) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + (self.4.keys_len()) - + (self.5.keys_len()) + (self.6.keys_len()) - + (self.7.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + (0 * 6 + 1) - + (0 * 7 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[4]; - let key = E::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[5]; - let key = F::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[6]; - let key = G::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[7]; - let key = H::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - }; - } - mod storage_type { - use super::storage_address::{StorageAddress, Yes}; - use super::utils::strip_storage_addess_root_bytes; - use super::StorageKey; - use crate::{ - backend::{BackendExt, BlockRef}, - client::OnlineClientT, error::{Error, MetadataError, StorageAddressError}, - metadata::{DecodeWithMetadata, Metadata}, - Config, - }; - use codec::Decode; - use derivative::Derivative; - use futures::StreamExt; - use scale_info::TypeDef; - use std::{future::Future, marker::PhantomData}; - use subxt_metadata::StorageHasher; - use subxt_metadata::{PalletMetadata, StorageEntryMetadata, StorageEntryType}; - /// This is returned from a couple of storage functions. - pub use crate::backend::StreamOfResults; - /// Query the runtime storage. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct Storage { - client: Client, - block_ref: BlockRef, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Storage - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - Storage { - client: ref __arg_0, - block_ref: ref __arg_1, - _marker: ref __arg_2, - } => { - Storage { - client: (*__arg_0).clone(), - block_ref: (*__arg_1).clone(), - _marker: (*__arg_2).clone(), - } - } - } - } - } - impl Storage { - /// Create a new [`Storage`] - pub(crate) fn new(client: Client, block_ref: BlockRef) -> Self { - Self { - client, - block_ref, - _marker: PhantomData, - } - } - } - impl Storage - where - T: Config, - Client: OnlineClientT, - { - /// Fetch the raw encoded value at the key given. - pub fn fetch_raw( - &self, - key: impl Into>, - ) -> impl Future>, Error>> + 'static { - let client = self.client.clone(); - let key = key.into(); - let block_ref = self.block_ref.clone(); - async move { - let data = client - .backend() - .storage_fetch_value(key, block_ref.hash()) - .await?; - Ok(data) - } - } - /// Stream all of the raw keys underneath the key given - pub fn fetch_raw_keys( - &self, - key: impl Into>, - ) -> impl Future< - Output = Result>, Error>, - > + 'static { - let client = self.client.clone(); - let block_hash = self.block_ref.hash(); - let key = key.into(); - async move { - let keys = client - .backend() - .storage_fetch_descendant_keys(key, block_hash) - .await?; - Ok(keys) - } - } - /// Fetch a decoded value from storage at a given address. - /// - /// # Example - /// - /// ```no_run - /// use subxt::{ PolkadotConfig, OnlineClient }; - /// - /// #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] - /// pub mod polkadot {} - /// - /// # #[tokio::main] - /// # async fn main() { - /// let api = OnlineClient::::new().await.unwrap(); - /// - /// // Address to a storage entry we'd like to access. - /// let address = polkadot::storage().xcm_pallet().queries(&12345); - /// - /// // Fetch just the keys, returning up to 10 keys. - /// let value = api - /// .storage() - /// .at_latest() - /// .await - /// .unwrap() - /// .fetch(&address) - /// .await - /// .unwrap(); - /// - /// println!("Value: {:?}", value); - /// # } - /// ``` - pub fn fetch<'address, Address>( - &self, - address: &'address Address, - ) -> impl Future, Error>> + 'address - where - Address: StorageAddress + 'address, - { - let client = self.clone(); - async move { - let metadata = client.client.metadata(); - let (pallet, entry) = lookup_entry_details( - address.pallet_name(), - address.entry_name(), - &metadata, - )?; - validate_storage_address(address, pallet)?; - let lookup_bytes = super::utils::storage_address_bytes( - address, - &metadata, - )?; - if let Some(data) = client.fetch_raw(lookup_bytes).await? { - let val = decode_storage_with_metadata::< - Address::Target, - >(&mut &*data, &metadata, entry)?; - Ok(Some(val)) - } else { - Ok(None) - } - } - } - /// Fetch a StorageKey that has a default value with an optional block hash. - pub fn fetch_or_default<'address, Address>( - &self, - address: &'address Address, - ) -> impl Future> + 'address - where - Address: StorageAddress - + 'address, - { - let client = self.clone(); - async move { - let pallet_name = address.pallet_name(); - let entry_name = address.entry_name(); - if let Some(data) = client.fetch(address).await? { - Ok(data) - } else { - let metadata = client.client.metadata(); - let (_pallet_metadata, storage_entry) = lookup_entry_details( - pallet_name, - entry_name, - &metadata, - )?; - let return_ty_id = return_type_from_storage_entry_type( - storage_entry.entry_type(), - ); - let bytes = &mut storage_entry.default_bytes(); - let val = Address::Target::decode_with_metadata( - bytes, - return_ty_id, - &metadata, - )?; - Ok(val) - } - } - } - /// Returns an iterator of key value pairs. - /// - /// ```no_run - /// use subxt::{ PolkadotConfig, OnlineClient }; - /// - /// #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] - /// pub mod polkadot {} - /// - /// # #[tokio::main] - /// # async fn main() { - /// let api = OnlineClient::::new().await.unwrap(); - /// - /// // Address to the root of a storage entry that we'd like to iterate over. - /// let address = polkadot::storage().xcm_pallet().version_notifiers_iter(); - /// - /// // Iterate over keys and values at that address. - /// let mut iter = api - /// .storage() - /// .at_latest() - /// .await - /// .unwrap() - /// .iter(address) - /// .await - /// .unwrap(); - /// - /// while let Some(Ok(kv)) = iter.next().await { - /// println!("Key bytes: 0x{}", hex::encode(&kv.key_bytes)); - /// println!("Value: {}", kv.value); - /// } - /// # } - /// ``` - pub fn iter
( - &self, - address: Address, - ) -> impl Future< - Output = Result>, Error>, - > + 'static - where - Address: StorageAddress + 'static, - Address::Keys: 'static + Sized, - { - let client = self.client.clone(); - let block_ref = self.block_ref.clone(); - async move { - let metadata = client.metadata(); - let (pallet, entry) = lookup_entry_details( - address.pallet_name(), - address.entry_name(), - &metadata, - )?; - validate_storage_address(&address, pallet)?; - let entry = entry.entry_type(); - let return_type_id = entry.value_ty(); - let hasher_type_id_pairs = storage_hasher_type_id_pairs( - entry, - &metadata, - )?; - let address_bytes = super::utils::storage_address_bytes( - &address, - &metadata, - )?; - let s = client - .backend() - .storage_fetch_descendant_values(address_bytes, block_ref.hash()) - .await? - .map(move |kv| { - let kv = match kv { - Ok(kv) => kv, - Err(e) => return Err(e), - }; - let value = Address::Target::decode_with_metadata( - &mut &*kv.value, - return_type_id, - &metadata, - )?; - let key_bytes = kv.key; - let cursor = &mut &key_bytes[..]; - strip_storage_addess_root_bytes(cursor)?; - let keys = ::decode_from_bytes( - cursor, - &hasher_type_id_pairs, - &metadata, - )?; - Ok(StorageKeyValuePair::
{ - keys, - key_bytes, - value, - }) - }); - let s = StreamOfResults::new(Box::pin(s)); - Ok(s) - } - } - /// The storage version of a pallet. - /// The storage version refers to the `frame_support::traits::Metadata::StorageVersion` type. - pub async fn storage_version( - &self, - pallet_name: impl AsRef, - ) -> Result { - self.client - .metadata() - .pallet_by_name(pallet_name.as_ref()) - .ok_or_else(|| MetadataError::PalletNameNotFound( - pallet_name.as_ref().into(), - ))?; - pub const STORAGE_VERSION_STORAGE_KEY_POSTFIX: &[u8] = b":__STORAGE_VERSION__:"; - let mut key_bytes: Vec = ::alloc::vec::Vec::new(); - key_bytes - .extend(&sp_core_hashing::twox_128(pallet_name.as_ref().as_bytes())); - key_bytes - .extend( - &sp_core_hashing::twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX), - ); - let storage_version_bytes = self - .fetch_raw(key_bytes) - .await? - .ok_or_else(|| { - { - let res = ::alloc::fmt::format( - format_args!( - "Unexpected: entry for storage version in pallet \"{0}\" not found", - pallet_name.as_ref() - ), - ); - res - } - })?; - u16::decode(&mut &storage_version_bytes[..]).map_err(Into::into) - } - /// Fetch the runtime WASM code. - pub async fn runtime_wasm_code(&self) -> Result, Error> { - const CODE: &str = ":code"; - self.fetch_raw(CODE.as_bytes()) - .await? - .ok_or_else(|| { - { - let res = ::alloc::fmt::format( - format_args!( - "Unexpected: entry for well known key \"{0}\" not found", - CODE - ), - ); - res - } - .into() - }) - } - } - pub(crate) fn storage_hasher_type_id_pairs( - entry: &StorageEntryType, - metadata: &Metadata, - ) -> Result, Error> { - match entry { - StorageEntryType::Plain(_) => Ok(::alloc::vec::Vec::new()), - StorageEntryType::Map { hashers, key_ty, .. } => { - let ty = metadata - .types() - .resolve(*key_ty) - .ok_or(MetadataError::TypeNotFound(*key_ty))?; - match &ty.type_def { - TypeDef::Tuple(tuple) => { - if hashers.len() < tuple.fields.len() { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: hashers.len(), - fields: tuple.fields.len(), - } - .into(), - ); - } - let pairs: Vec<(StorageHasher, u32)> = tuple - .fields - .iter() - .zip(hashers.iter()) - .map(|(e, h)| (*h, e.id)) - .collect(); - Ok(pairs) - } - _other => { - if hashers.is_empty() { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into(), - ); - } - Ok( - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([(hashers[0], *key_ty)]), - ), - ) - } - } - } - } - } - /// A pair of keys and values together with all the bytes that make up the storage address. - /// `keys` is `None` if non-concat hashers are used. In this case the keys could not be extracted back from the key_bytes. - pub struct StorageKeyValuePair { - /// The bytes that make up the address of the storage entry. - pub key_bytes: Vec, - /// The keys that can be used to construct the address of this storage entry. - pub keys: T::Keys, - /// The value of the storage entry. - pub value: T::Target, - } - #[automatically_derived] - impl ::core::clone::Clone - for StorageKeyValuePair - where - T::Keys: ::core::clone::Clone, - T::Target: ::core::clone::Clone, - { - #[inline] - fn clone(&self) -> StorageKeyValuePair { - StorageKeyValuePair { - key_bytes: ::core::clone::Clone::clone(&self.key_bytes), - keys: ::core::clone::Clone::clone(&self.keys), - value: ::core::clone::Clone::clone(&self.value), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug - for StorageKeyValuePair - where - T::Keys: ::core::fmt::Debug, - T::Target: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "StorageKeyValuePair", - "key_bytes", - &self.key_bytes, - "keys", - &self.keys, - "value", - &&self.value, - ) - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for StorageKeyValuePair - where - T::Keys: ::core::cmp::Eq, - T::Target: ::core::cmp::Eq, - { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for StorageKeyValuePair {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for StorageKeyValuePair - where - T::Keys: ::core::cmp::PartialEq, - T::Target: ::core::cmp::PartialEq, - { - #[inline] - fn eq(&self, other: &StorageKeyValuePair) -> bool { - self.key_bytes == other.key_bytes && self.keys == other.keys - && self.value == other.value - } - } - #[automatically_derived] - impl ::core::cmp::Ord - for StorageKeyValuePair - where - T::Keys: ::core::cmp::Ord, - T::Target: ::core::cmp::Ord, - { - #[inline] - fn cmp(&self, other: &StorageKeyValuePair) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp(&self.key_bytes, &other.key_bytes) { - ::core::cmp::Ordering::Equal => { - match ::core::cmp::Ord::cmp(&self.keys, &other.keys) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp(&self.value, &other.value) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd - for StorageKeyValuePair - where - T::Keys: ::core::cmp::PartialOrd, - T::Target: ::core::cmp::PartialOrd, - { - #[inline] - fn partial_cmp( - &self, - other: &StorageKeyValuePair, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp( - &self.key_bytes, - &other.key_bytes, - ) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - match ::core::cmp::PartialOrd::partial_cmp( - &self.keys, - &other.keys, - ) { - ::core::option::Option::Some( - ::core::cmp::Ordering::Equal, - ) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.value, - &other.value, - ) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - /// Validate a storage address against the metadata. - pub(crate) fn validate_storage_address( - address: &Address, - pallet: PalletMetadata<'_>, - ) -> Result<(), Error> { - if let Some(hash) = address.validation_hash() { - validate_storage(pallet, address.entry_name(), hash)?; - } - Ok(()) - } - /// Return details about the given storage entry. - fn lookup_entry_details<'a>( - pallet_name: &str, - entry_name: &str, - metadata: &'a Metadata, - ) -> Result<(PalletMetadata<'a>, &'a StorageEntryMetadata), Error> { - let pallet_metadata = metadata.pallet_by_name_err(pallet_name)?; - let storage_metadata = pallet_metadata - .storage() - .ok_or_else(|| MetadataError::StorageNotFoundInPallet( - pallet_name.to_owned(), - ))?; - let storage_entry = storage_metadata - .entry_by_name(entry_name) - .ok_or_else(|| MetadataError::StorageEntryNotFound( - entry_name.to_owned(), - ))?; - Ok((pallet_metadata, storage_entry)) - } - /// Validate a storage entry against the metadata. - fn validate_storage( - pallet: PalletMetadata<'_>, - storage_name: &str, - hash: [u8; 32], - ) -> Result<(), Error> { - let Some(expected_hash) = pallet.storage_hash(storage_name) else { - return Err(MetadataError::IncompatibleCodegen.into()); - }; - if expected_hash != hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - Ok(()) - } - /// Fetch the return type out of a [`StorageEntryType`]. - fn return_type_from_storage_entry_type(entry: &StorageEntryType) -> u32 { - match entry { - StorageEntryType::Plain(ty) => *ty, - StorageEntryType::Map { value_ty, .. } => *value_ty, - } - } - /// Given some bytes, a pallet and storage name, decode the response. - fn decode_storage_with_metadata( - bytes: &mut &[u8], - metadata: &Metadata, - storage_metadata: &StorageEntryMetadata, - ) -> Result { - let ty = storage_metadata.entry_type(); - let return_ty = return_type_from_storage_entry_type(ty); - let val = T::decode_with_metadata(bytes, return_ty, metadata)?; - Ok(val) - } - } - pub mod utils { - //! these utility methods complement the [`StorageAddress`] trait, but - //! aren't things that should ever be overridden, and so don't exist on - //! the trait itself. - use subxt_metadata::StorageHasher; - use super::StorageAddress; - use crate::{ - error::{Error, StorageAddressError}, - metadata::Metadata, - }; - /// Return the root of a given [`StorageAddress`]: hash the pallet name and entry name - /// and append those bytes to the output. - pub(crate) fn write_storage_address_root_bytes( - addr: &Address, - out: &mut Vec, - ) { - out.extend(sp_core_hashing::twox_128(addr.pallet_name().as_bytes())); - out.extend(sp_core_hashing::twox_128(addr.entry_name().as_bytes())); - } - /// Outputs the [`storage_address_root_bytes`] as well as any additional bytes that represent - /// a lookup in a storage map at that location. - pub(crate) fn storage_address_bytes( - addr: &Address, - metadata: &Metadata, - ) -> Result, Error> { - let mut bytes = Vec::new(); - write_storage_address_root_bytes(addr, &mut bytes); - addr.append_entry_bytes(metadata, &mut bytes)?; - Ok(bytes) - } - /// Outputs a vector containing the bytes written by [`write_storage_address_root_bytes`]. - pub(crate) fn storage_address_root_bytes( - addr: &Address, - ) -> Vec { - let mut bytes = Vec::new(); - write_storage_address_root_bytes(addr, &mut bytes); - bytes - } - /// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. - pub(crate) fn strip_storage_addess_root_bytes( - address_bytes: &mut &[u8], - ) -> Result<(), StorageAddressError> { - if address_bytes.len() >= 16 { - *address_bytes = &address_bytes[16..]; - Ok(()) - } else { - Err(StorageAddressError::UnexpectedAddressBytes) - } - } - /// Strips the first few bytes off a hash to possibly skip to the plan key value, - /// if [`hash_contains_unhashed_value()`] for this StorageHasher. - /// - /// Returns `Err(..)` if there are not enough bytes. - /// Returns `Ok(())` otherwise - pub fn strip_storage_hash_bytes( - hash: &mut &[u8], - hasher: &StorageHasher, - ) -> Result<(), StorageAddressError> { - let bytes_to_strip = match hasher { - StorageHasher::Blake2_128Concat => 16, - StorageHasher::Twox64Concat => 8, - StorageHasher::Blake2_128 => 16, - StorageHasher::Blake2_256 => 32, - StorageHasher::Twox128 => 16, - StorageHasher::Twox256 => 32, - StorageHasher::Identity => 0, - }; - if hash.len() < bytes_to_strip { - return Err(StorageAddressError::UnexpectedAddressBytes); - } - *hash = &hash[bytes_to_strip..]; - Ok(()) - } - /// This value is contained within the hash for concat-stle hashers - /// ([`StorageHasher::Identity`] or [`StorageHasher::Identity`]) and the - /// identity hash function ([`StorageHasher::Identity`]). - pub fn hash_contains_unhashed_value(hasher: &StorageHasher) -> bool { - match hasher { - StorageHasher::Blake2_128Concat - | StorageHasher::Twox64Concat - | StorageHasher::Identity => true, - _ => false, - } - } - } - pub use storage_client::StorageClient; - pub use storage_type::{Storage, StorageKeyValuePair}; - /// Types representing an address which describes where a storage - /// entry lives and how to properly decode it. - pub mod address { - pub use super::storage_address::{ - dynamic, Address, DynamicAddress, StaticStorageKey, StorageAddress, Yes, - }; - } - pub use storage_key::StorageKey; - pub use storage_address::{dynamic, Address, DynamicAddress, StorageAddress}; -} -pub mod tx { - //! Create and submit extrinsics. - //! - //! An extrinsic is submitted with an "signed extra" and "additional" parameters, which can be - //! different for each chain. The trait [`crate::config::ExtrinsicParams`] determines exactly which - //! additional and signed extra parameters are used when constructing an extrinsic, and is a part - //! of the chain configuration (see [`crate::config::Config`]). - use crate::macros::cfg_substrate_compat; - mod signer { - //! A library to **sub**mit e**xt**rinsics to a - //! [substrate](https://github.com/paritytech/substrate) node via RPC. - use crate::macros::cfg_substrate_compat; - use crate::Config; - /// Signing transactions requires a [`Signer`]. This is responsible for - /// providing the "from" account that the transaction is being signed by, - /// as well as actually signing a SCALE encoded payload. - pub trait Signer { - /// Return the "from" account ID. - fn account_id(&self) -> T::AccountId; - /// Return the "from" address. - fn address(&self) -> T::Address; - /// Takes a signer payload for an extrinsic, and returns a signature based on it. - /// - /// Some signers may fail, for instance because the hardware on which the keys are located has - /// refused the operation. - fn sign(&self, signer_payload: &[u8]) -> T::Signature; - } - } - mod tx_client { - use std::borrow::Cow; - use crate::{ - backend::{BackendExt, BlockRef, TransactionStatus}, - client::{OfflineClientT, OnlineClientT}, - config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, Hasher}, - error::{Error, MetadataError}, - tx::{Signer as SignerT, TxPayload, TxProgress}, - utils::{Encoded, PhantomDataSendSync}, - }; - use codec::{Compact, Decode, Encode}; - use derivative::Derivative; - use sp_core_hashing::blake2_256; - /// A client for working with transactions. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct TxClient { - client: Client, - _marker: PhantomDataSendSync, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for TxClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - TxClient { client: ref __arg_0, _marker: ref __arg_1 } => { - TxClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl TxClient { - /// Create a new [`TxClient`] - pub fn new(client: Client) -> Self { - Self { - client, - _marker: PhantomDataSendSync::new(), - } - } - } - impl> TxClient { - /// Run the validation logic against some extrinsic you'd like to submit. Returns `Ok(())` - /// if the call is valid (or if it's not possible to check since the call has no validation hash). - /// Return an error if the call was not valid or something went wrong trying to validate it (ie - /// the pallet or call in question do not exist at all). - pub fn validate(&self, call: &Call) -> Result<(), Error> - where - Call: TxPayload, - { - if let Some(details) = call.validation_details() { - let expected_hash = self - .client - .metadata() - .pallet_by_name_err(details.pallet_name)? - .call_hash(details.call_name) - .ok_or_else(|| MetadataError::CallNameNotFound( - details.call_name.to_owned(), - ))?; - if details.hash != expected_hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - } - Ok(()) - } - /// Return the SCALE encoded bytes representing the call data of the transaction. - pub fn call_data(&self, call: &Call) -> Result, Error> - where - Call: TxPayload, - { - let metadata = self.client.metadata(); - let mut bytes = Vec::new(); - call.encode_call_data_to(&metadata, &mut bytes)?; - Ok(bytes) - } - /// Creates an unsigned extrinsic without submitting it. - pub fn create_unsigned( - &self, - call: &Call, - ) -> Result, Error> - where - Call: TxPayload, - { - self.validate(call)?; - let extrinsic = { - let mut encoded_inner = Vec::new(); - 4u8.encode_to(&mut encoded_inner); - call.encode_call_data_to( - &self.client.metadata(), - &mut encoded_inner, - )?; - let len = Compact( - u32::try_from(encoded_inner.len()) - .expect("extrinsic size expected to be <4GB"), - ); - let mut encoded = Vec::new(); - len.encode_to(&mut encoded); - encoded.extend(encoded_inner); - encoded - }; - Ok(SubmittableExtrinsic::from_bytes(self.client.clone(), extrinsic)) - } - /// Create a partial extrinsic. - pub fn create_partial_signed_with_nonce( - &self, - call: &Call, - account_nonce: u64, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - { - self.validate(call)?; - let call_data = self.call_data(call)?; - let additional_and_extra_params = >::new(account_nonce, self.client.clone(), other_params)?; - Ok(PartialExtrinsic { - client: self.client.clone(), - call_data, - additional_and_extra_params, - }) - } - /// Creates a signed extrinsic without submitting it. - pub fn create_signed_with_nonce( - &self, - call: &Call, - signer: &Signer, - account_nonce: u64, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - Signer: SignerT, - { - self.validate(call)?; - let partial_signed = self - .create_partial_signed_with_nonce( - call, - account_nonce, - other_params, - )?; - Ok(partial_signed.sign(signer)) - } - } - impl TxClient - where - T: Config, - C: OnlineClientT, - { - /// Get the account nonce for a given account ID. - pub async fn account_nonce( - &self, - account_id: &T::AccountId, - ) -> Result { - let block_ref = self - .client - .backend() - .latest_finalized_block_ref() - .await?; - crate::blocks::get_account_nonce( - &self.client, - account_id, - block_ref.hash(), - ) - .await - } - /// Creates a partial signed extrinsic, without submitting it. - pub async fn create_partial_signed( - &self, - call: &Call, - account_id: &T::AccountId, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - { - let account_nonce = self.account_nonce(account_id).await?; - self.create_partial_signed_with_nonce(call, account_nonce, other_params) - } - /// Creates a signed extrinsic, without submitting it. - pub async fn create_signed( - &self, - call: &Call, - signer: &Signer, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - Signer: SignerT, - { - let account_nonce = self.account_nonce(&signer.account_id()).await?; - self.create_signed_with_nonce(call, signer, account_nonce, other_params) - } - /// Creates and signs an extrinsic and submits it to the chain. Passes default parameters - /// to construct the "signed extra" and "additional" payloads needed by the extrinsic. - /// - /// Returns a [`TxProgress`], which can be used to track the status of the transaction - /// and obtain details about it, once it has made it into a block. - pub async fn sign_and_submit_then_watch_default( - &self, - call: &Call, - signer: &Signer, - ) -> Result, Error> - where - Call: TxPayload, - Signer: SignerT, - >::OtherParams: Default, - { - self.sign_and_submit_then_watch(call, signer, Default::default()).await - } - /// Creates and signs an extrinsic and submits it to the chain. - /// - /// Returns a [`TxProgress`], which can be used to track the status of the transaction - /// and obtain details about it, once it has made it into a block. - pub async fn sign_and_submit_then_watch( - &self, - call: &Call, - signer: &Signer, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - Signer: SignerT, - { - self.create_signed(call, signer, other_params) - .await? - .submit_and_watch() - .await - } - /// Creates and signs an extrinsic and submits to the chain for block inclusion. Passes - /// default parameters to construct the "signed extra" and "additional" payloads needed - /// by the extrinsic. - /// - /// Returns `Ok` with the extrinsic hash if it is valid extrinsic. - /// - /// # Note - /// - /// Success does not mean the extrinsic has been included in the block, just that it is valid - /// and has been included in the transaction pool. - pub async fn sign_and_submit_default( - &self, - call: &Call, - signer: &Signer, - ) -> Result - where - Call: TxPayload, - Signer: SignerT, - >::OtherParams: Default, - { - self.sign_and_submit(call, signer, Default::default()).await - } - /// Creates and signs an extrinsic and submits to the chain for block inclusion. - /// - /// Returns `Ok` with the extrinsic hash if it is valid extrinsic. - /// - /// # Note - /// - /// Success does not mean the extrinsic has been included in the block, just that it is valid - /// and has been included in the transaction pool. - pub async fn sign_and_submit( - &self, - call: &Call, - signer: &Signer, - other_params: >::OtherParams, - ) -> Result - where - Call: TxPayload, - Signer: SignerT, - { - self.create_signed(call, signer, other_params).await?.submit().await - } - } - /// This payload contains the information needed to produce an extrinsic. - pub struct PartialExtrinsic { - client: C, - call_data: Vec, - additional_and_extra_params: T::ExtrinsicParams, - } - impl PartialExtrinsic - where - T: Config, - C: OfflineClientT, - { - fn with_signer_payload(&self, f: F) -> R - where - F: for<'a> FnOnce(Cow<'a, [u8]>) -> R, - { - let mut bytes = self.call_data.clone(); - self.additional_and_extra_params.encode_extra_to(&mut bytes); - self.additional_and_extra_params.encode_additional_to(&mut bytes); - if bytes.len() > 256 { - f(Cow::Borrowed(blake2_256(&bytes).as_ref())) - } else { - f(Cow::Owned(bytes)) - } - } - /// Return the signer payload for this extrinsic. These are the bytes that must - /// be signed in order to produce a valid signature for the extrinsic. - pub fn signer_payload(&self) -> Vec { - self.with_signer_payload(|bytes| bytes.to_vec()) - } - /// Return the bytes representing the call data for this partially constructed - /// extrinsic. - pub fn call_data(&self) -> &[u8] { - &self.call_data - } - /// Convert this [`PartialExtrinsic`] into a [`SubmittableExtrinsic`], ready to submit. - /// The provided `signer` is responsible for providing the "from" address for the transaction, - /// as well as providing a signature to attach to it. - pub fn sign(&self, signer: &Signer) -> SubmittableExtrinsic - where - Signer: SignerT, - { - let signature = self.with_signer_payload(|bytes| signer.sign(&bytes)); - self.sign_with_address_and_signature(&signer.address(), &signature) - } - /// Convert this [`PartialExtrinsic`] into a [`SubmittableExtrinsic`], ready to submit. - /// An address, and something representing a signature that can be SCALE encoded, are both - /// needed in order to construct it. If you have a `Signer` to hand, you can use - /// [`PartialExtrinsic::sign()`] instead. - pub fn sign_with_address_and_signature( - &self, - address: &T::Address, - signature: &T::Signature, - ) -> SubmittableExtrinsic { - let extrinsic = { - let mut encoded_inner = Vec::new(); - (0b10000000 + 4u8).encode_to(&mut encoded_inner); - address.encode_to(&mut encoded_inner); - signature.encode_to(&mut encoded_inner); - self.additional_and_extra_params.encode_extra_to(&mut encoded_inner); - encoded_inner.extend(&self.call_data); - let len = Compact( - u32::try_from(encoded_inner.len()) - .expect("extrinsic size expected to be <4GB"), - ); - let mut encoded = Vec::new(); - len.encode_to(&mut encoded); - encoded.extend(encoded_inner); - encoded - }; - SubmittableExtrinsic::from_bytes(self.client.clone(), extrinsic) - } - } - /// This represents an extrinsic that has been signed and is ready to submit. - pub struct SubmittableExtrinsic { - client: C, - encoded: Encoded, - marker: std::marker::PhantomData, - } - impl SubmittableExtrinsic - where - T: Config, - C: OfflineClientT, - { - /// Create a [`SubmittableExtrinsic`] from some already-signed and prepared - /// extrinsic bytes, and some client (anything implementing [`OfflineClientT`] - /// or [`OnlineClientT`]). - /// - /// Prefer to use [`TxClient`] to create and sign extrinsics. This is simply - /// exposed in case you want to skip this process and submit something you've - /// already created. - pub fn from_bytes(client: C, tx_bytes: Vec) -> Self { - Self { - client, - encoded: Encoded(tx_bytes), - marker: std::marker::PhantomData, - } - } - /// Calculate and return the hash of the extrinsic, based on the configured hasher. - pub fn hash(&self) -> T::Hash { - T::Hasher::hash_of(&self.encoded) - } - /// Returns the SCALE encoded extrinsic bytes. - pub fn encoded(&self) -> &[u8] { - &self.encoded.0 - } - /// Consumes [`SubmittableExtrinsic`] and returns the SCALE encoded - /// extrinsic bytes. - pub fn into_encoded(self) -> Vec { - self.encoded.0 - } - } - impl SubmittableExtrinsic - where - T: Config, - C: OnlineClientT, - { - /// Submits the extrinsic to the chain. - /// - /// Returns a [`TxProgress`], which can be used to track the status of the transaction - /// and obtain details about it, once it has made it into a block. - pub async fn submit_and_watch(&self) -> Result, Error> { - let ext_hash = self.hash(); - let sub = self - .client - .backend() - .submit_transaction(&self.encoded.0) - .await?; - Ok(TxProgress::new(sub, self.client.clone(), ext_hash)) - } - /// Submits the extrinsic to the chain for block inclusion. - /// - /// It's usually better to call `submit_and_watch` to get an idea of the progress of the - /// submission and whether it's eventually successful or not. This call does not guarantee - /// success, and is just sending the transaction to the chain. - pub async fn submit(&self) -> Result { - let ext_hash = self.hash(); - let mut sub = self - .client - .backend() - .submit_transaction(&self.encoded.0) - .await?; - match sub.next().await { - Some(Ok(status)) => { - match status { - TransactionStatus::Validated - | TransactionStatus::Broadcasted { .. } - | TransactionStatus::InBestBlock { .. } - | TransactionStatus::NoLongerInBestBlock - | TransactionStatus::InFinalizedBlock { .. } => Ok(ext_hash), - TransactionStatus::Error { message } => { - Err( - Error::Other({ - let res = ::alloc::fmt::format( - format_args!("Transaction error: {0}", message), - ); - res - }), - ) - } - TransactionStatus::Invalid { message } => { - Err( - Error::Other({ - let res = ::alloc::fmt::format( - format_args!("Transaction invalid: {0}", message), - ); - res - }), - ) - } - TransactionStatus::Dropped { message } => { - Err( - Error::Other({ - let res = ::alloc::fmt::format( - format_args!("Transaction dropped: {0}", message), - ); - res - }), - ) - } - } - } - Some(Err(e)) => Err(e), - None => { - Err( - Error::Other( - "Transaction broadcast was unsuccessful; stream terminated early" - .into(), - ), - ) - } - } - } - /// Validate a transaction by submitting it to the relevant Runtime API. A transaction that is - /// valid can be added to a block, but may still end up in an error state. - /// - /// Returns `Ok` with a [`ValidationResult`], which is the result of attempting to dry run the extrinsic. - pub async fn validate(&self) -> Result { - let latest_block_ref = self - .client - .backend() - .latest_finalized_block_ref() - .await?; - self.validate_at(latest_block_ref).await - } - /// Validate a transaction by submitting it to the relevant Runtime API. A transaction that is - /// valid can be added to a block, but may still end up in an error state. - /// - /// Returns `Ok` with a [`ValidationResult`], which is the result of attempting to dry run the extrinsic. - pub async fn validate_at( - &self, - at: impl Into>, - ) -> Result { - let block_hash = at.into().hash(); - let mut params = Vec::with_capacity(8 + self.encoded.0.len() + 8); - 2u8.encode_to(&mut params); - params.extend(self.encoded().iter()); - block_hash.encode_to(&mut params); - let res: Vec = self - .client - .backend() - .call( - "TaggedTransactionQueue_validate_transaction", - Some(¶ms), - block_hash, - ) - .await?; - ValidationResult::try_from_bytes(res) - } - /// This returns an estimate for what the extrinsic is expected to cost to execute, less any tips. - /// The actual amount paid can vary from block to block based on node traffic and other factors. - pub async fn partial_fee_estimate(&self) -> Result { - let mut params = self.encoded().to_vec(); - (self.encoded().len() as u32).encode_to(&mut params); - let latest_block_ref = self - .client - .backend() - .latest_finalized_block_ref() - .await?; - let (_, _, _, partial_fee) = self - .client - .backend() - .call_decoding::< - (Compact, Compact, u8, u128), - >( - "TransactionPaymentApi_query_info", - Some(¶ms), - latest_block_ref.hash(), - ) - .await?; - Ok(partial_fee) - } - } - impl ValidationResult { - #[allow(clippy::get_first)] - fn try_from_bytes(bytes: Vec) -> Result { - if bytes.get(0) == Some(&0) { - let res = TransactionValid::decode(&mut &bytes[1..])?; - Ok(ValidationResult::Valid(res)) - } else if bytes.get(0) == Some(&1) && bytes.get(1) == Some(&0) { - let res = TransactionInvalid::decode(&mut &bytes[2..])?; - Ok(ValidationResult::Invalid(res)) - } else if bytes.get(0) == Some(&1) && bytes.get(1) == Some(&1) { - let res = TransactionUnknown::decode(&mut &bytes[2..])?; - Ok(ValidationResult::Unknown(res)) - } else { - Err(crate::Error::Unknown(bytes)) - } - } - } - /// The result of performing [`SubmittableExtrinsic::validate()`]. - pub enum ValidationResult { - /// The transaction is valid - Valid(TransactionValid), - /// The transaction is invalid - Invalid(TransactionInvalid), - /// Unable to validate the transaction - Unknown(TransactionUnknown), - } - #[automatically_derived] - impl ::core::clone::Clone for ValidationResult { - #[inline] - fn clone(&self) -> ValidationResult { - match self { - ValidationResult::Valid(__self_0) => { - ValidationResult::Valid(::core::clone::Clone::clone(__self_0)) - } - ValidationResult::Invalid(__self_0) => { - ValidationResult::Invalid(::core::clone::Clone::clone(__self_0)) - } - ValidationResult::Unknown(__self_0) => { - ValidationResult::Unknown(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ValidationResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - ValidationResult::Valid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Valid", - &__self_0, - ) - } - ValidationResult::Invalid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Invalid", - &__self_0, - ) - } - ValidationResult::Unknown(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Unknown", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ValidationResult {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ValidationResult { - #[inline] - fn eq(&self, other: &ValidationResult) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - ValidationResult::Valid(__self_0), - ValidationResult::Valid(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - ValidationResult::Invalid(__self_0), - ValidationResult::Invalid(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - ValidationResult::Unknown(__self_0), - ValidationResult::Unknown(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - impl ValidationResult { - /// Is the transaction valid. - pub fn is_valid(&self) -> bool { - match self { - ValidationResult::Valid(_) => true, - _ => false, - } - } - } - /// Transaction is valid; here is some more information about it. - pub struct TransactionValid { - /// Priority of the transaction. - /// - /// Priority determines the ordering of two transactions that have all - /// their dependencies (required tags) satisfied. - pub priority: u64, - /// Transaction dependencies - /// - /// A non-empty list signifies that some other transactions which provide - /// given tags are required to be included before that one. - pub requires: Vec>, - /// Provided tags - /// - /// A list of tags this transaction provides. Successfully importing the transaction - /// will enable other transactions that depend on (require) those tags to be included as well. - /// Provided and required tags allow Substrate to build a dependency graph of transactions - /// and import them in the right (linear) order. - pub provides: Vec>, - /// Transaction longevity - /// - /// Longevity describes minimum number of blocks the validity is correct. - /// After this period transaction should be removed from the pool or revalidated. - pub longevity: u64, - /// A flag indicating if the transaction should be propagated to other peers. - /// - /// By setting `false` here the transaction will still be considered for - /// including in blocks that are authored on the current node, but will - /// never be sent to other peers. - pub propagate: bool, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for TransactionValid { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(TransactionValid { - priority: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::priority`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - requires: { - let __codec_res_edqy = , - > as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::requires`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - provides: { - let __codec_res_edqy = , - > as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::provides`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - longevity: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::longevity`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - propagate: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::propagate`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for TransactionValid { - #[inline] - fn clone(&self) -> TransactionValid { - TransactionValid { - priority: ::core::clone::Clone::clone(&self.priority), - requires: ::core::clone::Clone::clone(&self.requires), - provides: ::core::clone::Clone::clone(&self.provides), - longevity: ::core::clone::Clone::clone(&self.longevity), - propagate: ::core::clone::Clone::clone(&self.propagate), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionValid { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "TransactionValid", - "priority", - &self.priority, - "requires", - &self.requires, - "provides", - &self.provides, - "longevity", - &self.longevity, - "propagate", - &&self.propagate, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionValid {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionValid { - #[inline] - fn eq(&self, other: &TransactionValid) -> bool { - self.priority == other.priority && self.requires == other.requires - && self.provides == other.provides - && self.longevity == other.longevity - && self.propagate == other.propagate - } - } - /// The runtime was unable to validate the transaction. - pub enum TransactionUnknown { - /// Could not lookup some information that is required to validate the transaction. - CannotLookup, - /// No validator found for the given unsigned transaction. - NoUnsignedValidator, - /// Any other custom unknown validity that is not covered by this enum. - Custom(u8), - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for TransactionUnknown { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `TransactionUnknown`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionUnknown::CannotLookup) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionUnknown::NoUnsignedValidator, - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionUnknown::Custom({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionUnknown::Custom.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `TransactionUnknown`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for TransactionUnknown { - #[inline] - fn clone(&self) -> TransactionUnknown { - match self { - TransactionUnknown::CannotLookup => TransactionUnknown::CannotLookup, - TransactionUnknown::NoUnsignedValidator => { - TransactionUnknown::NoUnsignedValidator - } - TransactionUnknown::Custom(__self_0) => { - TransactionUnknown::Custom(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionUnknown { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionUnknown::CannotLookup => { - ::core::fmt::Formatter::write_str(f, "CannotLookup") - } - TransactionUnknown::NoUnsignedValidator => { - ::core::fmt::Formatter::write_str(f, "NoUnsignedValidator") - } - TransactionUnknown::Custom(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Custom", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionUnknown {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionUnknown { - #[inline] - fn eq(&self, other: &TransactionUnknown) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionUnknown::Custom(__self_0), - TransactionUnknown::Custom(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - /// The transaction is invalid. - pub enum TransactionInvalid { - /// The call of the transaction is not expected. - Call, - /// General error to do with the inability to pay some fees (e.g. account balance too low). - Payment, - /// General error to do with the transaction not yet being valid (e.g. nonce too high). - Future, - /// General error to do with the transaction being outdated (e.g. nonce too low). - Stale, - /// General error to do with the transaction's proofs (e.g. signature). - /// - /// # Possible causes - /// - /// When using a signed extension that provides additional data for signing, it is required - /// that the signing and the verifying side use the same additional data. Additional - /// data will only be used to generate the signature, but will not be part of the transaction - /// itself. As the verifying side does not know which additional data was used while signing - /// it will only be able to assume a bad signature and cannot express a more meaningful error. - BadProof, - /// The transaction birth block is ancient. - /// - /// # Possible causes - /// - /// For `FRAME`-based runtimes this would be caused by `current block number - /// - Era::birth block number > BlockHashCount`. (e.g. in Polkadot `BlockHashCount` = 2400, so - /// a - /// transaction with birth block number 1337 would be valid up until block number 1337 + 2400, - /// after which point the transaction would be considered to have an ancient birth block.) - AncientBirthBlock, - /// The transaction would exhaust the resources of current block. - /// - /// The transaction might be valid, but there are not enough resources - /// left in the current block. - ExhaustsResources, - /// Any other custom invalid validity that is not covered by this enum. - Custom(u8), - /// An extrinsic with a Mandatory dispatch resulted in Error. This is indicative of either a - /// malicious validator or a buggy `provide_inherent`. In any case, it can result in - /// dangerously overweight blocks and therefore if found, invalidates the block. - BadMandatory, - /// An extrinsic with a mandatory dispatch tried to be validated. - /// This is invalid; only inherent extrinsics are allowed to have mandatory dispatches. - MandatoryValidation, - /// The sending address is disabled or known to be invalid. - BadSigner, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for TransactionInvalid { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `TransactionInvalid`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::Call) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::Payment) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::Future) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 3usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::Stale) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 4usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::BadProof) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 5usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionInvalid::AncientBirthBlock, - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 6usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionInvalid::ExhaustsResources, - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 7usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionInvalid::Custom({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionInvalid::Custom.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 8usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::BadMandatory) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 9usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionInvalid::MandatoryValidation, - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 10usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::BadSigner) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `TransactionInvalid`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for TransactionInvalid { - #[inline] - fn clone(&self) -> TransactionInvalid { - match self { - TransactionInvalid::Call => TransactionInvalid::Call, - TransactionInvalid::Payment => TransactionInvalid::Payment, - TransactionInvalid::Future => TransactionInvalid::Future, - TransactionInvalid::Stale => TransactionInvalid::Stale, - TransactionInvalid::BadProof => TransactionInvalid::BadProof, - TransactionInvalid::AncientBirthBlock => { - TransactionInvalid::AncientBirthBlock - } - TransactionInvalid::ExhaustsResources => { - TransactionInvalid::ExhaustsResources - } - TransactionInvalid::Custom(__self_0) => { - TransactionInvalid::Custom(::core::clone::Clone::clone(__self_0)) - } - TransactionInvalid::BadMandatory => TransactionInvalid::BadMandatory, - TransactionInvalid::MandatoryValidation => { - TransactionInvalid::MandatoryValidation - } - TransactionInvalid::BadSigner => TransactionInvalid::BadSigner, - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionInvalid { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionInvalid::Call => { - ::core::fmt::Formatter::write_str(f, "Call") - } - TransactionInvalid::Payment => { - ::core::fmt::Formatter::write_str(f, "Payment") - } - TransactionInvalid::Future => { - ::core::fmt::Formatter::write_str(f, "Future") - } - TransactionInvalid::Stale => { - ::core::fmt::Formatter::write_str(f, "Stale") - } - TransactionInvalid::BadProof => { - ::core::fmt::Formatter::write_str(f, "BadProof") - } - TransactionInvalid::AncientBirthBlock => { - ::core::fmt::Formatter::write_str(f, "AncientBirthBlock") - } - TransactionInvalid::ExhaustsResources => { - ::core::fmt::Formatter::write_str(f, "ExhaustsResources") - } - TransactionInvalid::Custom(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Custom", - &__self_0, - ) - } - TransactionInvalid::BadMandatory => { - ::core::fmt::Formatter::write_str(f, "BadMandatory") - } - TransactionInvalid::MandatoryValidation => { - ::core::fmt::Formatter::write_str(f, "MandatoryValidation") - } - TransactionInvalid::BadSigner => { - ::core::fmt::Formatter::write_str(f, "BadSigner") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionInvalid {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionInvalid { - #[inline] - fn eq(&self, other: &TransactionInvalid) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionInvalid::Custom(__self_0), - TransactionInvalid::Custom(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - } - mod tx_payload { - //! This module contains the trait and types used to represent - //! transactions that can be submitted. - use crate::{ - dynamic::Value, error::{Error, MetadataError}, - metadata::Metadata, - }; - use codec::Encode; - use derivative::Derivative; - use scale_encode::EncodeAsFields; - use scale_value::{Composite, ValueDef, Variant}; - use std::{borrow::Cow, sync::Arc}; - /// This represents a transaction payload that can be submitted - /// to a node. - pub trait TxPayload { - /// Encode call data to the provided output. - fn encode_call_data_to( - &self, - metadata: &Metadata, - out: &mut Vec, - ) -> Result<(), Error>; - /// Encode call data and return the output. This is a convenience - /// wrapper around [`TxPayload::encode_call_data_to`]. - fn encode_call_data(&self, metadata: &Metadata) -> Result, Error> { - let mut v = Vec::new(); - self.encode_call_data_to(metadata, &mut v)?; - Ok(v) - } - /// Returns the details needed to validate the call, which - /// include a statically generated hash, the pallet name, - /// and the call name. - fn validation_details(&self) -> Option> { - None - } - } - pub struct ValidationDetails<'a> { - /// The pallet name. - pub pallet_name: &'a str, - /// The call name. - pub call_name: &'a str, - /// A hash (this is generated at compile time in our codegen) - /// to compare against the runtime code. - pub hash: [u8; 32], - } - /// A transaction payload containing some generic `CallData`. - #[derivative( - Clone(bound = "CallData: Clone"), - Debug(bound = "CallData: std::fmt::Debug"), - Eq(bound = "CallData: std::cmp::Eq"), - Ord(bound = "CallData: std::cmp::Ord"), - PartialEq(bound = "CallData: std::cmp::PartialEq"), - PartialOrd(bound = "CallData: std::cmp::PartialOrd") - )] - pub struct Payload { - pallet_name: Cow<'static, str>, - call_name: Cow<'static, str>, - call_data: CallData, - validation_hash: Option<[u8; 32]>, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Payload - where - CallData: Clone, - { - fn clone(&self) -> Self { - match *self { - Payload { - pallet_name: ref __arg_0, - call_name: ref __arg_1, - call_data: ref __arg_2, - validation_hash: ref __arg_3, - } => { - Payload { - pallet_name: (*__arg_0).clone(), - call_name: (*__arg_1).clone(), - call_data: (*__arg_2).clone(), - validation_hash: (*__arg_3).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Payload - where - CallData: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Payload { - pallet_name: ref __arg_0, - call_name: ref __arg_1, - call_data: ref __arg_2, - validation_hash: ref __arg_3, - } => { - let mut __debug_trait_builder = __f.debug_struct("Payload"); - let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); - let _ = __debug_trait_builder.field("call_name", &&(*__arg_1)); - let _ = __debug_trait_builder.field("call_data", &&(*__arg_2)); - let _ = __debug_trait_builder - .field("validation_hash", &&(*__arg_3)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for Payload - where - CallData: std::cmp::Eq, - {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for Payload - where - CallData: std::cmp::PartialEq, - { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - Payload { - pallet_name: ref __self_0, - call_name: ref __self_1, - call_data: ref __self_2, - validation_hash: ref __self_3, - } => { - match *other { - Payload { - pallet_name: ref __other_0, - call_name: ref __other_1, - call_data: ref __other_2, - validation_hash: ref __other_3, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - && &(*__self_3) == &(*__other_3) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialOrd for Payload - where - CallData: std::cmp::PartialOrd, - { - fn partial_cmp( - &self, - other: &Self, - ) -> ::std::option::Option<::std::cmp::Ordering> { - match *self { - Payload { - pallet_name: ref __self_0, - call_name: ref __self_1, - call_data: ref __self_2, - validation_hash: ref __self_3, - } => { - match *other { - Payload { - pallet_name: ref __other_0, - call_name: ref __other_1, - call_data: ref __other_2, - validation_hash: ref __other_3, - } => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_0), - &(*__other_0), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_1), - &(*__other_1), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_2), - &(*__other_2), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_3), - &(*__other_3), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::Ord for Payload - where - CallData: std::cmp::Ord, - { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - Payload { - pallet_name: ref __self_0, - call_name: ref __self_1, - call_data: ref __self_2, - validation_hash: ref __self_3, - } => { - match *other { - Payload { - pallet_name: ref __other_0, - call_name: ref __other_1, - call_data: ref __other_2, - validation_hash: ref __other_3, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - /// A boxed transaction payload. - pub type BoxedPayload = Payload>; - /// The type of a payload typically used for dynamic transaction payloads. - pub type DynamicPayload = Payload>; - impl Payload { - /// Create a new [`Payload`]. - pub fn new( - pallet_name: impl Into, - call_name: impl Into, - call_data: CallData, - ) -> Self { - Payload { - pallet_name: Cow::Owned(pallet_name.into()), - call_name: Cow::Owned(call_name.into()), - call_data, - validation_hash: None, - } - } - /// Create a new [`Payload`] using static strings for the pallet and call name. - /// This is only expected to be used from codegen. - #[doc(hidden)] - pub fn new_static( - pallet_name: &'static str, - call_name: &'static str, - call_data: CallData, - validation_hash: [u8; 32], - ) -> Self { - Payload { - pallet_name: Cow::Borrowed(pallet_name), - call_name: Cow::Borrowed(call_name), - call_data, - validation_hash: Some(validation_hash), - } - } - /// Box the payload. - pub fn boxed(self) -> BoxedPayload - where - CallData: EncodeAsFields + Send + Sync + 'static, - { - BoxedPayload { - pallet_name: self.pallet_name, - call_name: self.call_name, - call_data: Arc::new(self.call_data), - validation_hash: self.validation_hash, - } - } - /// Do not validate this call prior to submitting it. - pub fn unvalidated(self) -> Self { - Self { - validation_hash: None, - ..self - } - } - /// Returns the call data. - pub fn call_data(&self) -> &CallData { - &self.call_data - } - /// Returns the pallet name. - pub fn pallet_name(&self) -> &str { - &self.pallet_name - } - /// Returns the call name. - pub fn call_name(&self) -> &str { - &self.call_name - } - } - impl Payload> { - /// Convert the dynamic `Composite` payload into a [`Value`]. - /// This is useful if you want to use this as an argument for a - /// larger dynamic call that wants to use this as a nested call. - pub fn into_value(self) -> Value<()> { - let call = Value { - context: (), - value: ValueDef::Variant(Variant { - name: self.call_name.into_owned(), - values: self.call_data, - }), - }; - Value::unnamed_variant(self.pallet_name, [call]) - } - } - impl TxPayload for Payload { - fn encode_call_data_to( - &self, - metadata: &Metadata, - out: &mut Vec, - ) -> Result<(), Error> { - let pallet = metadata.pallet_by_name_err(&self.pallet_name)?; - let call = pallet - .call_variant_by_name(&self.call_name) - .ok_or_else(|| MetadataError::CallNameNotFound( - (*self.call_name).to_owned(), - ))?; - let pallet_index = pallet.index(); - let call_index = call.index; - pallet_index.encode_to(out); - call_index.encode_to(out); - let mut fields = call - .fields - .iter() - .map(|f| scale_encode::Field::new(f.ty.id, f.name.as_deref())); - self.call_data.encode_as_fields_to(&mut fields, metadata.types(), out)?; - Ok(()) - } - fn validation_details(&self) -> Option> { - self.validation_hash - .map(|hash| ValidationDetails { - pallet_name: &self.pallet_name, - call_name: &self.call_name, - hash, - }) - } - } - /// Construct a transaction at runtime; essentially an alias to [`Payload::new()`] - /// which provides a [`Composite`] value for the call data. - pub fn dynamic( - pallet_name: impl Into, - call_name: impl Into, - call_data: impl Into>, - ) -> DynamicPayload { - Payload::new(pallet_name, call_name, call_data.into()) - } - } - mod tx_progress { - //! Types representing extrinsics/transactions that have been submitted to a node. - use std::task::Poll; - use crate::utils::strip_compact_prefix; - use crate::{ - backend::{BlockRef, StreamOfResults, TransactionStatus as BackendTxStatus}, - client::OnlineClientT, - error::{DispatchError, Error, RpcError, TransactionError}, - events::EventsClient, Config, - }; - use derivative::Derivative; - use futures::{Stream, StreamExt}; - /// This struct represents a subscription to the progress of some transaction. - pub struct TxProgress { - sub: Option>>, - ext_hash: T::Hash, - client: C, - } - impl std::fmt::Debug for TxProgress { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("TxProgress") - .field("sub", &"") - .field("ext_hash", &self.ext_hash) - .field("client", &"") - .finish() - } - } - impl Unpin for TxProgress {} - impl TxProgress { - /// Instantiate a new [`TxProgress`] from a custom subscription. - pub fn new( - sub: StreamOfResults>, - client: C, - ext_hash: T::Hash, - ) -> Self { - Self { - sub: Some(sub), - client, - ext_hash, - } - } - /// Return the hash of the extrinsic. - pub fn extrinsic_hash(&self) -> T::Hash { - self.ext_hash - } - } - impl TxProgress - where - T: Config, - C: OnlineClientT, - { - /// Return the next transaction status when it's emitted. This just delegates to the - /// [`futures::Stream`] implementation for [`TxProgress`], but allows you to - /// avoid importing that trait if you don't otherwise need it. - pub async fn next(&mut self) -> Option, Error>> { - StreamExt::next(self).await - } - /// Wait for the transaction to be finalized, and return a [`TxInBlock`] - /// instance when it is, or an error if there was a problem waiting for finalization. - /// - /// **Note:** consumes `self`. If you'd like to perform multiple actions as the state of the - /// transaction progresses, use [`TxProgress::next()`] instead. - /// - /// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some - /// probability that the transaction will not make it into a block but there is no guarantee - /// that this is true. In those cases the stream is closed however, so you currently have no way to find - /// out if they finally made it into a block or not. - pub async fn wait_for_finalized(mut self) -> Result, Error> { - while let Some(status) = self.next().await { - match status? { - TxStatus::InFinalizedBlock(s) => return Ok(s), - TxStatus::Error { message } => { - return Err(TransactionError::Error(message).into()); - } - TxStatus::Invalid { message } => { - return Err(TransactionError::Invalid(message).into()); - } - TxStatus::Dropped { message } => { - return Err(TransactionError::Dropped(message).into()); - } - _ => continue, - } - } - Err(RpcError::SubscriptionDropped.into()) - } - /// Wait for the transaction to be finalized, and for the transaction events to indicate - /// that the transaction was successful. Returns the events associated with the transaction, - /// as well as a couple of other details (block hash and extrinsic hash). - /// - /// **Note:** consumes self. If you'd like to perform multiple actions as progress is made, - /// use [`TxProgress::next()`] instead. - /// - /// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some - /// probability that the transaction will not make it into a block but there is no guarantee - /// that this is true. In those cases the stream is closed however, so you currently have no way to find - /// out if they finally made it into a block or not. - pub async fn wait_for_finalized_success( - self, - ) -> Result, Error> { - let evs = self.wait_for_finalized().await?.wait_for_success().await?; - Ok(evs) - } - } - impl Stream for TxProgress { - type Item = Result, Error>; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - let sub = match self.sub.as_mut() { - Some(sub) => sub, - None => return Poll::Ready(None), - }; - sub.poll_next_unpin(cx) - .map_ok(|status| { - match status { - BackendTxStatus::Validated => TxStatus::Validated, - BackendTxStatus::Broadcasted { num_peers } => { - TxStatus::Broadcasted { num_peers } - } - BackendTxStatus::NoLongerInBestBlock => { - TxStatus::NoLongerInBestBlock - } - BackendTxStatus::InBestBlock { hash } => { - TxStatus::InBestBlock( - TxInBlock::new(hash, self.ext_hash, self.client.clone()), - ) - } - BackendTxStatus::InFinalizedBlock { hash } => { - self.sub = None; - TxStatus::InFinalizedBlock( - TxInBlock::new(hash, self.ext_hash, self.client.clone()), - ) - } - BackendTxStatus::Error { message } => { - self.sub = None; - TxStatus::Error { message } - } - BackendTxStatus::Invalid { message } => { - self.sub = None; - TxStatus::Invalid { message } - } - BackendTxStatus::Dropped { message } => { - self.sub = None; - TxStatus::Dropped { message } - } - } - }) - } - } - /// Possible transaction statuses returned from our [`TxProgress::next()`] call. - #[derivative(Debug(bound = "C: std::fmt::Debug"))] - pub enum TxStatus { - /// Transaction is part of the future queue. - Validated, - /// The transaction has been broadcast to other nodes. - Broadcasted { - /// Number of peers it's been broadcast to. - num_peers: u32, - }, - /// Transaction is no longer in a best block. - NoLongerInBestBlock, - /// Transaction has been included in block with given hash. - InBestBlock(TxInBlock), - /// Transaction has been finalized by a finality-gadget, e.g GRANDPA - InFinalizedBlock(TxInBlock), - /// Something went wrong in the node. - Error { - /// Human readable message; what went wrong. - message: String, - }, - /// Transaction is invalid (bad nonce, signature etc). - Invalid { - /// Human readable message; why was it invalid. - message: String, - }, - /// The transaction was dropped. - Dropped { - /// Human readable message; why was it dropped. - message: String, - }, - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for TxStatus - where - C: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - TxStatus::Validated => { - let mut __debug_trait_builder = __f.debug_tuple("Validated"); - __debug_trait_builder.finish() - } - TxStatus::Broadcasted { num_peers: ref __arg_0 } => { - let mut __debug_trait_builder = __f.debug_struct("Broadcasted"); - let _ = __debug_trait_builder.field("num_peers", &&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::NoLongerInBestBlock => { - let mut __debug_trait_builder = __f - .debug_tuple("NoLongerInBestBlock"); - __debug_trait_builder.finish() - } - TxStatus::InBestBlock(ref __arg_0) => { - let mut __debug_trait_builder = __f.debug_tuple("InBestBlock"); - let _ = __debug_trait_builder.field(&&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::InFinalizedBlock(ref __arg_0) => { - let mut __debug_trait_builder = __f - .debug_tuple("InFinalizedBlock"); - let _ = __debug_trait_builder.field(&&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::Error { message: ref __arg_0 } => { - let mut __debug_trait_builder = __f.debug_struct("Error"); - let _ = __debug_trait_builder.field("message", &&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::Invalid { message: ref __arg_0 } => { - let mut __debug_trait_builder = __f.debug_struct("Invalid"); - let _ = __debug_trait_builder.field("message", &&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::Dropped { message: ref __arg_0 } => { - let mut __debug_trait_builder = __f.debug_struct("Dropped"); - let _ = __debug_trait_builder.field("message", &&(*__arg_0)); - __debug_trait_builder.finish() - } - } - } - } - impl TxStatus { - /// A convenience method to return the finalized details. Returns - /// [`None`] if the enum variant is not [`TxStatus::InFinalizedBlock`]. - pub fn as_finalized(&self) -> Option<&TxInBlock> { - match self { - Self::InFinalizedBlock(val) => Some(val), - _ => None, - } - } - /// A convenience method to return the best block details. Returns - /// [`None`] if the enum variant is not [`TxStatus::InBestBlock`]. - pub fn as_in_block(&self) -> Option<&TxInBlock> { - match self { - Self::InBestBlock(val) => Some(val), - _ => None, - } - } - } - /// This struct represents a transaction that has made it into a block. - #[derivative(Debug(bound = "C: std::fmt::Debug"))] - pub struct TxInBlock { - block_ref: BlockRef, - ext_hash: T::Hash, - client: C, - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for TxInBlock - where - C: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - TxInBlock { - block_ref: ref __arg_0, - ext_hash: ref __arg_1, - client: ref __arg_2, - } => { - let mut __debug_trait_builder = __f.debug_struct("TxInBlock"); - let _ = __debug_trait_builder.field("block_ref", &&(*__arg_0)); - let _ = __debug_trait_builder.field("ext_hash", &&(*__arg_1)); - let _ = __debug_trait_builder.field("client", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - impl TxInBlock { - pub(crate) fn new( - block_ref: BlockRef, - ext_hash: T::Hash, - client: C, - ) -> Self { - Self { - block_ref, - ext_hash, - client, - } - } - /// Return the hash of the block that the transaction has made it into. - pub fn block_hash(&self) -> T::Hash { - self.block_ref.hash() - } - /// Return the hash of the extrinsic that was submitted. - pub fn extrinsic_hash(&self) -> T::Hash { - self.ext_hash - } - } - impl> TxInBlock { - /// Fetch the events associated with this transaction. If the transaction - /// was successful (ie no `ExtrinsicFailed`) events were found, then we return - /// the events associated with it. If the transaction was not successful, or - /// something else went wrong, we return an error. - /// - /// **Note:** If multiple `ExtrinsicFailed` errors are returned (for instance - /// because a pallet chooses to emit one as an event, which is considered - /// abnormal behaviour), it is not specified which of the errors is returned here. - /// You can use [`TxInBlock::fetch_events`] instead if you'd like to - /// work with multiple "error" events. - /// - /// **Note:** This has to download block details from the node and decode events - /// from them. - pub async fn wait_for_success( - &self, - ) -> Result, Error> { - let events = self.fetch_events().await?; - for ev in events.iter() { - let ev = ev?; - if ev.pallet_name() == "System" - && ev.variant_name() == "ExtrinsicFailed" - { - let dispatch_error = DispatchError::decode_from( - ev.field_bytes(), - self.client.metadata(), - )?; - return Err(dispatch_error.into()); - } - } - Ok(events) - } - /// Fetch all of the events associated with this transaction. This succeeds whether - /// the transaction was a success or not; it's up to you to handle the error and - /// success events however you prefer. - /// - /// **Note:** This has to download block details from the node and decode events - /// from them. - pub async fn fetch_events( - &self, - ) -> Result, Error> { - let block_body = self - .client - .backend() - .block_body(self.block_ref.hash()) - .await? - .ok_or(Error::Transaction(TransactionError::BlockNotFound))?; - let extrinsic_idx = block_body - .iter() - .position(|ext| { - use crate::config::Hasher; - let Ok((_, stripped)) = strip_compact_prefix(ext) else { - return false; - }; - let hash = T::Hasher::hash_of(&stripped); - hash == self.ext_hash - }) - .ok_or(Error::Transaction(TransactionError::BlockNotFound))?; - let events = EventsClient::new(self.client.clone()) - .at(self.block_ref.clone()) - .await?; - Ok( - crate::blocks::ExtrinsicEvents::new( - self.ext_hash, - extrinsic_idx as u32, - events, - ), - ) - } - } - } - pub use self::{ - signer::Signer, - tx_client::{ - PartialExtrinsic, SubmittableExtrinsic, TransactionInvalid, - TransactionUnknown, TxClient, ValidationResult, - }, - tx_payload::{dynamic, BoxedPayload, DynamicPayload, Payload, TxPayload}, - tx_progress::{TxInBlock, TxProgress, TxStatus}, - }; -} -pub mod utils { - //! Miscellaneous utility helpers. - mod account_id { - //! The "default" Substrate/Polkadot AccountId. This is used in codegen, as well as signing related bits. - //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_core::AccountId32` - //! for instance, to gain functionality without forcing a dependency on Substrate crates here. - use codec::{Decode, Encode}; - use serde::{Deserialize, Serialize}; - /// A 32-byte cryptographic identifier. This is a simplified version of Substrate's - /// `sp_core::crypto::AccountId32`. To obtain more functionality, convert this into - /// that type. - pub struct AccountId32(pub [u8; 32]); - #[automatically_derived] - impl ::core::clone::Clone for AccountId32 { - #[inline] - fn clone(&self) -> AccountId32 { - AccountId32(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::cmp::Eq for AccountId32 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for AccountId32 {} - #[automatically_derived] - impl ::core::cmp::PartialEq for AccountId32 { - #[inline] - fn eq(&self, other: &AccountId32) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Ord for AccountId32 { - #[inline] - fn cmp(&self, other: &AccountId32) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for AccountId32 { - #[inline] - fn partial_cmp( - &self, - other: &AccountId32, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for AccountId32 { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.0) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.0) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.0, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike for AccountId32 {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for AccountId32 { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok( - AccountId32({ - let __codec_res_edqy = <[u8; 32] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `AccountId32.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for AccountId32 { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "AccountId32", - &&self.0, - ) - } - } - impl ::scale_encode::EncodeAsType for AccountId32 { - #[allow(unused_variables)] - fn encode_as_type_to( - &self, - __encode_as_type_type_id: u32, - __encode_as_type_types: &::scale_encode::PortableRegistry, - __encode_as_type_out: &mut ::scale_encode::Vec, - ) -> Result<(), ::scale_encode::Error> { - let AccountId32(_0) = self; - ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ) - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - } - impl ::scale_encode::EncodeAsFields for AccountId32 { - #[allow(unused_variables)] - fn encode_as_fields_to( - &self, - __encode_as_type_fields: &mut dyn ::scale_encode::FieldIter<'_>, - __encode_as_type_types: &::scale_encode::PortableRegistry, - __encode_as_type_out: &mut ::scale_encode::Vec, - ) -> Result<(), ::scale_encode::Error> { - let AccountId32(_0) = self; - ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ) - .encode_as_fields_to( - __encode_as_type_fields, - __encode_as_type_types, - __encode_as_type_out, - ) - } - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for AccountId32 { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = AccountId32; - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_tuple(&mut value.as_tuple(), type_id) - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: value.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = value; - Ok( - AccountId32({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ) - } - } - impl ::scale_decode::DecodeAsFields for AccountId32 { - fn decode_as_fields<'info>( - input: &mut &[u8], - fields: &mut dyn ::scale_decode::FieldIter<'info>, - types: &'info ::scale_decode::PortableRegistry, - ) -> Result { - let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; - let mut composite = ::scale_decode::visitor::types::Composite::new( - input, - path, - fields, - types, - false, - ); - use ::scale_decode::{Visitor, IntoVisitor}; - let val = ::into_visitor() - .visit_composite( - &mut composite, - ::scale_decode::visitor::TypeId(0), - ); - composite.skip_decoding()?; - *input = composite.bytes_from_undecoded(); - val.map_err(From::from) - } - } - }; - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo for AccountId32 { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "AccountId32", - "subxt::utils::account_id", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .docs( - &[ - "A 32-byte cryptographic identifier. This is a simplified version of Substrate's", - "`sp_core::crypto::AccountId32`. To obtain more functionality, convert this into", - "that type.", - ], - ) - .composite( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 32]>().type_name("[u8; 32]")), - ) - } - } - }; - impl AsRef<[u8]> for AccountId32 { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } - } - impl AsRef<[u8; 32]> for AccountId32 { - fn as_ref(&self) -> &[u8; 32] { - &self.0 - } - } - impl From<[u8; 32]> for AccountId32 { - fn from(x: [u8; 32]) -> Self { - AccountId32(x) - } - } - impl AccountId32 { - fn to_ss58check(&self) -> String { - const SUBSTRATE_SS58_PREFIX: u8 = 42; - let mut v = <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([SUBSTRATE_SS58_PREFIX]), - ); - v.extend(self.0); - let r = ss58hash(&v); - v.extend(&r[0..2]); - use base58::ToBase58; - v.to_base58() - } - fn from_ss58check(s: &str) -> Result { - const CHECKSUM_LEN: usize = 2; - let body_len = 32; - use base58::FromBase58; - let data = s.from_base58().map_err(|_| FromSs58Error::BadBase58)?; - if data.len() < 2 { - return Err(FromSs58Error::BadLength); - } - let prefix_len = match data[0] { - 0..=63 => 1, - 64..=127 => 2, - _ => return Err(FromSs58Error::InvalidPrefix), - }; - if data.len() != prefix_len + body_len + CHECKSUM_LEN { - return Err(FromSs58Error::BadLength); - } - let hash = ss58hash(&data[0..body_len + prefix_len]); - let checksum = &hash[0..CHECKSUM_LEN]; - if data[body_len + prefix_len..body_len + prefix_len + CHECKSUM_LEN] - != *checksum - { - return Err(FromSs58Error::InvalidChecksum); - } - let result = data[prefix_len..body_len + prefix_len] - .try_into() - .map_err(|_| FromSs58Error::BadLength)?; - Ok(AccountId32(result)) - } - } - /// An error obtained from trying to interpret an SS58 encoded string into an AccountId32 - #[allow(missing_docs)] - pub enum FromSs58Error { - #[error("Base 58 requirement is violated")] - BadBase58, - #[error("Length is bad")] - BadLength, - #[error("Invalid checksum")] - InvalidChecksum, - #[error("Invalid SS58 prefix byte.")] - InvalidPrefix, - } - #[allow(unused_qualifications)] - impl std::error::Error for FromSs58Error {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for FromSs58Error { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - FromSs58Error::BadBase58 {} => { - __formatter.write_str("Base 58 requirement is violated") - } - FromSs58Error::BadLength {} => __formatter.write_str("Length is bad"), - FromSs58Error::InvalidChecksum {} => { - __formatter.write_str("Invalid checksum") - } - FromSs58Error::InvalidPrefix {} => { - __formatter.write_str("Invalid SS58 prefix byte.") - } - } - } - } - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::clone::Clone for FromSs58Error { - #[inline] - fn clone(&self) -> FromSs58Error { - *self - } - } - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::marker::Copy for FromSs58Error {} - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::cmp::Eq for FromSs58Error { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::marker::StructuralPartialEq for FromSs58Error {} - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::cmp::PartialEq for FromSs58Error { - #[inline] - fn eq(&self, other: &FromSs58Error) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::fmt::Debug for FromSs58Error { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - FromSs58Error::BadBase58 => "BadBase58", - FromSs58Error::BadLength => "BadLength", - FromSs58Error::InvalidChecksum => "InvalidChecksum", - FromSs58Error::InvalidPrefix => "InvalidPrefix", - }, - ) - } - } - fn ss58hash(data: &[u8]) -> Vec { - use blake2::{Blake2b512, Digest}; - const PREFIX: &[u8] = b"SS58PRE"; - let mut ctx = Blake2b512::new(); - ctx.update(PREFIX); - ctx.update(data); - ctx.finalize().to_vec() - } - impl Serialize for AccountId32 { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_ss58check()) - } - } - impl<'de> Deserialize<'de> for AccountId32 { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - AccountId32::from_ss58check(&String::deserialize(deserializer)?) - .map_err(|e| serde::de::Error::custom({ - let res = ::alloc::fmt::format(format_args!("{0:?}", e)); - res - })) - } - } - impl std::fmt::Display for AccountId32 { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.write_fmt(format_args!("{0}", self.to_ss58check())) - } - } - impl std::str::FromStr for AccountId32 { - type Err = FromSs58Error; - fn from_str(s: &str) -> Result { - AccountId32::from_ss58check(s) - } - } - } - pub mod bits { - //! Generic `scale_bits` over `bitvec`-like `BitOrder` and `BitFormat` types. - use codec::{Compact, Input}; - use scale_bits::{ - scale::format::{Format, OrderFormat, StoreFormat}, - Bits, - }; - use scale_decode::IntoVisitor; - use std::marker::PhantomData; - /// Associates `bitvec::store::BitStore` trait with corresponding, type-erased `scale_bits::StoreFormat` enum. - /// - /// Used to decode bit sequences by providing `scale_bits::StoreFormat` using - /// `bitvec`-like type type parameters. - pub trait BitStore { - /// Corresponding `scale_bits::StoreFormat` value. - const FORMAT: StoreFormat; - /// Number of bits that the backing store types holds. - const BITS: u32; - } - impl BitStore for u8 { - const FORMAT: StoreFormat = StoreFormat::U8; - const BITS: u32 = ::BITS; - } - impl BitStore for u16 { - const FORMAT: StoreFormat = StoreFormat::U16; - const BITS: u32 = ::BITS; - } - impl BitStore for u32 { - const FORMAT: StoreFormat = StoreFormat::U32; - const BITS: u32 = ::BITS; - } - impl BitStore for u64 { - const FORMAT: StoreFormat = StoreFormat::U64; - const BITS: u32 = ::BITS; - } - /// Associates `bitvec::order::BitOrder` trait with corresponding, type-erased `scale_bits::OrderFormat` enum. - /// - /// Used to decode bit sequences in runtime by providing `scale_bits::OrderFormat` using - /// `bitvec`-like type type parameters. - pub trait BitOrder { - /// Corresponding `scale_bits::OrderFormat` value. - const FORMAT: OrderFormat; - } - ///Type-level value that corresponds to `scale_bits::OrderFormat::Lsb0` at run-time - /// and `bitvec::order::BitOrder::Lsb0` at the type level. - pub enum Lsb0 {} - #[automatically_derived] - impl ::core::clone::Clone for Lsb0 { - #[inline] - fn clone(&self) -> Lsb0 { - match *self {} - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Lsb0 { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self {} - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Lsb0 {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Lsb0 { - #[inline] - fn eq(&self, other: &Lsb0) -> bool { - match *self {} - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Lsb0 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - impl BitOrder for Lsb0 { - const FORMAT: OrderFormat = OrderFormat::Lsb0; - } - ///Type-level value that corresponds to `scale_bits::OrderFormat::Msb0` at run-time - /// and `bitvec::order::BitOrder::Msb0` at the type level. - pub enum Msb0 {} - #[automatically_derived] - impl ::core::clone::Clone for Msb0 { - #[inline] - fn clone(&self) -> Msb0 { - match *self {} - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Msb0 { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self {} - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Msb0 {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Msb0 { - #[inline] - fn eq(&self, other: &Msb0) -> bool { - match *self {} - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Msb0 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - impl BitOrder for Msb0 { - const FORMAT: OrderFormat = OrderFormat::Msb0; - } - /// Constructs a run-time format parameters based on the corresponding type-level parameters. - fn bit_format() -> Format { - Format { - order: Order::FORMAT, - store: Store::FORMAT, - } - } - /// `scale_bits::Bits` generic over the bit store (`u8`/`u16`/`u32`/`u64`) and bit order (LSB, MSB) - /// used for SCALE encoding/decoding. Uses `scale_bits::Bits`-default `u8` and LSB format underneath. - pub struct DecodedBits { - bits: Bits, - _marker: PhantomData<(Store, Order)>, - } - #[automatically_derived] - impl ::core::fmt::Debug - for DecodedBits { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "DecodedBits", - "bits", - &self.bits, - "_marker", - &&self._marker, - ) - } - } - #[automatically_derived] - impl< - Store: ::core::clone::Clone, - Order: ::core::clone::Clone, - > ::core::clone::Clone for DecodedBits { - #[inline] - fn clone(&self) -> DecodedBits { - DecodedBits { - bits: ::core::clone::Clone::clone(&self.bits), - _marker: ::core::clone::Clone::clone(&self._marker), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for DecodedBits {} - #[automatically_derived] - impl< - Store: ::core::cmp::PartialEq, - Order: ::core::cmp::PartialEq, - > ::core::cmp::PartialEq for DecodedBits { - #[inline] - fn eq(&self, other: &DecodedBits) -> bool { - self.bits == other.bits && self._marker == other._marker - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for DecodedBits { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - impl DecodedBits { - /// Extracts the underlying `scale_bits::Bits` value. - pub fn into_bits(self) -> Bits { - self.bits - } - /// References the underlying `scale_bits::Bits` value. - pub fn as_bits(&self) -> &Bits { - &self.bits - } - } - impl core::iter::FromIterator for DecodedBits { - fn from_iter>(iter: T) -> Self { - DecodedBits { - bits: Bits::from_iter(iter), - _marker: PhantomData, - } - } - } - impl codec::Decode - for DecodedBits { - fn decode(input: &mut I) -> Result { - /// Equivalent of `BitSlice::MAX_BITS` on 32bit machine. - const ARCH32BIT_BITSLICE_MAX_BITS: u32 = 0x1fff_ffff; - let Compact(bits) = >::decode(input)?; - if bits > ARCH32BIT_BITSLICE_MAX_BITS { - return Err("Attempt to decode a BitVec with too many bits".into()); - } - let elements = (bits / Store::BITS) + u32::from(bits % Store::BITS != 0); - let bytes_in_elem = Store::BITS.saturating_div(u8::BITS); - let bytes_needed = (elements * bytes_in_elem) as usize; - let mut storage = codec::Encode::encode(&Compact(bits)); - let prefix_len = storage.len(); - storage.reserve_exact(bytes_needed); - storage.extend(::alloc::vec::from_elem(0, bytes_needed)); - input.read(&mut storage[prefix_len..])?; - let decoder = scale_bits::decode_using_format_from( - &storage, - bit_format::(), - )?; - let bits = decoder.collect::, _>>()?; - let bits = Bits::from_iter(bits); - Ok(DecodedBits { - bits, - _marker: PhantomData, - }) - } - } - impl codec::Encode - for DecodedBits { - fn size_hint(&self) -> usize { - self.bits.size_hint() - } - fn encoded_size(&self) -> usize { - self.bits.encoded_size() - } - fn encode(&self) -> Vec { - scale_bits::encode_using_format( - self.bits.iter(), - bit_format::(), - ) - } - } - #[doc(hidden)] - pub struct DecodedBitsVisitor(std::marker::PhantomData<(S, O)>); - impl scale_decode::Visitor for DecodedBitsVisitor { - type Value<'scale, 'info> = DecodedBits; - type Error = scale_decode::Error; - fn unchecked_decode_as_type<'scale, 'info>( - self, - input: &mut &'scale [u8], - type_id: scale_decode::visitor::TypeId, - types: &'info scale_info::PortableRegistry, - ) -> scale_decode::visitor::DecodeAsTypeResult< - Self, - Result, Self::Error>, - > { - let res = scale_decode::visitor::decode_with_visitor( - input, - type_id.0, - types, - Bits::into_visitor(), - ) - .map(|bits| DecodedBits { - bits, - _marker: PhantomData, - }); - scale_decode::visitor::DecodeAsTypeResult::Decoded(res) - } - } - impl scale_decode::IntoVisitor for DecodedBits { - type Visitor = DecodedBitsVisitor; - fn into_visitor() -> Self::Visitor { - DecodedBitsVisitor(PhantomData) - } - } - impl scale_encode::EncodeAsType for DecodedBits { - fn encode_as_type_to( - &self, - type_id: u32, - types: &scale_info::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - self.bits.encode_as_type_to(type_id, types, out) - } - } - } - mod era { - use scale_decode::DecodeAsType; - use scale_encode::EncodeAsType; - /// An era to describe the longevity of a transaction. - pub enum Era { - /// The transaction is valid forever. The genesis hash must be present in the signed content. - #[default] - Immortal, - /// The transaction will expire. Use [`Era::mortal`] to construct this with correct values. - /// - /// When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter - /// of `system` module. - Mortal { - /// The number of blocks that the tx will be valid for after the checkpoint block - /// hash found in the signer payload. - period: u64, - /// The phase in the period that this transaction's lifetime begins (and, importantly, - /// implies which block hash is included in the signature material). If the `period` is - /// greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that - /// `period` is. - phase: u64, - }, - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Era {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Era { - #[inline] - fn eq(&self, other: &Era) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - Era::Mortal { period: __self_0, phase: __self_1 }, - Era::Mortal { period: __arg1_0, phase: __arg1_1 }, - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::default::Default for Era { - #[inline] - fn default() -> Era { - Self::Immortal - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Era { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Era { - #[inline] - fn clone(&self) -> Era { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for Era {} - #[automatically_derived] - impl ::core::fmt::Debug for Era { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - Era::Immortal => ::core::fmt::Formatter::write_str(f, "Immortal"), - Era::Mortal { period: __self_0, phase: __self_1 } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Mortal", - "period", - __self_0, - "phase", - &__self_1, - ) - } - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Era { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - Era::Immortal => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "Era", - 0u32, - "Immortal", - ) - } - Era::Mortal { ref period, ref phase } => { - let mut __serde_state = _serde::Serializer::serialize_struct_variant( - __serializer, - "Era", - 1u32, - "Mortal", - 0 + 1 + 1, - )?; - _serde::ser::SerializeStructVariant::serialize_field( - &mut __serde_state, - "period", - period, - )?; - _serde::ser::SerializeStructVariant::serialize_field( - &mut __serde_state, - "phase", - phase, - )?; - _serde::ser::SerializeStructVariant::end(__serde_state) - } - } - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Era { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "Immortal" => _serde::__private::Ok(__Field::__field0), - "Mortal" => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"Immortal" => _serde::__private::Ok(__Field::__field0), - b"Mortal" => _serde::__private::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Era; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "enum Era", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(Era::Immortal) - } - (__Field::__field1, __variant) => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "period" => _serde::__private::Ok(__Field::__field0), - "phase" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"period" => _serde::__private::Ok(__Field::__field0), - b"phase" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Era; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant Era::Mortal", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant Era::Mortal with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct variant Era::Mortal with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(Era::Mortal { - period: __field0, - phase: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("period"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("phase"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("period")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("phase")? - } - }; - _serde::__private::Ok(Era::Mortal { - period: __field0, - phase: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "period", - "phase", - ]; - _serde::de::VariantAccess::struct_variant( - __variant, - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &["Immortal", "Mortal"]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "Era", - VARIANTS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for Era { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = Era; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "Immortal" { - return Ok(Era::Immortal); - } - if value.name() == "Mortal" { - let fields = value.fields(); - return if fields.has_unnamed_fields() { - if fields.remaining() != 2usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 2usize, - }), - ); - } - let vals = fields; - Ok(Era::Mortal { - period: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("period"))? - }, - phase: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("phase"))? - }, - }) - } else { - let vals: ::scale_decode::BTreeMap, _> = fields - .map(|res| res.map(|item| (item.name(), item))) - .collect::>()?; - Ok(Era::Mortal { - period: { - let val = *vals - .get(&Some("period")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "period".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("period"))? - }, - phase: { - let val = *vals - .get(&Some("phase")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "phase".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("phase"))? - }, - }) - }; - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new(["Immortal", "Mortal"]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - impl ::scale_encode::EncodeAsType for Era { - #[allow(unused_variables)] - fn encode_as_type_to( - &self, - __encode_as_type_type_id: u32, - __encode_as_type_types: &::scale_encode::PortableRegistry, - __encode_as_type_out: &mut ::scale_encode::Vec, - ) -> Result<(), ::scale_encode::Error> { - match self { - Self::Immortal => { - ::scale_encode::Variant { - name: "Immortal", - fields: ::scale_encode::Composite( - ([] - as [( - Option<&'static str>, - &dyn ::scale_encode::EncodeAsType, - ); 0]) - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Mortal { period, phase } => { - ::scale_encode::Variant { - name: "Mortal", - fields: ::scale_encode::Composite( - [ - ( - Some("period"), - period as &dyn ::scale_encode::EncodeAsType, - ), - (Some("phase"), phase as &dyn ::scale_encode::EncodeAsType), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - _ => { - ::core::panicking::panic( - "internal error: entered unreachable code", - ) - } - } - } - } - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo for Era { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "Era", - "subxt::utils::era", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .docs(&["An era to describe the longevity of a transaction."]) - .variant( - ::scale_info::build::Variants::new() - .variant( - "Immortal", - |v| { - v - .index(0usize as ::core::primitive::u8) - .docs( - &[ - "The transaction is valid forever. The genesis hash must be present in the signed content.", - ], - ) - }, - ) - .variant( - "Mortal", - |v| { - v - .index(1usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::named() - .field(|f| { - f - .ty::() - .name("period") - .type_name("u64") - .docs( - &[ - "The number of blocks that the tx will be valid for after the checkpoint block", - "hash found in the signer payload.", - ], - ) - }) - .field(|f| { - f - .ty::() - .name("phase") - .type_name("u64") - .docs( - &[ - "The phase in the period that this transaction's lifetime begins (and, importantly,", - "implies which block hash is included in the signature material). If the `period` is", - "greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that", - "`period` is.", - ], - ) - }), - ) - .docs( - &[ - "The transaction will expire. Use [`Era::mortal`] to construct this with correct values.", - "", - "When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter", - "of `system` module.", - ], - ) - }, - ), - ) - } - } - }; - impl Era { - /// Create a new era based on a period (which should be a power of two between 4 and 65536 - /// inclusive) and a block number on which it should start (or, for long periods, be shortly - /// after the start). - /// - /// If using `Era` in the context of `FRAME` runtime, make sure that `period` - /// does not exceed `BlockHashCount` parameter passed to `system` module, since that - /// prunes old blocks and renders transactions immediately invalid. - pub fn mortal(period: u64, current: u64) -> Self { - let period = period - .checked_next_power_of_two() - .unwrap_or(1 << 16) - .clamp(4, 1 << 16); - let phase = current % period; - let quantize_factor = (period >> 12).max(1); - let quantized_phase = phase / quantize_factor * quantize_factor; - Self::Mortal { - period, - phase: quantized_phase, - } - } - } - impl codec::Encode for Era { - fn encode_to(&self, output: &mut T) { - match self { - Self::Immortal => output.push_byte(0), - Self::Mortal { period, phase } => { - let quantize_factor = (*period >> 12).max(1); - let encoded = (period.trailing_zeros() - 1).clamp(1, 15) as u16 - | ((phase / quantize_factor) << 4) as u16; - encoded.encode_to(output); - } - } - } - } - impl codec::Decode for Era { - fn decode(input: &mut I) -> Result { - let first = input.read_byte()?; - if first == 0 { - Ok(Self::Immortal) - } else { - let encoded = first as u64 + ((input.read_byte()? as u64) << 8); - let period = 2 << (encoded % (1 << 4)); - let quantize_factor = (period >> 12).max(1); - let phase = (encoded >> 4) * quantize_factor; - if period >= 4 && phase < period { - Ok(Self::Mortal { period, phase }) - } else { - Err("Invalid period and phase".into()) - } - } - } - } - } - mod multi_address { - //! The "default" Substrate/Polkadot Address type. This is used in codegen, as well as signing related bits. - //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_runtime::MultiAddress` - //! for instance, to gain functionality without forcing a dependency on Substrate crates here. - use codec::{Decode, Encode}; - /// A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's - /// `sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion - /// functionality is provided via `From` impls if the `substrate-compat` feature is enabled). - pub enum MultiAddress { - /// It's an account ID (pubkey). - Id(AccountId), - /// It's an account index. - Index(#[codec(compact)] AccountIndex), - /// It's some arbitrary raw bytes. - Raw(Vec), - /// It's a 32 byte representation. - Address32([u8; 32]), - /// Its a 20 byte representation. - Address20([u8; 20]), - } - #[automatically_derived] - impl< - AccountId: ::core::clone::Clone, - AccountIndex: ::core::clone::Clone, - > ::core::clone::Clone for MultiAddress { - #[inline] - fn clone(&self) -> MultiAddress { - match self { - MultiAddress::Id(__self_0) => { - MultiAddress::Id(::core::clone::Clone::clone(__self_0)) - } - MultiAddress::Index(__self_0) => { - MultiAddress::Index(::core::clone::Clone::clone(__self_0)) - } - MultiAddress::Raw(__self_0) => { - MultiAddress::Raw(::core::clone::Clone::clone(__self_0)) - } - MultiAddress::Address32(__self_0) => { - MultiAddress::Address32(::core::clone::Clone::clone(__self_0)) - } - MultiAddress::Address20(__self_0) => { - MultiAddress::Address20(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for MultiAddress { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; - let _: ::core::cmp::AssertParamIsEq<[u8; 20]>; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for MultiAddress {} - #[automatically_derived] - impl< - AccountId: ::core::cmp::PartialEq, - AccountIndex: ::core::cmp::PartialEq, - > ::core::cmp::PartialEq for MultiAddress { - #[inline] - fn eq(&self, other: &MultiAddress) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - ( - MultiAddress::Index(__self_0), - MultiAddress::Index(__arg1_0), - ) => *__self_0 == *__arg1_0, - (MultiAddress::Raw(__self_0), MultiAddress::Raw(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - ( - MultiAddress::Address32(__self_0), - MultiAddress::Address32(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MultiAddress::Address20(__self_0), - MultiAddress::Address20(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl< - AccountId: ::core::cmp::Ord, - AccountIndex: ::core::cmp::Ord, - > ::core::cmp::Ord for MultiAddress { - #[inline] - fn cmp( - &self, - other: &MultiAddress, - ) -> ::core::cmp::Ordering { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) { - ::core::cmp::Ordering::Equal => { - match (self, other) { - (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { - ::core::cmp::Ord::cmp(__self_0, __arg1_0) - } - ( - MultiAddress::Index(__self_0), - MultiAddress::Index(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiAddress::Raw(__self_0), - MultiAddress::Raw(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiAddress::Address32(__self_0), - MultiAddress::Address32(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiAddress::Address20(__self_0), - MultiAddress::Address20(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl< - AccountId: ::core::cmp::PartialOrd, - AccountIndex: ::core::cmp::PartialOrd, - > ::core::cmp::PartialOrd for MultiAddress { - #[inline] - fn partial_cmp( - &self, - other: &MultiAddress, - ) -> ::core::option::Option<::core::cmp::Ordering> { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match (self, other) { - (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - (MultiAddress::Index(__self_0), MultiAddress::Index(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - (MultiAddress::Raw(__self_0), MultiAddress::Raw(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - ( - MultiAddress::Address32(__self_0), - MultiAddress::Address32(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - ( - MultiAddress::Address20(__self_0), - MultiAddress::Address20(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode - for MultiAddress - where - AccountId: ::codec::Encode, - AccountId: ::codec::Encode, - AccountIndex: ::codec::HasCompact, - { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - MultiAddress::Id(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiAddress::Index(ref aa) => { - 0_usize - .saturating_add( - ::codec::Encode::size_hint( - &<::Type as ::codec::EncodeAsRef< - '_, - AccountIndex, - >>::RefType::from(aa), - ), - ) - } - MultiAddress::Raw(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiAddress::Address32(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiAddress::Address20(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - _ => 0_usize, - } - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - match *self { - MultiAddress::Id(ref aa) => { - __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiAddress::Index(ref aa) => { - __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); - { - ::codec::Encode::encode_to( - &<::Type as ::codec::EncodeAsRef< - '_, - AccountIndex, - >>::RefType::from(aa), - __codec_dest_edqy, - ); - } - } - MultiAddress::Raw(ref aa) => { - __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiAddress::Address32(ref aa) => { - __codec_dest_edqy.push_byte(3usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiAddress::Address20(ref aa) => { - __codec_dest_edqy.push_byte(4usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::codec::EncodeLike - for MultiAddress - where - AccountId: ::codec::Encode, - AccountId: ::codec::Encode, - AccountIndex: ::codec::HasCompact, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode - for MultiAddress - where - AccountId: ::codec::Decode, - AccountId: ::codec::Decode, - AccountIndex: ::codec::HasCompact, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `MultiAddress`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Id({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Id.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Index({ - let __codec_res_edqy = <::Type as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Index.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy.into() - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Raw({ - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Raw.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 3usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Address32({ - let __codec_res_edqy = <[u8; 32] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Address32.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 4usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Address20({ - let __codec_res_edqy = <[u8; 20] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Address20.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `MultiAddress`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - #[automatically_derived] - impl< - AccountId: ::core::fmt::Debug, - AccountIndex: ::core::fmt::Debug, - > ::core::fmt::Debug for MultiAddress { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - MultiAddress::Id(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Id", - &__self_0, - ) - } - MultiAddress::Index(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Index", - &__self_0, - ) - } - MultiAddress::Raw(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Raw", - &__self_0, - ) - } - MultiAddress::Address32(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Address32", - &__self_0, - ) - } - MultiAddress::Address20(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Address20", - &__self_0, - ) - } - } - } - } - impl ::scale_encode::EncodeAsType - for MultiAddress - where - AccountId: ::scale_encode::EncodeAsType, - AccountIndex: ::scale_encode::EncodeAsType, - { - #[allow(unused_variables)] - fn encode_as_type_to( - &self, - __encode_as_type_type_id: u32, - __encode_as_type_types: &::scale_encode::PortableRegistry, - __encode_as_type_out: &mut ::scale_encode::Vec, - ) -> Result<(), ::scale_encode::Error> { - match self { - Self::Id(_0) => { - ::scale_encode::Variant { - name: "Id", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Index(_0) => { - ::scale_encode::Variant { - name: "Index", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Raw(_0) => { - ::scale_encode::Variant { - name: "Raw", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Address32(_0) => { - ::scale_encode::Variant { - name: "Address32", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Address20(_0) => { - ::scale_encode::Variant { - name: "Address20", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - _ => { - ::core::panicking::panic( - "internal error: entered unreachable code", - ) - } - } - } - } - const _: () = { - pub struct Visitor( - ::core::marker::PhantomData<(AccountId, AccountIndex)>, - ); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor - for MultiAddress - where - AccountId: ::scale_decode::IntoVisitor, - ::scale_decode::Error: From< - <::Visitor as ::scale_decode::Visitor>::Error, - >, - AccountIndex: ::scale_decode::IntoVisitor, - ::scale_decode::Error: From< - <::Visitor as ::scale_decode::Visitor>::Error, - >, - { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor - for Visitor - where - AccountId: ::scale_decode::IntoVisitor, - ::scale_decode::Error: From< - <::Visitor as ::scale_decode::Visitor>::Error, - >, - AccountIndex: ::scale_decode::IntoVisitor, - ::scale_decode::Error: From< - <::Visitor as ::scale_decode::Visitor>::Error, - >, - { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = MultiAddress; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "Id" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Id({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Index" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Index({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Raw" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Raw({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Address32" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Address32({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Address20" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Address20({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - "Id", - "Index", - "Raw", - "Address32", - "Address20", - ]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo - for MultiAddress - where - AccountId: ::scale_info::TypeInfo + 'static, - AccountIndex: ::scale_info::scale::HasCompact, - AccountId: ::scale_info::TypeInfo + 'static, - AccountIndex: ::scale_info::TypeInfo + 'static, - { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "MultiAddress", - "subxt::utils::multi_address", - &[], - ), - ) - .type_params( - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - ::scale_info::TypeParameter::new( - "AccountId", - ::core::option::Option::Some( - ::scale_info::meta_type::(), - ), - ), - ::scale_info::TypeParameter::new( - "AccountIndex", - ::core::option::Option::Some( - ::scale_info::meta_type::(), - ), - ), - ]), - ), - ) - .docs( - &[ - "A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's", - "`sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion", - "functionality is provided via `From` impls if the `substrate-compat` feature is enabled).", - ], - ) - .variant( - ::scale_info::build::Variants::new() - .variant( - "Id", - |v| { - v - .index(0usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::().type_name("AccountId")), - ) - .docs(&["It's an account ID (pubkey)."]) - }, - ) - .variant( - "Index", - |v| { - v - .index(1usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| { - f.compact::().type_name("AccountIndex") - }), - ) - .docs(&["It's an account index."]) - }, - ) - .variant( - "Raw", - |v| { - v - .index(2usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::>().type_name("Vec")), - ) - .docs(&["It's some arbitrary raw bytes."]) - }, - ) - .variant( - "Address32", - |v| { - v - .index(3usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 32]>().type_name("[u8; 32]")), - ) - .docs(&["It's a 32 byte representation."]) - }, - ) - .variant( - "Address20", - |v| { - v - .index(4usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 20]>().type_name("[u8; 20]")), - ) - .docs(&["Its a 20 byte representation."]) - }, - ), - ) - } - } - }; - impl From - for MultiAddress { - fn from(a: AccountId) -> Self { - Self::Id(a) - } - } - } - mod multi_signature { - //! The "default" Substrate/Polkadot Signature type. This is used in codegen, as well as signing related bits. - //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_runtime::MultiSignature` - //! for instance, to gain functionality without forcing a dependency on Substrate crates here. - use codec::{Decode, Encode}; - /// Signature container that can store known signature types. This is a simplified version of - /// `sp_runtime::MultiSignature`. To obtain more functionality, convert this into that type. - pub enum MultiSignature { - /// An Ed25519 signature. - Ed25519([u8; 64]), - /// An Sr25519 signature. - Sr25519([u8; 64]), - /// An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID). - Ecdsa([u8; 65]), - } - #[automatically_derived] - impl ::core::clone::Clone for MultiSignature { - #[inline] - fn clone(&self) -> MultiSignature { - match self { - MultiSignature::Ed25519(__self_0) => { - MultiSignature::Ed25519(::core::clone::Clone::clone(__self_0)) - } - MultiSignature::Sr25519(__self_0) => { - MultiSignature::Sr25519(::core::clone::Clone::clone(__self_0)) - } - MultiSignature::Ecdsa(__self_0) => { - MultiSignature::Ecdsa(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for MultiSignature { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; - let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; - let _: ::core::cmp::AssertParamIsEq<[u8; 65]>; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for MultiSignature {} - #[automatically_derived] - impl ::core::cmp::PartialEq for MultiSignature { - #[inline] - fn eq(&self, other: &MultiSignature) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - MultiSignature::Ed25519(__self_0), - MultiSignature::Ed25519(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MultiSignature::Sr25519(__self_0), - MultiSignature::Sr25519(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MultiSignature::Ecdsa(__self_0), - MultiSignature::Ecdsa(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Ord for MultiSignature { - #[inline] - fn cmp(&self, other: &MultiSignature) -> ::core::cmp::Ordering { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) { - ::core::cmp::Ordering::Equal => { - match (self, other) { - ( - MultiSignature::Ed25519(__self_0), - MultiSignature::Ed25519(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiSignature::Sr25519(__self_0), - MultiSignature::Sr25519(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiSignature::Ecdsa(__self_0), - MultiSignature::Ecdsa(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for MultiSignature { - #[inline] - fn partial_cmp( - &self, - other: &MultiSignature, - ) -> ::core::option::Option<::core::cmp::Ordering> { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match (self, other) { - ( - MultiSignature::Ed25519(__self_0), - MultiSignature::Ed25519(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - ( - MultiSignature::Sr25519(__self_0), - MultiSignature::Sr25519(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - ( - MultiSignature::Ecdsa(__self_0), - MultiSignature::Ecdsa(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for MultiSignature { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - MultiSignature::Ed25519(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiSignature::Sr25519(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiSignature::Ecdsa(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - _ => 0_usize, - } - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - match *self { - MultiSignature::Ed25519(ref aa) => { - __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiSignature::Sr25519(ref aa) => { - __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiSignature::Ecdsa(ref aa) => { - __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::codec::EncodeLike for MultiSignature {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for MultiSignature { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `MultiSignature`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiSignature::Ed25519({ - let __codec_res_edqy = <[u8; 64] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiSignature::Ed25519.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiSignature::Sr25519({ - let __codec_res_edqy = <[u8; 64] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiSignature::Sr25519.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiSignature::Ecdsa({ - let __codec_res_edqy = <[u8; 65] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiSignature::Ecdsa.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `MultiSignature`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for MultiSignature { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - MultiSignature::Ed25519(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Ed25519", - &__self_0, - ) - } - MultiSignature::Sr25519(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Sr25519", - &__self_0, - ) - } - MultiSignature::Ecdsa(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Ecdsa", - &__self_0, - ) - } - } - } - } - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo for MultiSignature { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "MultiSignature", - "subxt::utils::multi_signature", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .docs( - &[ - "Signature container that can store known signature types. This is a simplified version of", - "`sp_runtime::MultiSignature`. To obtain more functionality, convert this into that type.", - ], - ) - .variant( - ::scale_info::build::Variants::new() - .variant( - "Ed25519", - |v| { - v - .index(0usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 64]>().type_name("[u8; 64]")), - ) - .docs(&["An Ed25519 signature."]) - }, - ) - .variant( - "Sr25519", - |v| { - v - .index(1usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 64]>().type_name("[u8; 64]")), - ) - .docs(&["An Sr25519 signature."]) - }, - ) - .variant( - "Ecdsa", - |v| { - v - .index(2usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 65]>().type_name("[u8; 65]")), - ) - .docs( - &[ - "An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID).", - ], - ) - }, - ), - ) - } - } - }; - } - mod static_type { - use codec::{Decode, Encode}; - use scale_decode::{visitor::DecodeAsTypeResult, IntoVisitor, Visitor}; - use scale_encode::EncodeAsType; - /// If the type inside this implements [`Encode`], this will implement [`scale_encode::EncodeAsType`]. - /// If the type inside this implements [`Decode`], this will implement [`scale_decode::DecodeAsType`]. - /// - /// In either direction, we ignore any type information and just attempt to encode/decode statically - /// via the [`Encode`] and [`Decode`] implementations. This can be useful as an adapter for types which - /// do not implement [`scale_encode::EncodeAsType`] and [`scale_decode::DecodeAsType`] themselves, but - /// it's best to avoid using it where possible as it will not take into account any type information, - /// and is thus more likely to encode or decode incorrectly. - pub struct Static(pub T); - #[automatically_derived] - impl ::core::fmt::Debug for Static { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Static", &&self.0) - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for Static - where - T: ::codec::Encode, - T: ::codec::Encode, - { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.0) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.0) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.0, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike for Static - where - T: ::codec::Encode, - T: ::codec::Encode, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for Static - where - T: ::codec::Decode, - T: ::codec::Decode, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok( - Static::< - T, - >({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `Static.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - } - } - }; - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Static {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Static { - #[inline] - fn eq(&self, other: &Static) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Static { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Static { - #[inline] - fn clone(&self) -> Static { - Static(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Static { - #[inline] - fn partial_cmp( - &self, - other: &Static, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Static { - #[inline] - fn cmp(&self, other: &Static) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::hash::Hash for Static { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - impl EncodeAsType for Static { - fn encode_as_type_to( - &self, - _type_id: u32, - _types: &scale_decode::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - self.0.encode_to(out); - Ok(()) - } - } - pub struct StaticDecodeAsTypeVisitor(std::marker::PhantomData); - impl Visitor for StaticDecodeAsTypeVisitor { - type Value<'scale, 'info> = Static; - type Error = scale_decode::Error; - fn unchecked_decode_as_type<'scale, 'info>( - self, - input: &mut &'scale [u8], - _type_id: scale_decode::visitor::TypeId, - _types: &'info scale_info::PortableRegistry, - ) -> DecodeAsTypeResult< - Self, - Result, Self::Error>, - > { - use scale_decode::{visitor::DecodeError, Error}; - let decoded = T::decode(input) - .map(Static) - .map_err(|e| Error::new(DecodeError::CodecError(e).into())); - DecodeAsTypeResult::Decoded(decoded) - } - } - impl IntoVisitor for Static { - type Visitor = StaticDecodeAsTypeVisitor; - fn into_visitor() -> Self::Visitor { - StaticDecodeAsTypeVisitor(std::marker::PhantomData) - } - } - impl From for Static { - fn from(value: T) -> Self { - Static(value) - } - } - impl std::ops::Deref for Static { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl std::ops::DerefMut for Static { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - } - mod unchecked_extrinsic { - //! The "default" Substrate/Polkadot UncheckedExtrinsic. - //! This is used in codegen for runtime API calls. - //! - //! The inner bytes represent the encoded extrinsic expected by the - //! runtime APIs. Deriving `EncodeAsType` would lead to the inner - //! bytes to be re-encoded (length prefixed). - use std::marker::PhantomData; - use codec::{Decode, Encode}; - use scale_decode::{ - visitor::DecodeAsTypeResult, DecodeAsType, IntoVisitor, Visitor, - }; - use super::{Encoded, Static}; - /// The unchecked extrinsic from substrate. - pub struct UncheckedExtrinsic( - Static, - #[codec(skip)] - PhantomData<(Address, Call, Signature, Extra)>, - ); - #[automatically_derived] - impl< - Address: ::core::clone::Clone, - Call: ::core::clone::Clone, - Signature: ::core::clone::Clone, - Extra: ::core::clone::Clone, - > ::core::clone::Clone for UncheckedExtrinsic { - #[inline] - fn clone(&self) -> UncheckedExtrinsic { - UncheckedExtrinsic( - ::core::clone::Clone::clone(&self.0), - ::core::clone::Clone::clone(&self.1), - ) - } - } - #[automatically_derived] - impl< - Address: ::core::fmt::Debug, - Call: ::core::fmt::Debug, - Signature: ::core::fmt::Debug, - Extra: ::core::fmt::Debug, - > ::core::fmt::Debug for UncheckedExtrinsic { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field2_finish( - f, - "UncheckedExtrinsic", - &self.0, - &&self.1, - ) - } - } - #[automatically_derived] - impl< - Address: ::core::cmp::Eq, - Call: ::core::cmp::Eq, - Signature: ::core::cmp::Eq, - Extra: ::core::cmp::Eq, - > ::core::cmp::Eq for UncheckedExtrinsic { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq< - PhantomData<(Address, Call, Signature, Extra)>, - >; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for UncheckedExtrinsic {} - #[automatically_derived] - impl< - Address: ::core::cmp::PartialEq, - Call: ::core::cmp::PartialEq, - Signature: ::core::cmp::PartialEq, - Extra: ::core::cmp::PartialEq, - > ::core::cmp::PartialEq - for UncheckedExtrinsic { - #[inline] - fn eq( - &self, - other: &UncheckedExtrinsic, - ) -> bool { - self.0 == other.0 && self.1 == other.1 - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode - for UncheckedExtrinsic { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.0) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.0) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.0, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike - for UncheckedExtrinsic {} - }; - impl< - Address, - Call, - Signature, - Extra, - > UncheckedExtrinsic { - /// Construct a new [`UncheckedExtrinsic`]. - pub fn new(bytes: Vec) -> Self { - Self(Static(Encoded(bytes)), PhantomData) - } - /// Get the bytes of the encoded extrinsic. - pub fn bytes(&self) -> &[u8] { - self.0.0.0.as_slice() - } - } - impl Decode - for UncheckedExtrinsic { - fn decode(input: &mut I) -> Result { - let xt_vec: Vec = Decode::decode(input)?; - Ok(UncheckedExtrinsic::new(xt_vec)) - } - } - impl scale_encode::EncodeAsType - for UncheckedExtrinsic { - fn encode_as_type_to( - &self, - type_id: u32, - types: &scale_info::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - self.0.encode_as_type_to(type_id, types, out) - } - } - impl From> - for UncheckedExtrinsic { - fn from(bytes: Vec) -> Self { - UncheckedExtrinsic::new(bytes) - } - } - impl< - Address, - Call, - Signature, - Extra, - > From> for Vec { - fn from(bytes: UncheckedExtrinsic) -> Self { - bytes.0.0.0 - } - } - pub struct UncheckedExtrinsicDecodeAsTypeVisitor< - Address, - Call, - Signature, - Extra, - >( - PhantomData<(Address, Call, Signature, Extra)>, - ); - impl Visitor - for UncheckedExtrinsicDecodeAsTypeVisitor { - type Value<'scale, 'info> = UncheckedExtrinsic< - Address, - Call, - Signature, - Extra, - >; - type Error = scale_decode::Error; - fn unchecked_decode_as_type<'scale, 'info>( - self, - input: &mut &'scale [u8], - type_id: scale_decode::visitor::TypeId, - types: &'info scale_info::PortableRegistry, - ) -> DecodeAsTypeResult< - Self, - Result, Self::Error>, - > { - DecodeAsTypeResult::Decoded( - Self::Value::decode_as_type(input, type_id.0, types), - ) - } - } - impl IntoVisitor - for UncheckedExtrinsic { - type Visitor = UncheckedExtrinsicDecodeAsTypeVisitor< - Address, - Call, - Signature, - Extra, - >; - fn into_visitor() -> Self::Visitor { - UncheckedExtrinsicDecodeAsTypeVisitor(PhantomData) - } - } - } - mod wrapper_opaque { - use super::PhantomDataSendSync; - use codec::{Compact, Decode, DecodeAll, Encode}; - use derivative::Derivative; - use scale_decode::{IntoVisitor, Visitor}; - use scale_encode::EncodeAsType; - /// A wrapper for any type `T` which implement encode/decode in a way compatible with `Vec`. - /// [`WrapperKeepOpaque`] stores the type only in its opaque format, aka as a `Vec`. To - /// access the real type `T` [`Self::try_decode`] needs to be used. - #[derivative( - Debug(bound = ""), - Clone(bound = ""), - PartialEq(bound = ""), - Eq(bound = ""), - Default(bound = ""), - Hash(bound = "") - )] - pub struct WrapperKeepOpaque { - data: Vec, - _phantom: PhantomDataSendSync, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for WrapperKeepOpaque { - fn clone(&self) -> Self { - match *self { - WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { - WrapperKeepOpaque { - data: (*__arg_0).clone(), - _phantom: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for WrapperKeepOpaque { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { - let mut __debug_trait_builder = __f - .debug_struct("WrapperKeepOpaque"); - let _ = __debug_trait_builder.field("data", &&(*__arg_0)); - let _ = __debug_trait_builder.field("_phantom", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::default::Default for WrapperKeepOpaque { - fn default() -> Self { - WrapperKeepOpaque { - data: ::std::default::Default::default(), - _phantom: ::std::default::Default::default(), - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for WrapperKeepOpaque {} - #[allow(unused_qualifications)] - impl ::std::hash::Hash for WrapperKeepOpaque { - fn hash<__HT>(&self, __state: &mut __HT) - where - __HT: ::std::hash::Hasher, - { - match *self { - WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { - ::std::hash::Hash::hash(&(*__arg_0), __state); - ::std::hash::Hash::hash(&(*__arg_1), __state); - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for WrapperKeepOpaque { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - WrapperKeepOpaque { - data: ref __self_0, - _phantom: ref __self_1, - } => { - match *other { - WrapperKeepOpaque { - data: ref __other_0, - _phantom: ref __other_1, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - } - } - } - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for WrapperKeepOpaque - where - PhantomDataSendSync: ::codec::Encode, - PhantomDataSendSync: ::codec::Encode, - { - fn size_hint(&self) -> usize { - 0_usize - .saturating_add(::codec::Encode::size_hint(&self.data)) - .saturating_add(::codec::Encode::size_hint(&self._phantom)) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&self.data, __codec_dest_edqy); - ::codec::Encode::encode_to(&self._phantom, __codec_dest_edqy); - } - } - #[automatically_derived] - impl ::codec::EncodeLike for WrapperKeepOpaque - where - PhantomDataSendSync: ::codec::Encode, - PhantomDataSendSync: ::codec::Encode, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for WrapperKeepOpaque - where - PhantomDataSendSync: ::codec::Decode, - PhantomDataSendSync: ::codec::Decode, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(WrapperKeepOpaque:: { - data: { - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `WrapperKeepOpaque::data`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - _phantom: { - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `WrapperKeepOpaque::_phantom`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - impl WrapperKeepOpaque { - /// Try to decode the wrapped type from the inner `data`. - /// - /// Returns `None` if the decoding failed. - pub fn try_decode(&self) -> Option - where - T: Decode, - { - T::decode_all(&mut &self.data[..]).ok() - } - /// Returns the length of the encoded `T`. - pub fn encoded_len(&self) -> usize { - self.data.len() - } - /// Returns the encoded data. - pub fn encoded(&self) -> &[u8] { - &self.data - } - /// Create from the given encoded `data`. - pub fn from_encoded(data: Vec) -> Self { - Self { - data, - _phantom: PhantomDataSendSync::new(), - } - } - /// Create from some raw value by encoding it. - pub fn from_value(value: T) -> Self - where - T: Encode, - { - Self { - data: value.encode(), - _phantom: PhantomDataSendSync::new(), - } - } - } - impl EncodeAsType for WrapperKeepOpaque { - fn encode_as_type_to( - &self, - type_id: u32, - types: &scale_info::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - use scale_encode::error::{Error, ErrorKind, Kind}; - let Some(ty) = types.resolve(type_id) else { - return Err(Error::new(ErrorKind::TypeNotFound(type_id))); - }; - let scale_info::TypeDef::Composite(_) = &ty.type_def else { - return Err( - Error::new(ErrorKind::WrongShape { - actual: Kind::Struct, - expected: type_id, - }), - ); - }; - if ty.path.ident().as_deref() != Some("WrapperKeepOpaque") { - return Err( - Error::new(ErrorKind::WrongShape { - actual: Kind::Struct, - expected: type_id, - }), - ); - } - self.data.encode_to(out); - Ok(()) - } - } - pub struct WrapperKeepOpaqueVisitor(std::marker::PhantomData); - impl Visitor for WrapperKeepOpaqueVisitor { - type Value<'scale, 'info> = WrapperKeepOpaque; - type Error = scale_decode::Error; - fn visit_composite<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - use scale_decode::error::{Error, ErrorKind}; - if value.path().ident().as_deref() != Some("WrapperKeepOpaque") { - return Err( - Error::custom_str( - "Type to decode is not 'WrapperTypeKeepOpaque'", - ), - ); - } - if value.remaining() != 2 { - return Err( - Error::new(ErrorKind::WrongLength { - actual_len: value.remaining(), - expected_len: 2, - }), - ); - } - let Compact(len) = value - .decode_item(Compact::::into_visitor()) - .expect("length checked")?; - let field = value.next().expect("length checked")?; - if field.bytes().len() != len as usize { - return Err( - Error::custom_str( - "WrapperTypeKeepOpaque compact encoded length doesn't line up with encoded byte len", - ), - ); - } - Ok(WrapperKeepOpaque { - data: field.bytes().to_vec(), - _phantom: PhantomDataSendSync::new(), - }) - } - } - impl IntoVisitor for WrapperKeepOpaque { - type Visitor = WrapperKeepOpaqueVisitor; - fn into_visitor() -> Self::Visitor { - WrapperKeepOpaqueVisitor(std::marker::PhantomData) - } - } - } - use crate::error::RpcError; - use crate::Error; - use codec::{Compact, Decode, Encode}; - use derivative::Derivative; - use url::Url; - pub use account_id::AccountId32; - pub use era::Era; - pub use multi_address::MultiAddress; - pub use multi_signature::MultiSignature; - pub use static_type::Static; - pub use unchecked_extrinsic::UncheckedExtrinsic; - pub use wrapper_opaque::WrapperKeepOpaque; - #[doc(hidden)] - pub use primitive_types::{H160, H256, H512}; - /// Wraps an already encoded byte vector, prevents being encoded as a raw byte vector as part of - /// the transaction payload - pub struct Encoded(pub Vec); - #[automatically_derived] - impl ::core::clone::Clone for Encoded { - #[inline] - fn clone(&self) -> Encoded { - Encoded(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Encoded { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Encoded", &&self.0) - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Encoded { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Encoded {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Encoded { - #[inline] - fn eq(&self, other: &Encoded) -> bool { - self.0 == other.0 - } - } - impl codec::Encode for Encoded { - fn encode(&self) -> Vec { - self.0.to_owned() - } - } - /// Decodes a compact encoded value from the beginning of the provided bytes, - /// returning the value and any remaining bytes. - pub(crate) fn strip_compact_prefix( - bytes: &[u8], - ) -> Result<(u64, &[u8]), codec::Error> { - let cursor = &mut &*bytes; - let val = >::decode(cursor)?; - Ok((val.0, *cursor)) - } - /// A URL is considered secure if it uses a secure scheme ("https" or "wss") or is referring to localhost. - /// - /// Returns an error if the the string could not be parsed into a URL. - pub fn url_is_secure(url: &str) -> Result { - let url = Url::parse(url) - .map_err(|e| Error::Rpc(RpcError::ClientError(Box::new(e))))?; - let secure_scheme = url.scheme() == "https" || url.scheme() == "wss"; - let is_localhost = url - .host() - .is_some_and(|e| match e { - url::Host::Domain(e) => e == "localhost", - url::Host::Ipv4(e) => e.is_loopback(), - url::Host::Ipv6(e) => e.is_loopback(), - }); - Ok(secure_scheme || is_localhost) - } - /// Validates, that the given Url is secure ("https" or "wss" scheme) or is referring to localhost. - pub fn validate_url_is_secure(url: &str) -> Result<(), Error> { - if !url_is_secure(url)? { - Err(Error::Rpc(crate::error::RpcError::InsecureUrl(url.into()))) - } else { - Ok(()) - } - } - /// A version of [`std::marker::PhantomData`] that is also Send and Sync (which is fine - /// because regardless of the generic param, it is always possible to Send + Sync this - /// 0 size type). - #[derivative( - Clone(bound = ""), - PartialEq(bound = ""), - Debug(bound = ""), - Eq(bound = ""), - Default(bound = ""), - Hash(bound = "") - )] - #[scale_info(skip_type_params(T))] - #[doc(hidden)] - pub struct PhantomDataSendSync(core::marker::PhantomData); - #[allow(unused_qualifications)] - impl ::std::clone::Clone for PhantomDataSendSync { - fn clone(&self) -> Self { - match *self { - PhantomDataSendSync(ref __arg_0) => { - PhantomDataSendSync((*__arg_0).clone()) - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for PhantomDataSendSync { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - PhantomDataSendSync(ref __arg_0) => { - let mut __debug_trait_builder = __f - .debug_tuple("PhantomDataSendSync"); - let _ = __debug_trait_builder.field(&&(*__arg_0)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::default::Default for PhantomDataSendSync { - fn default() -> Self { - PhantomDataSendSync(::std::default::Default::default()) - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for PhantomDataSendSync {} - #[allow(unused_qualifications)] - impl ::std::hash::Hash for PhantomDataSendSync { - fn hash<__HT>(&self, __state: &mut __HT) - where - __HT: ::std::hash::Hasher, - { - match *self { - PhantomDataSendSync(ref __arg_0) => { - ::std::hash::Hash::hash(&(*__arg_0), __state); - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for PhantomDataSendSync { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - PhantomDataSendSync(ref __self_0) => { - match *other { - PhantomDataSendSync(ref __other_0) => { - true && &(*__self_0) == &(*__other_0) - } - } - } - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for PhantomDataSendSync - where - core::marker::PhantomData: ::codec::Encode, - core::marker::PhantomData: ::codec::Encode, - { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.0) - } - fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>( - &self, - __codec_dest_edqy: &mut __CodecOutputEdqy, - ) { - ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.0) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.0, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike for PhantomDataSendSync - where - core::marker::PhantomData: ::codec::Encode, - core::marker::PhantomData: ::codec::Encode, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for PhantomDataSendSync - where - core::marker::PhantomData: ::codec::Decode, - core::marker::PhantomData: ::codec::Decode, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok( - PhantomDataSendSync::< - T, - >({ - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `PhantomDataSendSync.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - } - } - }; - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo for PhantomDataSendSync - where - core::marker::PhantomData: ::scale_info::TypeInfo + 'static, - T: 'static, - { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "PhantomDataSendSync", - "subxt::utils", - &[], - ), - ) - .type_params( - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - ::scale_info::TypeParameter::new( - "T", - ::core::option::Option::None, - ), - ]), - ), - ) - .docs( - &[ - "A version of [`std::marker::PhantomData`] that is also Send and Sync (which is fine", - "because regardless of the generic param, it is always possible to Send + Sync this", - "0 size type).", - ], - ) - .composite( - ::scale_info::build::Fields::unnamed() - .field(|f| { - f - .ty::>() - .type_name("core::marker::PhantomData") - }), - ) - } - } - }; - impl PhantomDataSendSync { - pub(crate) fn new() -> Self { - Self(core::marker::PhantomData) - } - } - unsafe impl Send for PhantomDataSendSync {} - unsafe impl Sync for PhantomDataSendSync {} - /// This represents a key-value collection and is SCALE compatible - /// with collections like BTreeMap. This has the same type params - /// as `BTreeMap` which allows us to easily swap the two during codegen. - pub type KeyedVec = Vec<(K, V)>; -} -#[macro_use] -mod macros { - pub(crate) use { - cfg_feature, cfg_jsonrpsee, cfg_reconnecting_rpc_client, cfg_substrate_compat, - cfg_unstable_light_client, - }; - #[allow(unused)] - pub(crate) use {cfg_jsonrpsee_native, cfg_jsonrpsee_web}; -} -pub use crate::{ - client::{OfflineClient, OnlineClient}, - config::{Config, PolkadotConfig, SubstrateConfig}, - error::Error, metadata::Metadata, -}; -/// Re-export external crates that are made use of in the subxt API. -pub mod ext { - pub use codec; - pub use frame_metadata; - pub use futures; - pub use scale_bits; - pub use scale_decode; - pub use scale_encode; - pub use scale_value; -} -/// Generate a strongly typed API for interacting with a Substrate runtime from its metadata. -/// -/// # Metadata -/// -/// First, you'll need to get hold of some metadata for the node you'd like to interact with. One -/// way to do this is by using the `subxt` CLI tool: -/// -/// ```bash -/// # Install the CLI tool: -/// cargo install subxt-cli -/// # Use it to download metadata (in this case, from a node running locally) -/// subxt metadata > polkadot_metadata.scale -/// ``` -/// -/// Run `subxt metadata --help` for more options. -/// -/// # Basic usage -/// -/// Annotate a Rust module with the `subxt` attribute referencing the aforementioned metadata file. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// )] -/// mod polkadot {} -/// ``` -/// -/// The `subxt` macro will populate the annotated module with all of the methods and types required -/// for interacting with the runtime that the metadata is in via Subxt. -/// -/// # Configuration -/// -/// This macro supports a number of attributes to configure what is generated: -/// -/// ## `crate = "..."` -/// -/// Use this attribute to specify a custom path to the `subxt` crate: -/// -/// ```rust -/// # pub extern crate subxt; -/// # pub mod path { pub mod to { pub use subxt; } } -/// # fn main() {} -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// crate = "crate::path::to::subxt" -/// )] -/// mod polkadot {} -/// ``` -/// -/// This is useful if you write a library which uses this macro, but don't want to force users to depend on `subxt` -/// at the top level too. By default the path `::subxt` is used. -/// -/// ## `substitute_type(path = "...", with = "...")` -/// -/// This attribute replaces any reference to the generated type at the path given by `path` with a -/// reference to the path given by `with`. -/// -/// ```rust -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// substitute_type(path = "sp_arithmetic::per_things::Perbill", with = "crate::Foo") -/// )] -/// mod polkadot {} -/// -/// # #[derive( -/// # scale_encode::EncodeAsType, -/// # scale_decode::DecodeAsType, -/// # codec::Encode, -/// # codec::Decode, -/// # Clone, -/// # Debug, -/// # )] -/// // In reality this needs some traits implementing on -/// // it to allow it to be used in place of Perbill: -/// pub struct Foo(u32); -/// # impl codec::CompactAs for Foo { -/// # type As = u32; -/// # fn encode_as(&self) -> &Self::As { -/// # &self.0 -/// # } -/// # fn decode_from(x: Self::As) -> Result { -/// # Ok(Foo(x)) -/// # } -/// # } -/// # impl From> for Foo { -/// # fn from(v: codec::Compact) -> Foo { -/// # v.0 -/// # } -/// # } -/// # fn main() {} -/// ``` -/// -/// If the type you're substituting contains generic parameters, you can "pattern match" on those, and -/// make use of them in the substituted type, like so: -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// substitute_type( -/// path = "sp_runtime::multiaddress::MultiAddress", -/// with = "::subxt::utils::Static<::sp_runtime::MultiAddress>" -/// ) -/// )] -/// mod polkadot {} -/// ``` -/// -/// The above is also an example of using the [`crate::utils::Static`] type to wrap some type which doesn't -/// on it's own implement [`scale_encode::EncodeAsType`] or [`scale_decode::DecodeAsType`], which are required traits -/// for any substitute type to implement by default. -/// -/// ## `derive_for_all_types = "..."` -/// -/// By default, all generated types derive a small set of traits. This attribute allows you to derive additional -/// traits on all generated types: -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// derive_for_all_types = "Eq, PartialEq" -/// )] -/// mod polkadot {} -/// ``` -/// -/// Any substituted types (including the default substitutes) must also implement these traits in order to avoid errors -/// here. -/// -/// ## `derive_for_type(path = "...", derive = "...")` -/// -/// Unlike the above, which derives some trait on every generated type, this attribute allows you to derive traits only -/// for specific types. Note that any types which are used inside the specified type may also need to derive the same traits. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// derive_for_all_types = "Eq, PartialEq", -/// derive_for_type(path = "frame_support::PalletId", derive = "Ord, PartialOrd"), -/// derive_for_type(path = "sp_runtime::ModuleError", derive = "Hash"), -/// )] -/// mod polkadot {} -/// ``` -/// -/// ## `runtime_metadata_insecure_url = "..."` -/// -/// This attribute can be used instead of `runtime_metadata_path` and will tell the macro to download metadata from a node running -/// at the provided URL, rather than a node running locally. This can be useful in CI, but is **not recommended** in production code, -/// since it runs at compile time and will cause compilation to fail if the node at the given address is unavailable or unresponsive. -/// -/// ```rust,ignore -/// #[subxt::subxt( -/// runtime_metadata_insecure_url = "wss://rpc.polkadot.io:443" -/// )] -/// mod polkadot {} -/// ``` -/// -/// ## `generate_docs` -/// -/// By default, documentation is not generated via the macro, since IDEs do not typically make use of it. This attribute -/// forces documentation to be generated, too. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// generate_docs -/// )] -/// mod polkadot {} -/// ``` -/// -/// ## `runtime_types_only` -/// -/// By default, the macro will generate various interfaces to make using Subxt simpler in addition with any types that need -/// generating to make this possible. This attribute makes the codegen only generate the types and not the Subxt interface. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// runtime_types_only -/// )] -/// mod polkadot {} -/// ``` -/// -/// ## `no_default_derives` -/// -/// By default, the macro will add all derives necessary for the generated code to play nicely with Subxt. Adding this attribute -/// removes all default derives. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// runtime_types_only, -/// no_default_derives, -/// derive_for_all_types="codec::Encode, codec::Decode" -/// )] -/// mod polkadot {} -/// ``` -/// -/// **Note**: At the moment, you must derive at least one of `codec::Encode` or `codec::Decode` or `scale_encode::EncodeAsType` or -/// `scale_decode::DecodeAsType` (because we add `#[codec(..)]` attributes on some fields/types during codegen), and you must use this -/// feature in conjunction with `runtime_types_only` (or manually specify a bunch of defaults to make codegen work properly when -/// generating the subxt interfaces). -/// -/// ## `unstable_metadata` -/// -/// This attribute works only in combination with `runtime_metadata_insecure_url`. By default, the macro will fetch the latest stable -/// version of the metadata from the target node. This attribute makes the codegen attempt to fetch the unstable version of -/// the metadata first. This is **not recommended** in production code, since the unstable metadata a node is providing is likely -/// to be incompatible with Subxt. -/// -/// ```rust,ignore -/// #[subxt::subxt( -/// runtime_metadata_insecure_url = "wss://rpc.polkadot.io:443", -/// unstable_metadata -/// )] -/// mod polkadot {} -/// ``` -pub use subxt_macro::subxt; diff --git a/subxt/expand.txt b/subxt/expand.txt deleted file mode 100644 index e3eef50a0a..0000000000 --- a/subxt/expand.txt +++ /dev/null @@ -1,44181 +0,0 @@ -#![feature(prelude_import)] -//! Subxt is a library for interacting with Substrate based nodes. Using it looks something like this: -//! -//! ```rust,ignore -/*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let from = dev::alice(); - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} -*/ -//! ``` -//! -//! Take a look at [the Subxt guide](book) to learn more about how to use Subxt. -#[prelude_import] -use std::prelude::rust_2021::*; -#[macro_use] -extern crate std; -pub mod book { - //! # The Subxt Guide - //! - //! Subxt is a library for interacting with Substrate based nodes. It has a focus on **sub**mitting - //! e**xt**rinsics, hence the name, however it's also capable of reading blocks, storage, events and - //! constants from a node. The aim of this guide is to explain key concepts and get you started with - //! using Subxt. - //! - //! 1. [Features](#features-at-a-glance) - //! 2. [Limitations](#limitations) - //! 3. [Quick start](#quick-start) - //! 4. [Usage](#usage) - //! - //! ## Features at a glance - //! - //! Here's a quick overview of the features that Subxt has to offer: - //! - //! - Subxt allows you to generate a static, type safe interface to a node given some metadata; this - //! allows you to catch many errors at compile time rather than runtime. - //! - Subxt also makes heavy use of node metadata to encode/decode the data sent to/from it. This - //! allows it to target almost any node which can output the correct metadata, and allows it some - //! flexibility in encoding and decoding things to account for cross-node differences. - //! - Subxt has a pallet-oriented interface, meaning that code you write to talk to some pallet on - //! one node will often "Just Work" when pointed at different nodes that use the same pallet. - //! - Subxt can work offline; you can generate and sign transactions, access constants from node - //! metadata and more, without a network connection. This is all checked at compile time, so you - //! can be certain it won't try to establish a network connection if you don't want it to. - //! - Subxt can forego the statically generated interface and build transactions, storage queries - //! and constant queries using data provided at runtime, rather than queries constructed - //! statically. - //! - Subxt can be compiled to WASM to run in the browser, allowing it to back Rust based browser - //! apps, or even bind to JS apps. - //! - //! ## Limitations - //! - //! In various places, you can provide a block hash to access data at a particular block, for - //! instance: - //! - //! - [`crate::storage::StorageClient::at`] - //! - [`crate::events::EventsClient::at`] - //! - [`crate::blocks::BlocksClient::at`] - //! - [`crate::runtime_api::RuntimeApiClient::at`] - //! - //! However, Subxt is (by default) only capable of properly working with blocks that were produced - //! after the most recent runtime update. This is because it uses the most recent metadata given - //! back by a node to encode and decode things. It's possible to decode older blocks produced by a - //! runtime that emits compatible (currently, V14) metadata by manually setting the metadata used by - //! the client using [`crate::client::OnlineClient::set_metadata()`]. - //! - //! Subxt does not support working with blocks produced prior to the runtime update that introduces - //! V14 metadata. It may have some success decoding older blocks using newer metadata, but may also - //! completely fail to do so. - //! - //! ## Quick start - //! - //! Here is a simple but complete example of using Subxt to transfer some tokens from the example - //! accounts, Alice to Bob: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let from = dev::alice(); - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} -*/ - //! ``` - //! - //! This example assumes that a Polkadot node is running locally (Subxt endeavors to support all - //! recent releases). Typically, to use Subxt to talk to some custom Substrate node (for example a - //! parachain node), you'll want to: - //! - //! 1. [Generate an interface](setup::codegen) - //! 2. [Create a config](setup::config) - //! 3. [Use the config to instantiate the client](setup::client) - //! - //! Follow the above links to learn more about each step. - //! - //! ## Usage - //! - //! Once Subxt is configured, the next step is interacting with a node. Follow the links - //! below to learn more about how to use Subxt for each of the following things: - //! - //! - [Transactions](usage::transactions): Subxt can build and submit transactions, wait until they are in - //! blocks, and retrieve the associated events. - //! - [Storage](usage::storage): Subxt can query the node storage. - //! - [Events](usage::events): Subxt can read the events emitted for recent blocks. - //! - [Constants](usage::constants): Subxt can access the constant values stored in a node, which - //! remain the same for a given runtime version. - //! - [Blocks](usage::blocks): Subxt can load recent blocks or subscribe to new/finalized blocks, - //! reading the extrinsics, events and storage at these blocks. - //! - [Runtime APIs](usage::runtime_apis): Subxt can make calls into pallet runtime APIs to retrieve - //! data. - //! - [Custom values](usage::custom_values): Subxt can access "custom values" stored in the metadata. - //! - [Raw RPC calls](usage::rpc): Subxt can be used to make raw RPC requests to compatible nodes. - //! - //! ## Examples - //! - //! Some complete, self contained examples which are not a part of this guide: - //! - //! - [`parachain-example`](https://github.com/paritytech/subxt/tree/master/examples/parachain-example) is an example - //! which uses Zombienet to spawn a parachain locally, and then connects to it using Subxt. - //! - [`wasm-example`](https://github.com/paritytech/subxt/tree/master/examples/wasm-example) is an example of writing - //! a Rust app that contains a Yew based UI, uses Subxt to interact with a chain, and compiles to WASM in order to - //! run entirely in the browser. - pub mod setup { - //! This modules contains details on setting up Subxt: - //! - //! - [Codegen](codegen) - //! - [Client](client) - //! - //! Alternately, [go back](super). - pub mod client { - //! # The Subxt client. - //! - //! The client forms the entry point to all of the Subxt APIs. Every client implements one or - //! both of [`crate::client::OfflineClientT`] and [`crate::client::OnlineClientT`]. - //! - //! Subxt ships with three clients which implement one or both of traits: - //! - An [online client](crate::client::OnlineClient). - //! - An [offline client](crate::client::OfflineClient). - //! - A light client (which is currently still unstable). - //! - //! In theory it's possible for users to implement their own clients, although this isn't generally - //! expected. - //! - //! The provided clients are all generic over the [`crate::config::Config`] that they accept, which - //! determines how they will interact with the chain. - //! - //! In the case of the [`crate::OnlineClient`], we have various ways to instantiate it: - //! - //! - [`crate::OnlineClient::new()`] to connect to a node running locally. This uses the default Subxt - //! backend, and the default RPC client. - //! - [`crate::OnlineClient::from_url()`] to connect to a node at a specific URL. This uses the default Subxt - //! backend, and the default RPC client. - //! - [`crate::OnlineClient::from_rpc_client()`] to instantiate the client with a [`crate::backend::rpc::RpcClient`]. - //! - [`crate::OnlineClient::from_backend()`] to instantiate Subxt using a custom backend. Currently there - //! is just one backend, [`crate::backend::legacy::LegacyBackend`]. This backend can be instantiated from - //! a [`crate::backend::rpc::RpcClient`]. - //! - //! [`crate::backend::rpc::RpcClient`] can itself be instantiated from anything that implements the low level - //! [`crate::backend::rpc::RpcClientT`] trait; this allows you to decide how Subxt will attempt to talk to a node - //! if you'd prefer something other default client. We use this approach under the hood to implement the light client. - //! - //! ## Examples - //! - //! Most of the other examples will instantiate a client. Here are a couple of examples for less common - //! cases. - //! - //! ### Writing a custom [`crate::backend::rpc::RpcClientT`] implementation: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use std::{ - fmt::Write, - pin::Pin, - sync::{Arc, Mutex}, -}; -use subxt::{ - backend::rpc::{RawRpcFuture, RawRpcSubscription, RawValue, RpcClient, RpcClientT}, - OnlineClient, PolkadotConfig, -}; - -// A dummy RPC client that doesn't actually handle requests properly -// at all, but instead just logs what requests to it were made. -struct MyLoggingClient { - log: Arc>, -} - -// We have to implement this fairly low level trait to turn [`MyLoggingClient`] -// into an RPC client that we can make use of in Subxt. Here we just log the requests -// made but don't forward them to any real node, and instead just return nonsense. -impl RpcClientT for MyLoggingClient { - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box> { - writeln!( - self.log.lock().unwrap(), - "{method}({})", - params.as_ref().map(|p| p.get()).unwrap_or("[]") - ) - .unwrap(); - - // We've logged the request; just return garbage. Because a boxed future is returned, - // you're able to run whatever async code you'd need to actually talk to a node. - let res = RawValue::from_string("[]".to_string()).unwrap(); - Box::pin(std::future::ready(Ok(res))) - } - - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription> { - writeln!( - self.log.lock().unwrap(), - "{sub}({}) (unsub: {unsub})", - params.as_ref().map(|p| p.get()).unwrap_or("[]") - ) - .unwrap(); - - // We've logged the request; just return garbage. Because a boxed future is returned, - // and that will return a boxed Stream impl, you have a bunch of flexibility to build - // and return whatever type of Stream you see fit. - let res = RawValue::from_string("[]".to_string()).unwrap(); - let stream = futures::stream::once(async move { Ok(res) }); - let stream: Pin + Send>> = Box::pin(stream); - // This subscription does not provide an ID. - Box::pin(std::future::ready(Ok(RawRpcSubscription { - stream, - id: None, - }))) - } -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Instantiate our replacement RPC client. - let log = Arc::default(); - let rpc_client = { - let inner = MyLoggingClient { - log: Arc::clone(&log), - }; - RpcClient::new(inner) - }; - - // Pass this into our OnlineClient to instantiate it. This will lead to some - // RPC calls being made to fetch chain details/metadata, which will immediately - // fail.. - let _ = OnlineClient::::from_rpc_client(rpc_client).await; - - // But, we can see that the calls were made via our custom RPC client: - println!("Log of calls made:\n\n{}", log.lock().unwrap().as_str()); - Ok(()) -} -*/ - //! ``` - //! - //! ### Creating an [`crate::OfflineClient`]: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::ext::codec::Decode; -use subxt::metadata::Metadata; -use subxt::utils::H256; -use subxt::{config::PolkadotConfig, OfflineClient}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // We need to obtain the following details for an OfflineClient to be instantiated: - - // 1. Genesis hash (RPC call: chain_getBlockHash(0)): - let genesis_hash = { - let h = "91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3"; - let bytes = hex::decode(h).unwrap(); - H256::from_slice(&bytes) - }; - - // 2. A runtime version (system_version constant on a Substrate node has these): - let runtime_version = subxt::backend::RuntimeVersion { - spec_version: 9370, - transaction_version: 20, - }; - - // 3. Metadata (I'll load it from the downloaded metadata, but you can use - // `subxt metadata > file.scale` to download it): - let metadata = { - let bytes = std::fs::read("./artifacts/polkadot_metadata_small.scale").unwrap(); - Metadata::decode(&mut &*bytes).unwrap() - }; - - // Create an offline client using the details obtained above: - let _api = OfflineClient::::new(genesis_hash, runtime_version, metadata); - - Ok(()) -} -*/ - //! ``` - //! - } - pub mod codegen { - //! # Generating an interface - //! - //! The simplest way to use Subxt is to generate an interface to a chain that you'd like to interact - //! with. This generated interface allows you to build transactions and construct queries to access - //! data while leveraging the full type safety of the Rust compiler. - //! - //! ## The `#[subxt]` macro - //! - //! The most common way to generate the interface is to use the [`#[subxt]`](crate::subxt) macro. - //! Using this macro looks something like: - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_tiny.scale")] - //! pub mod polkadot {} - //! ``` - //! - //! The macro takes a path to some node metadata, and uses that to generate the interface you'll use - //! to talk to it. [Go here](crate::subxt) to learn more about the options available to the macro. - //! - //! To obtain this metadata you'll need for the above, you can use the `subxt` CLI tool to download it - //! from a node. The tool can be installed via `cargo`: - //! - //! ```shell - //! cargo install subxt-cli - //! ``` - //! - //! And then it can be used to fetch metadata and save it to a file: - //! - //! ```shell - //! # Download and save all of the metadata: - //! subxt metadata > metadata.scale - //! # Download and save only the pallets you want to generate an interface for: - //! subxt metadata --pallets Balances,System > metadata.scale - //! ``` - //! - //! Explicitly specifying pallets will cause the tool to strip out all unnecessary metadata and type - //! information, making the bundle much smaller in the event that you only need to generate an - //! interface for a subset of the available pallets on the node. - //! - //! ## The CLI tool - //! - //! Using the [`#[subxt]`](crate::subxt) macro carries some downsides: - //! - //! - Using it to generate an interface will have a small impact on compile times (though much less of - //! one if you only need a few pallets). - //! - IDE support for autocompletion and documentation when using the macro interface can be poor. - //! - It's impossible to manually look at the generated code to understand and debug things. - //! - //! If these are an issue, you can manually generate the same code that the macro generates under the hood - //! by using the `subxt codegen` command: - //! - //! ```shell - //! # Install the CLI tool if you haven't already: - //! cargo install subxt-cli - //! # Generate and format rust code, saving it to `interface.rs`: - //! subxt codegen | rustfmt > interface.rs - //! ``` - //! - //! Use `subxt codegen --help` for more options; many of the options available via the macro are - //! also available via the CLI tool, such as the ability to substitute generated types for others, - //! or strip out docs from the generated code. - //! - } - pub mod config { - //! # Creating a Config - //! - //! Subxt requires you to provide a type implementing [`crate::config::Config`] in order to connect to a node. - //! The [`crate::config::Config`] trait for the most part mimics the `frame_system::Config` trait. - //! For most use cases, you can just use one of the following Configs shipped with Subxt: - //! - //! - [`PolkadotConfig`](crate::config::PolkadotConfig) for talking to Polkadot nodes, and - //! - [`SubstrateConfig`](crate::config::SubstrateConfig) for talking to generic nodes built with Substrate. - //! - //! # How to create a Config for a custom chain? - //! - //! Some chains may use config that is not compatible with our [`PolkadotConfig`](crate::config::PolkadotConfig) or - //! [`SubstrateConfig`](crate::config::SubstrateConfig). - //! - //! We now walk through creating a custom [`crate::config::Config`] for a parachain, using the - //! ["Statemint"](https://parachains.info/details/statemint) parachain, also known as "Asset Hub", as an example. It - //! is currently (as of 2023-06-26) deployed on Polkadot and [Kusama (as "Statemine")](https://parachains.info/details/statemine). - //! - //! To construct a valid [`crate::config::Config`] implementation, we need to find out which types to use for `AccountId`, `Hasher`, etc. - //! For this, we need to take a look at the source code of Statemint, which is currently a part of the [Cumulus Github repository](https://github.com/paritytech/cumulus). - //! The crate defining the asset hub runtime can be found [here](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/assets/asset-hub-polkadot). - //! - //! ## `AccountId`, `Hash`, `Hasher` and `Header` - //! - //! For these config types, we need to find out where the parachain runtime implements the `frame_system::Config` trait. - //! Look for a code fragment like `impl frame_system::Config for Runtime { ... }` In the source code. - //! For Statemint it looks like [this](https://github.com/paritytech/cumulus/blob/e2b7ad2061824f490c08df27a922c64f50accd6b/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs#L179) - //! at the time of writing. The `AccountId`, `Hash` and `Header` types of the [frame_system::pallet::Config](https://docs.rs/frame-system/latest/frame_system/pallet/trait.Config.html) - //! correspond to the ones we want to use in our Subxt [crate::Config]. In the Case of Statemint (Asset Hub) they are: - //! - //! - AccountId: `sp_core::crypto::AccountId32` - //! - Hash: `sp_core::H256` - //! - Hasher (type `Hashing` in [frame_system::pallet::Config](https://docs.rs/frame-system/latest/frame_system/pallet/trait.Config.html)): `sp_runtime::traits::BlakeTwo256` - //! - Header: `sp_runtime::generic::Header` - //! - //! Subxt has its own versions of some of these types in order to avoid needing to pull in Substrate dependencies: - //! - //! - `sp_core::crypto::AccountId32` can be swapped with [`crate::utils::AccountId32`]. - //! - `sp_core::H256` is a re-export which subxt also provides as [`crate::config::substrate::H256`]. - //! - `sp_runtime::traits::BlakeTwo256` can be swapped with [`crate::config::substrate::BlakeTwo256`]. - //! - `sp_runtime::generic::Header` can be swapped with [`crate::config::substrate::SubstrateHeader`]. - //! - //! Having a look at how those types are implemented can give some clues as to how to implement other custom types that - //! you may need to use as part of your config. - //! - //! ## `Address`, `Signature` - //! - //! A Substrate runtime is typically constructed by using the [frame_support::construct_runtime](https://docs.rs/frame-support/latest/frame_support/macro.construct_runtime.html) macro. - //! In this macro, we need to specify the type of an `UncheckedExtrinsic`. Most of the time, the `UncheckedExtrinsic` will be of the type - //! `sp_runtime::generic::UncheckedExtrinsic`. - //! The generic parameters `Address` and `Signature` specified when declaring the `UncheckedExtrinsic` type - //! are the types for `Address` and `Signature` we should use with our [crate::Config] implementation. This information can - //! also be obtained from the metadata (see [`frame_metadata::v15::ExtrinsicMetadata`]). In case of Statemint (Polkadot Asset Hub) - //! we see the following types being used in `UncheckedExtrinsic`: - //! - //! - Address: `sp_runtime::MultiAddress` - //! - Signature: `sp_runtime::MultiSignature` - //! - //! As above, Subxt has its own versions of these types that can be used instead to avoid pulling in Substrate dependencies. - //! Using the Subxt versions also makes interacting with generated code (which uses them in some places) a little nicer: - //! - //! - `sp_runtime::MultiAddress` can be swapped with [`crate::utils::MultiAddress`]. - //! - `sp_runtime::MultiSignature` can be swapped with [`crate::utils::MultiSignature`]. - //! - //! ## ExtrinsicParams - //! - //! Chains each have a set of "signed extensions" configured. Signed extensions provide a means to extend how transactions - //! work. Each signed extension can potentially encode some "extra" data which is sent along with a transaction, as well as some - //! "additional" data which is included in the transaction signer payload, but not transmitted along with the transaction. On - //! a node, signed extensions can then perform additional checks on the submitted transactions to ensure their validity. - //! - //! The `ExtrinsicParams` config type expects to be given an implementation of the [`crate::config::ExtrinsicParams`] trait. - //! Implementations of the [`crate::config::ExtrinsicParams`] trait are handed some parameters from Subxt itself, and can - //! accept arbitrary `OtherParams` from users, and are then expected to provide this "extra" and "additional" data when asked - //! via the required [`crate::config::ExtrinsicParamsEncoder`] impl. - //! - //! **In most cases, the default [crate::config::DefaultExtrinsicParams] type will work**: it understands the "standard" - //! signed extensions that are in use, and allows the user to provide things like a tip, and set the extrinsic mortality via - //! [`crate::config::DefaultExtrinsicParamsBuilder`]. It will use the chain metadata to decide which signed extensions to use - //! and in which order. It will return an error if the chain uses a signed extension which it doesn't know how to handle. - //! - //! If the chain uses novel signed extensions (or if you just wish to provide a different interface for users to configure - //! transactions), you can either: - //! - //! 1. Implement a new signed extension and add it to the list. - //! 2. Implement [`crate::config::DefaultExtrinsicParams`] from scratch. - //! - //! See below for examples of each. - //! - //! ### Finding out which signed extensions a chain is using. - //! - //! In either case, you'll want to find out which signed extensions a chain is using. This information can be obtained from - //! the `SignedExtra` parameter of the `UncheckedExtrinsic` of your parachain, which will be a tuple of signed extensions. - //! It can also be obtained from the metadata (see [`frame_metadata::v15::SignedExtensionMetadata`]). - //! - //! For statemint, the signed extensions look like - //! [this](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs#L779): - //! - //! ```rs - //! pub type SignedExtra = ( - //! frame_system::CheckNonZeroSender, - //! frame_system::CheckSpecVersion, - //! frame_system::CheckTxVersion, - //! frame_system::CheckGenesis, - //! frame_system::CheckEra, - //! frame_system::CheckNonce, - //! frame_system::CheckWeight, - //! pallet_asset_tx_payment::ChargeAssetTxPayment, - //! ); - //! ``` - //! - //! Each element of the `SignedExtra` tuple implements [codec::Encode] and `sp_runtime::traits::SignedExtension` - //! which has an associated type `AdditionalSigned` that also implements [codec::Encode]. Let's look at the underlying types - //! for each tuple element. All zero-sized types have been replaced by `()` for simplicity. - //! - //! | tuple element | struct type | `AdditionalSigned` type | - //! | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | - //! | [`frame_system::CheckNonZeroSender`](https://docs.rs/frame-system/latest/frame_system/struct.CheckNonZeroSender.html) | () | () | - //! | [`frame_system::CheckSpecVersion`](https://docs.rs/frame-system/latest/frame_system/struct.CheckSpecVersion.html) | () | [u32] | - //! | [`frame_system::CheckTxVersion`](https://docs.rs/frame-system/latest/frame_system/struct.CheckTxVersion.html) | () | [u32] | - //! | [`frame_system::CheckGenesis`](https://docs.rs/frame-system/latest/frame_system/struct.CheckGenesis.html) | () | `Config::Hash` = `sp_core::H256` | - //! | [`frame_system::CheckMortality`](https://docs.rs/frame-system/latest/frame_system/struct.CheckMortality.html) | `sp_runtime::generic::Era` | `Config::Hash` = `sp_core::H256` | - //! | [`frame_system::CheckNonce`](https://docs.rs/frame-system/latest/frame_system/struct.CheckNonce.html) | `frame_system::pallet::Config::Index` = u32 | () | - //! | [`frame_system::CheckWeight`](https://docs.rs/frame-system/latest/frame_system/struct.CheckWeight.html) | () | () | - //! | [`frame_system::ChargeAssetTxPayment`](https://docs.rs/frame-system/latest/frame_system/struct.ChargeAssetTxPayment.html) | [pallet_asset_tx_payment::ChargeAssetTxPayment](https://docs.rs/pallet-asset-tx-payment/latest/pallet_asset_tx_payment/struct.ChargeAssetTxPayment.html) | () | - //! - //! All types in the `struct type` column make up the "extra" data that we're expected to provide. All types in the - //! `AdditionalSigned` column make up the "additional" data that we're expected to provide. This information will be useful - //! whether we want to implement [`crate::config::SignedExtension`] for a signed extension, or implement - //! [`crate::config::ExtrinsicParams`] from scratch. - //! - //! As it happens, all of the signed extensions in the table are either already exported in [`crate::config::signed_extensions`], - //! or they hand back no "additional" or "extra" data. In both of these cases, the default `ExtrinsicParams` configuration will - //! work out of the box. - //! - //! ### Implementing and adding new signed extensions to the config - //! - //! If you do need to implement a novel signed extension, then you can implement [`crate::config::signed_extensions::SignedExtension`] - //! on a custom type and place it into a new set of signed extensions, like so: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use codec::Encode; -use scale_encode::EncodeAsType; -use scale_info::PortableRegistry; -use subxt::client::OfflineClientT; -use subxt::config::signed_extensions; -use subxt::config::{ - Config, DefaultExtrinsicParamsBuilder, ExtrinsicParams, ExtrinsicParamsEncoder, - ExtrinsicParamsError, -}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod runtime {} - -// We don't need to construct this at runtime, -// so an empty enum is appropriate: -#[derive(EncodeAsType)] -pub enum CustomConfig {} - -impl Config for CustomConfig { - type Hash = subxt::utils::H256; - type AccountId = subxt::utils::AccountId32; - type Address = subxt::utils::MultiAddress; - type Signature = subxt::utils::MultiSignature; - type Hasher = subxt::config::substrate::BlakeTwo256; - type Header = subxt::config::substrate::SubstrateHeader; - type ExtrinsicParams = signed_extensions::AnyOf< - Self, - ( - // Load in the existing signed extensions we're interested in - // (if the extension isn't actually needed it'll just be ignored): - signed_extensions::CheckSpecVersion, - signed_extensions::CheckTxVersion, - signed_extensions::CheckNonce, - signed_extensions::CheckGenesis, - signed_extensions::CheckMortality, - signed_extensions::ChargeAssetTxPayment, - signed_extensions::ChargeTransactionPayment, - // And add a new one of our own: - CustomSignedExtension, - ), - >; - type AssetId = u32; -} - -// Our custom signed extension doesn't do much: -pub struct CustomSignedExtension; - -// Give the extension a name; this allows `AnyOf` to look it -// up in the chain metadata in order to know when and if to use it. -impl signed_extensions::SignedExtension for CustomSignedExtension { - type Decoded = (); - fn matches(identifier: &str, _type_id: u32, _types: &PortableRegistry) -> bool { - identifier == "CustomSignedExtension" - } -} - -// Gather together any params we need for our signed extension, here none. -impl ExtrinsicParams for CustomSignedExtension { - type OtherParams = (); - - fn new>( - _nonce: u64, - _client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CustomSignedExtension) - } -} - -// Encode whatever the extension needs to provide when asked: -impl ExtrinsicParamsEncoder for CustomSignedExtension { - fn encode_extra_to(&self, v: &mut Vec) { - "Hello".encode_to(v); - } - fn encode_additional_to(&self, v: &mut Vec) { - true.encode_to(v) - } -} - -// When composing a tuple of signed extensions, the user parameters we need must -// be able to convert `Into` a tuple of corresponding `OtherParams`. Here, we just -// "hijack" the default param builder, but add the `OtherParams` (`()`) for our -// new signed extension at the end, to make the types line up. IN reality you may wish -// to construct an entirely new interface to provide the relevant `OtherParams`. -pub fn custom( - params: DefaultExtrinsicParamsBuilder, -) -> <::ExtrinsicParams as ExtrinsicParams>::OtherParams { - let (a, b, c, d, e, f, g) = params.build(); - (a, b, c, d, e, f, g, ()) -} - -#[tokio::main] -async fn main() { - // With the config defined, it can be handed to Subxt as follows: - let client = subxt::OnlineClient::::new().await.unwrap(); - - let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); - - // Configure the tx params: - let tx_config = DefaultExtrinsicParamsBuilder::new().tip(1234); - - // And provide them when submitting a transaction: - let _ = client - .tx() - .sign_and_submit_then_watch(&tx_payload, &dev::alice(), custom(tx_config)) - .await; -} -*/ - //! ``` - //! - //! ### Implementing [`crate::config::ExtrinsicParams`] from scratch - //! - //! Alternately, you are free to implement [`crate::config::ExtrinsicParams`] entirely from scratch if you know exactly what "extra" and` - //! "additional" data your node needs and would prefer to craft your own interface. - //! - //! Let's see what this looks like (this config won't work on any real node): - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use codec::Encode; -use subxt::client::OfflineClientT; -use subxt::config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] -pub mod runtime {} - -// We don't need to construct this at runtime, -// so an empty enum is appropriate: -pub enum CustomConfig {} - -impl Config for CustomConfig { - type Hash = subxt::utils::H256; - type AccountId = subxt::utils::AccountId32; - type Address = subxt::utils::MultiAddress; - type Signature = subxt::utils::MultiSignature; - type Hasher = subxt::config::substrate::BlakeTwo256; - type Header = subxt::config::substrate::SubstrateHeader; - type ExtrinsicParams = CustomExtrinsicParams; - type AssetId = u32; -} - -// This represents some arbitrary (and nonsensical) custom parameters that -// will be attached to transaction extra and additional payloads: -pub struct CustomExtrinsicParams { - genesis_hash: T::Hash, - tip: u128, - foo: bool, -} - -// We can provide a "pretty" interface to allow users to provide these: -#[derive(Default)] -pub struct CustomExtrinsicParamsBuilder { - tip: u128, - foo: bool, -} - -impl CustomExtrinsicParamsBuilder { - pub fn new() -> Self { - Default::default() - } - pub fn tip(mut self, value: u128) -> Self { - self.tip = value; - self - } - pub fn enable_foo(mut self) -> Self { - self.foo = true; - self - } -} - -// Describe how to fetch and then encode the params: -impl ExtrinsicParams for CustomExtrinsicParams { - type OtherParams = CustomExtrinsicParamsBuilder; - - // Gather together all of the params we will need to encode: - fn new>( - _nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - Ok(Self { - genesis_hash: client.genesis_hash(), - tip: other_params.tip, - foo: other_params.foo, - }) - } -} - -// Encode the relevant params when asked: -impl ExtrinsicParamsEncoder for CustomExtrinsicParams { - fn encode_extra_to(&self, v: &mut Vec) { - (self.tip, self.foo).encode_to(v); - } - fn encode_additional_to(&self, v: &mut Vec) { - self.genesis_hash.encode_to(v) - } -} - -#[tokio::main] -async fn main() { - // With the config defined, it can be handed to Subxt as follows: - let client = subxt::OnlineClient::::new().await.unwrap(); - - let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); - - // Build your custom "OtherParams": - let tx_config = CustomExtrinsicParamsBuilder::new().tip(1234).enable_foo(); - - // And provide them when submitting a transaction: - let _ = client - .tx() - .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) - .await; -} -*/ - //! ``` - //! - //! ### Using a type from the metadata as a config parameter - //! - //! You can also use types that are generated from chain metadata as type parameters of the Config trait. - //! Just make sure all trait bounds are satisfied. This can often be achieved by using custom derives with the subxt macro. - //! For example, the AssetHub Parachain expects tips to include a `MultiLocation`, which is a type we can draw from the metadata. - //! - //! This example shows what using the `MultiLocation` struct as part of your config would look like in subxt: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::config::{ - Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, PolkadotConfig, SubstrateConfig, -}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt( - runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", - derive_for_type( - path = "xcm::v2::multilocation::MultiLocation", - derive = "Clone", - recursive - ) -)] -pub mod runtime {} -use runtime::runtime_types::xcm::v2::multilocation::{Junctions, MultiLocation}; - -// We don't need to construct this at runtime, so an empty enum is appropriate. -pub enum AssetHubConfig {} - -impl Config for AssetHubConfig { - type Hash = ::Hash; - type AccountId = ::AccountId; - type Address = ::Address; - type Signature = ::Signature; - type Hasher = ::Hasher; - type Header = ::Header; - type ExtrinsicParams = DefaultExtrinsicParams; - // Here we use the MultiLocation from the metadata as a part of the config: - // The `ChargeAssetTxPayment` signed extension that is part of the ExtrinsicParams above, now uses the type: - type AssetId = MultiLocation; -} - -#[tokio::main] -async fn main() { - // With the config defined, we can create an extrinsic with subxt: - let client = subxt::OnlineClient::::new().await.unwrap(); - let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); - - // Build extrinsic params using an asset at this location as a tip: - let location: MultiLocation = MultiLocation { - parents: 3, - interior: Junctions::Here, - }; - let tx_config = DefaultExtrinsicParamsBuilder::::new() - .tip_of(1234, location) - .build(); - - // And provide the extrinsic params including the tip when submitting a transaction: - let _ = client - .tx() - .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) - .await; -} -*/ - //! ``` - } - } - pub mod usage { - //! This modules contains examples of using Subxt; follow the links for more: - //! - //! - [Transactions](transactions) - //! - [Storage](storage) - //! - [Events](events) - //! - [Constants](constants) - //! - [Blocks](blocks) - //! - [Runtime APIs](runtime_apis) - //! - [Unstable Light Client](light_client) - //! - [Custom Values](custom_values) - //! - [RPC calls](rpc) - //! - //! Alternately, [go back](super). - pub mod blocks { - //! # Blocks - //! - //! The [blocks API](crate::blocks::BlocksClient) in Subxt unifies many of the other interfaces, and - //! allows you to: - //! - //! - Access information about specific blocks (see [`crate::blocks::BlocksClient::at()`] and - //! [`crate::blocks::BlocksClient::at_latest()`]). - //! - Subscribe to [all](crate::blocks::BlocksClient::subscribe_all()), - //! [best](crate::blocks::BlocksClient::subscribe_best()) or - //! [finalized](crate::blocks::BlocksClient::subscribe_finalized()) blocks as they are produced. - //! Prefer to subscribe to finalized blocks unless you know what you're doing. - //! - //! In either case, you'll end up with [`crate::blocks::Block`]'s, from which you can access various - //! information about the block, such a the [header](crate::blocks::Block::header()), [block - //! number](crate::blocks::Block::number()) and [body (the extrinsics)](crate::blocks::Block::extrinsics()). - //! [`crate::blocks::Block`]'s also provide shortcuts to other Subxt APIs that will operate at the - //! given block: - //! - //! - [storage](crate::blocks::Block::storage()), - //! - [events](crate::blocks::Block::events()) - //! - [runtime APIs](crate::blocks::Block::runtime_api()) - //! - //! Aside from these links to other Subxt APIs, the main thing that we can do here is iterate over and - //! decode the extrinsics in a block body. - //! - //! ## Decoding Extrinsics - //! - //! Given a block, you can [download the block body](crate::blocks::Block::extrinsics()) and [iterate over - //! the extrinsics](crate::blocks::Extrinsics::iter()) stored within it. The extrinsics yielded are of type - //! [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), which is just a blob of bytes that also stores which - //! pallet and call in that pallet it belongs to. It also contains information about signed extensions that - //! have been used for submitting this extrinsic. - //! - //! To use the extrinsic, you probably want to decode it into a concrete Rust type. These Rust types representing - //! extrinsics from different pallets can be generated from metadata using the subxt macro or the CLI tool. - //! - //! When decoding the extrinsic into a static type you have two options: - //! - //! ### Statically decode the extrinsics into [the root extrinsic type](crate::blocks::ExtrinsicDetails::as_root_extrinsic()) - //! - //! The root extrinsic type generated by subxt is a Rust enum with one variant for each pallet. Each of these - //! variants has a field that is another enum whose variants cover all calls of the respective pallet. - //! If the extrinsic bytes are valid and your metadata matches the chain's metadata, decoding the bytes of an extrinsic into - //! this root extrinsic type should always succeed. - //! - //! This example shows how to subscribe to blocks and decode the extrinsics in each block into the root extrinsic type. - //! Once we get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), we can decode it statically or dynamically. - //! We can also access details about the extrinsic, including the associated events and signed extensions. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Subscribe to all finalized blocks: - let mut blocks_sub = api.blocks().subscribe_finalized().await?; - - // For each block, print a bunch of information about it: - while let Some(block) = blocks_sub.next().await { - let block = block?; - - let block_number = block.header().number; - let block_hash = block.hash(); - - println!("Block #{block_number}:"); - println!(" Hash: {block_hash}"); - println!(" Extrinsics:"); - - // Log each of the extrinsic with it's associated events: - let extrinsics = block.extrinsics().await?; - for ext in extrinsics.iter() { - let ext = ext?; - let idx = ext.index(); - let events = ext.events().await?; - let bytes_hex = format!("0x{}", hex::encode(ext.bytes())); - - // See the API docs for more ways to decode extrinsics: - let decoded_ext = ext.as_root_extrinsic::(); - - println!(" Extrinsic #{idx}:"); - println!(" Bytes: {bytes_hex}"); - println!(" Decoded: {decoded_ext:?}"); - - println!(" Events:"); - for evt in events.iter() { - let evt = evt?; - let pallet_name = evt.pallet_name(); - let event_name = evt.variant_name(); - let event_values = evt.field_values()?; - - println!(" {pallet_name}_{event_name}"); - println!(" {}", event_values); - } - - println!(" Signed Extensions:"); - if let Some(signed_extensions) = ext.signed_extensions() { - for signed_extension in signed_extensions.iter() { - let signed_extension = signed_extension?; - let name = signed_extension.name(); - let value = signed_extension.value()?.to_string(); - println!(" {name}: {value}"); - } - } - } - } - - Ok(()) -} -*/ - //! ``` - //! - //! ### Statically decode the extrinsic into [a specific pallet call](crate::blocks::ExtrinsicDetails::as_extrinsic()) - //! - //! This is useful if you are expecting a specific extrinsic to be part of some block. If the extrinsic you try to decode - //! is a different extrinsic, an `Ok(None)` value is returned from [`as_extrinsic::()`](crate::blocks::ExtrinsicDetails::as_extrinsic()); - //! - //! If you are only interested in finding specific extrinsics in a block, you can also [iterate over all of them](crate::blocks::Extrinsics::find), - //! get only [the first one](crate::blocks::Extrinsics::find_first), or [the last one](crate::blocks::Extrinsics::find_last). - //! - //! The following example monitors `TransferKeepAlive` extrinsics on the Polkadot network. - //! We statically decode them and access the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and [account nonce](crate::blocks::ExtrinsicSignedExtensions::nonce()) signed extensions. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{ - utils::{AccountId32, MultiAddress}, - OnlineClient, PolkadotConfig, -}; - -use codec::Decode; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -use polkadot::balances::calls::types::TransferKeepAlive; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client that subscribes to blocks of the Polkadot network. - let api = OnlineClient::::from_url("wss://rpc.polkadot.io:443").await?; - - // Subscribe to all finalized blocks: - let mut blocks_sub = api.blocks().subscribe_finalized().await?; - - // For each block, print details about the `TransferKeepAlive` transactions we are interested in. - while let Some(block) = blocks_sub.next().await { - let block = block?; - let block_number = block.header().number; - let block_hash = block.hash(); - println!("Block #{block_number} ({block_hash}):"); - - let extrinsics = block.extrinsics().await?; - for transfer in extrinsics.find::() { - let transfer = transfer?; - - let Some(extensions) = transfer.details.signed_extensions() else { - panic!("TransferKeepAlive should be signed") - }; - - let addr_bytes = transfer - .details - .address_bytes() - .expect("TransferKeepAlive should be signed"); - let sender = MultiAddress::::decode(&mut &addr_bytes[..]) - .expect("Decoding should work"); - let sender = display_address(&sender); - let receiver = display_address(&transfer.value.dest); - let value = transfer.value.value; - let tip = extensions.tip().expect("Should have tip"); - let nonce = extensions.nonce().expect("Should have nonce"); - - println!( - " Transfer of {value} DOT:\n {sender} (Tip: {tip}, Nonce: {nonce}) ---> {receiver}", - ); - } - } - - Ok(()) -} - -fn display_address(addr: &MultiAddress) -> String { - if let MultiAddress::Id(id32) = addr { - format!("{id32}") - } else { - "MultiAddress::...".into() - } -} -*/ - //! ``` - //! - //! ### Dynamically decode the extrinsic - //! - //! Sometimes you might use subxt with metadata that is not known at compile time. In this case, you do not have access to a statically generated - //! interface module that contains the relevant Rust types. You can [decode ExtrinsicDetails dynamically](crate::blocks::ExtrinsicDetails::field_values()), - //! which gives you access to it's fields as a [scale value composite](scale_value::Composite). - //! The following example looks for signed extrinsics on the Polkadot network and retrieves their pallet name, variant name, data fields and signed extensions dynamically. - //! Notice how we do not need to use code generation via the subxt macro. The only fixed component we provide is the [PolkadotConfig](crate::config::PolkadotConfig). - //! Other than that it works in a chain-agnostic way: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client that subscribes to blocks of the Polkadot network. - let api = OnlineClient::::from_url("wss://rpc.polkadot.io:443").await?; - - // Subscribe to all finalized blocks: - let mut blocks_sub = api.blocks().subscribe_finalized().await?; - while let Some(block) = blocks_sub.next().await { - let block = block?; - let block_number = block.header().number; - let block_hash = block.hash(); - println!("Block #{block_number} ({block_hash})"); - - // Decode each signed extrinsic in the block dynamically - let extrinsics = block.extrinsics().await?; - for ext in extrinsics.iter() { - let ext = ext?; - - let Some(signed_extensions) = ext.signed_extensions() else { - continue; // we do not look at inherents in this example - }; - - let meta = ext.extrinsic_metadata()?; - let fields = ext.field_values()?; - - println!(" {}/{}", meta.pallet.name(), meta.variant.name); - println!(" Signed Extensions:"); - for signed_ext in signed_extensions.iter() { - let signed_ext = signed_ext?; - // We only want to take a look at these 3 signed extensions, because the others all just have unit fields. - if ["CheckMortality", "CheckNonce", "ChargeTransactionPayment"] - .contains(&signed_ext.name()) - { - println!(" {}: {}", signed_ext.name(), signed_ext.value()?); - } - } - println!(" Fields:"); - println!(" {}\n", fields); - } - } - - Ok(()) -} -*/ - //! ``` - //! - //! ## Decoding signed extensions - //! - //! Extrinsics can contain signed extensions. The signed extensions can be different across chains. - //! The [Config](crate::Config) implementation for your chain defines which signed extensions you expect. - //! Once you get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails) for an extrinsic you are interested in, - //! you can try to [get its signed extensions](crate::blocks::ExtrinsicDetails::signed_extensions()). - //! These are only available on signed extrinsics. You can try to [find a specific signed extension](crate::blocks::ExtrinsicSignedExtensions::find), - //! in the returned [signed extensions](crate::blocks::ExtrinsicSignedExtensions). - //! - //! Subxt also provides utility functions to get the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and the - //! [account nonce](crate::blocks::ExtrinsicSignedExtensions::tip()) associated with an extrinsic, given its signed extensions. - //! If you prefer to do things dynamically you can get the data of the signed extension as a [scale value](crate::blocks::ExtrinsicSignedExtension::value()). - //! - } - pub mod constants { - //! # Constants - //! - //! There are various constants stored in a node; the types and values of these are defined in a - //! runtime, and can only change when the runtime is updated. Much like [`super::storage`], we can - //! query these using Subxt by taking the following steps: - //! - //! 1. [Constructing a constant query](#constructing-a-query). - //! 2. [Submitting the query to get back the associated value](#submitting-it). - //! - //! ## Constructing a constant query - //! - //! We can use the statically generated interface to build constant queries: - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] - //! pub mod polkadot {} - //! - //! let constant_query = polkadot::constants().system().block_length(); - //! ``` - //! - //! Alternately, we can dynamically construct a constant query: - //! - //! ```rust,no_run - //! use subxt::dynamic::Value; - //! - //! let storage_query = subxt::dynamic::constant("System", "BlockLength"); - //! ``` - //! - //! Static queries also have a static return type, so the constant is decoded appropriately. In - //! addition, they are validated at runtime to ensure that they align with the current node state. - //! Dynamic queries must be decoded into some static type manually, or into the dynamic - //! [`crate::dynamic::Value`] type. - //! - //! ## Submitting it - //! - //! Constant queries are handed to Subxt via [`crate::constants::ConstantsClient::at()`]. It's worth - //! noting that constant values are pulled directly out of the node metadata which Subxt has - //! already acquired, and so this function requires no network access and is available from a - //! [`crate::OfflineClient`]. - //! - //! Here's an example using a static query: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // A query to obtain some contant: - let constant_query = polkadot::constants().system().block_length(); - - // Obtain the value: - let value = api.constants().at(&constant_query)?; - - println!("Block length: {value:?}"); - Ok(()) -} -*/ - //! ``` - //! - //! And here's one using a dynamic query: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // A dynamic query to obtain some contant: - let constant_query = subxt::dynamic::constant("System", "BlockLength"); - - // Obtain the value: - let value = api.constants().at(&constant_query)?; - - println!("Constant bytes: {:?}", value.encoded()); - println!("Constant value: {}", value.to_value()?); - Ok(()) -} -*/ - //! ``` - //! - } - pub mod custom_values { - //! # Custom Values - //! - //! Substrate-based chains can expose custom values in their metadata. - //! Each of these values: - //! - //! - can be accessed by a unique __name__. - //! - refers to a concrete __type__ stored in the metadata. - //! - contains a scale encoded __value__ of that type. - //! - //! ## Getting a custom value - //! - //! Custom values can be accessed via a [`CustomValuesClient`](crate::custom_values::CustomValuesClient). - //! The client exposes an `at` function by which a custom value can be fetched, given an address to this custom value. - //! An address can be as simple as the aforementioned __name__ as a [str]. This will return a dynamic value, that you can manually decode into the type you want. - //! Suppose, the custom types contain a value of type `Foo` under the name `"foo"` you can access it like in this example: - //! - //! ```rust,ignore - //! use subxt::{OnlineClient, PolkadotConfig, ext::{codec::Decode, scale_decode::DecodeAsType}}; - //! - //! #[derive(Decode, DecodeAsType, Debug)] - //! struct Foo { - //! n: u8, - //! b: bool, - //! } - //! - //! let api = OnlineClient::::new().await?; - //! let custom_value_client = api.custom_values(); - //! let foo_dynamic = custom_value_client.at("foo")?; - //! let foo: Foo = foo_dynamic.as_type()?; - //! - //! ``` - //! - //! Alternatively we also provide a statically generated api for custom values: - //! - //! ```rust,ignore - //! #[subxt::subxt(runtime_metadata_path = "some_metadata.scale")] - //! pub mod interface {} - //! - //! let static_address = interface::custom().foo(); - //! - //! let api = OnlineClient::::new().await?; - //! let custom_value_client = api.custom_values(); - //! - //! // Now the `at()` function already decodes the value into the Foo type: - //! let foo = custom_value_client.at(&static_address)?; - //! ``` - //! - //! Note: Names of custom values are converted to __snake_case__ to produce a valid function name during code generation. - //! If there are multiple values where the names would be equal when converted to __snake_case__, functions might not be statically generated for some of them, because of naming conflicts. - //! Make sure names in the custom values of your metadata differ significantly. - } - pub mod events { - //! # Events - //! - //! In the process of adding extrinsics to a block, they are executed. When extrinsics are executed, - //! they normally produce events describing what's happening (at the very least, an event dictating whether - //! the extrinsic has succeeded or failed). The node may also emit some events of its own as the block is - //! processed. - //! - //! Events live in a single location in node storage which is overwritten at each block. Normal nodes tend to - //! keep a snapshot of the state at a small number of previous blocks, so you can sometimes access - //! older events by using [`crate::events::EventsClient::at()`] and providing an older block hash. - //! - //! When we submit transactions using Subxt, methods like [`crate::tx::TxProgress::wait_for_finalized_success()`] - //! return [`crate::blocks::ExtrinsicEvents`], which can be used to iterate and inspect the events produced - //! by that transaction being executed. We can also access _all_ of the events produced in a single block using one - //! of these two interfaces: - //! - //! ```rust,no_run - //! # #[tokio::main] - //! # async fn main() -> Result<(), Box> { - //! use subxt::client::OnlineClient; - //! use subxt::config::PolkadotConfig; - //! - //! // Create client: - //! let client = OnlineClient::::new().await?; - //! - //! // Get events from the latest block (use .at() to specify a block hash): - //! let events = client.blocks().at_latest().await?.events().await?; - //! // We can use this shorthand too: - //! let events = client.events().at_latest().await?; - //! # Ok(()) - //! # } - //! ``` - //! - //! Once we've loaded our events, we can iterate all events or search for specific events via - //! methods like [`crate::events::Events::iter()`] and [`crate::events::Events::find()`]. See - //! [`crate::events::Events`] and [`crate::events::EventDetails`] for more information. - //! - //! ## Example - //! - //! Here's an example which puts this all together: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Get events for the latest block: - let events = api.events().at_latest().await?; - - // We can dynamically decode events: - println!("Dynamic event details:"); - for event in events.iter() { - let event = event?; - - let pallet = event.pallet_name(); - let variant = event.variant_name(); - let field_values = event.field_values()?; - - println!("{pallet}::{variant}: {field_values}"); - } - - // Or we can attempt to statically decode them into the root Event type: - println!("Static event details:"); - for event in events.iter() { - let event = event?; - - if let Ok(ev) = event.as_root_event::() { - println!("{ev:?}"); - } else { - println!(""); - } - } - - // Or we can look for specific events which match our statically defined ones: - let transfer_event = events.find_first::()?; - if let Some(ev) = transfer_event { - println!(" - Balance transfer success: value: {:?}", ev.amount); - } else { - println!(" - No balance transfer event found in this block"); - } - - Ok(()) -} -*/ - //! ``` - //! - } - pub mod light_client { - //! # Light Client - //! - //! The light client based interface uses _Smoldot_ to connect to a _chain_, rather than an individual - //! node. This means that you don't have to trust a specific node when interacting with some chain. - //! - //! This feature is currently unstable. Use the `unstable-light-client` feature flag to enable it. - //! To use this in WASM environments, also enable the `web` feature flag. - //! - //! To connect to a blockchain network, the Light Client requires a trusted sync state of the network, - //! known as a _chain spec_. One way to obtain this is by making a `sync_state_genSyncSpec` RPC call to a - //! trusted node belonging to the chain that you wish to interact with. - //! - //! The following is an example of fetching the chain spec from a local running node on port 9933: - //! - //! ```bash - //! curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "sync_state_genSyncSpec", "params":[true]}' http://localhost:9933/ | jq .result > chain_spec.json - //! ``` - //! - //! Alternately, you can have the `LightClient` download the chain spec from a trusted node when it - //! initializes, which is not recommended in production but is useful for examples and testing, as below. - //! - //! ## Examples - //! - //! ### Basic Example - //! - //! This example connects to a local chain and submits a transaction. To run this, you first need - //! to have a local polkadot node running using the following command: - //! - //! ```text - //! polkadot --dev --node-key 0000000000000000000000000000000000000000000000000000000000000001 - //! ``` - //! - //! Leave that running for a minute, and then you can run the example using the following command - //! in the `subxt` crate: - //! - //! ```bash - //! cargo run --example light_client_tx_basic --features=unstable-light-client - //! ``` - //! - //! This is the code that will be executed: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{client::LightClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // The smoldot logs are informative: - tracing_subscriber::fmt::init(); - - // Create a light client by fetching the chain spec of a local running node. - // In this case, because we start one single node, the bootnodes must be overwritten - // for the light client to connect to the local node. - // - // The `12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp` is the P2P address - // from a local polkadot node starting with - // `--node-key 0000000000000000000000000000000000000000000000000000000000000001` - let api = LightClient::::builder() - .bootnodes([ - "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp", - ]) - .build_from_url("ws://127.0.0.1:9944") - .await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let from = dev::alice(); - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} -*/ - //! ``` - //! - //! ### Connecting to a parachain - //! - //! This example connects to a parachain using the light client. Currently, it's quite verbose to do this. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use futures::StreamExt; -use std::{iter, num::NonZeroU32}; -use subxt::{ - client::{LightClient, RawLightClient}, - PolkadotConfig, -}; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -const POLKADOT_SPEC: &str = include_str!("../../artifacts/demo_chain_specs/polkadot.json"); -const ASSET_HUB_SPEC: &str = - include_str!("../../artifacts/demo_chain_specs/polkadot_asset_hub.json"); - -#[tokio::main] -async fn main() -> Result<(), Box> { - // The smoldot logs are informative: - tracing_subscriber::fmt::init(); - - // Connecting to a parachain is a multi step process. - - // Step 1. Construct a new smoldot client. - let mut client = - subxt_lightclient::smoldot::Client::new(subxt_lightclient::smoldot::DefaultPlatform::new( - "subxt-example-light-client".into(), - "version-0".into(), - )); - - // Step 2. Connect to the relay chain of the parachain. For this example, the Polkadot relay chain. - let polkadot_connection = client - .add_chain(subxt_lightclient::smoldot::AddChainConfig { - specification: POLKADOT_SPEC, - json_rpc: subxt_lightclient::smoldot::AddChainConfigJsonRpc::Enabled { - max_pending_requests: NonZeroU32::new(128).unwrap(), - max_subscriptions: 1024, - }, - potential_relay_chains: iter::empty(), - database_content: "", - user_data: (), - }) - .expect("Light client chain added with valid spec; qed"); - let polkadot_json_rpc_responses = polkadot_connection - .json_rpc_responses - .expect("Light client configured with json rpc enabled; qed"); - let polkadot_chain_id = polkadot_connection.chain_id; - - // Step 3. Connect to the parachain. For this example, the Asset hub parachain. - let assethub_connection = client - .add_chain(subxt_lightclient::smoldot::AddChainConfig { - specification: ASSET_HUB_SPEC, - json_rpc: subxt_lightclient::smoldot::AddChainConfigJsonRpc::Enabled { - max_pending_requests: NonZeroU32::new(128).unwrap(), - max_subscriptions: 1024, - }, - // The chain specification of the asset hub parachain mentions that the identifier - // of its relay chain is `polkadot`. - potential_relay_chains: [polkadot_chain_id].into_iter(), - database_content: "", - user_data: (), - }) - .expect("Light client chain added with valid spec; qed"); - let parachain_json_rpc_responses = assethub_connection - .json_rpc_responses - .expect("Light client configured with json rpc enabled; qed"); - let parachain_chain_id = assethub_connection.chain_id; - - // Step 4. Turn the smoldot client into a raw client. - let raw_light_client = RawLightClient::builder() - .add_chain(polkadot_chain_id, polkadot_json_rpc_responses) - .add_chain(parachain_chain_id, parachain_json_rpc_responses) - .build(client) - .await?; - - // Step 5. Obtain a client to target the relay chain and the parachain. - let polkadot_api: LightClient = - raw_light_client.for_chain(polkadot_chain_id).await?; - let parachain_api: LightClient = - raw_light_client.for_chain(parachain_chain_id).await?; - - // Step 6. Subscribe to the finalized blocks of the chains. - let polkadot_sub = polkadot_api - .blocks() - .subscribe_finalized() - .await? - .map(|block| ("Polkadot", block)); - let parachain_sub = parachain_api - .blocks() - .subscribe_finalized() - .await? - .map(|block| ("AssetHub", block)); - let mut stream_combinator = futures::stream::select(polkadot_sub, parachain_sub); - - while let Some((chain, block)) = stream_combinator.next().await { - let block = block?; - - println!(" Chain {:?} hash={:?}", chain, block.hash()); - } - - Ok(()) -} -*/ - //! ``` - } - pub mod rpc { - //! # RPC calls - //! - //! Subxt exposes low level interfaces that can be used to make RPC requests; [`crate::backend::legacy::rpc_methods`] - //! and [`crate::backend::unstable::rpc_methods`]. - //! - //! These interfaces cannot be accessed directly through an [`crate::OnlineClient`]; this is so that the high level - //! Subxt APIs can target either the "legacy" or the more modern "unstable" sets of RPC methods by selecting an appropriate - //! [`crate::backend::Backend`]. It also means that there could exist a backend in the future that doesn't use JSON-RPC at all. - //! - //! # Example - //! - //! Here's an example which calls some legacy JSON-RPC methods, and reuses the same connection to run a full Subxt client - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::backend::{legacy::LegacyRpcMethods, rpc::RpcClient}; -use subxt::config::DefaultExtrinsicParamsBuilder as Params; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // First, create a raw RPC client: - let rpc_client = RpcClient::from_url("ws://127.0.0.1:9944").await?; - - // Use this to construct our RPC methods: - let rpc = LegacyRpcMethods::::new(rpc_client.clone()); - - // We can use the same client to drive our full Subxt interface too: - let api = OnlineClient::::from_rpc_client(rpc_client.clone()).await?; - - // Now, we can make some RPC calls using some legacy RPC methods. - println!( - "📛 System Name: {:?}\n🩺 Health: {:?}\n🖫 Properties: {:?}\n🔗 Chain: {:?}\n", - rpc.system_name().await?, - rpc.system_health().await?, - rpc.system_properties().await?, - rpc.system_chain().await? - ); - - // We can also interleave RPC calls and using the full Subxt client, here to submit multiple - // transactions using the legacy `system_account_next_index` RPC call, which returns a nonce - // that is adjusted for any transactions already in the pool: - - let alice = dev::alice(); - let bob = dev::bob(); - - loop { - let current_nonce = rpc - .system_account_next_index(&alice.public_key().into()) - .await?; - let current_header = rpc.chain_get_header(None).await?.unwrap(); - - let ext_params = Params::new().mortal(¤t_header, 8).build(); - - let balance_transfer = polkadot::tx() - .balances() - .transfer_allow_death(bob.public_key().into(), 1_000_000); - - let ext_hash = api - .tx() - .create_signed_with_nonce(&balance_transfer, &alice, current_nonce, ext_params)? - .submit() - .await?; - - println!("Submitted ext {ext_hash} with nonce {current_nonce}"); - - // Sleep less than block time, but long enough to ensure - // not all transactions end up in the same block. - tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - } -} -*/ - //! ``` - } - pub mod runtime_apis { - //! # Runtime API interface - //! - //! The Runtime API interface allows Subxt to call runtime APIs exposed by certain pallets in order - //! to obtain information. Much like [`super::storage`] and [`super::transactions`], Making a runtime - //! call to a node and getting the response back takes the following steps: - //! - //! 1. [Constructing a runtime call](#constructing-a-runtime-call) - //! 2. [Submitting it to get back the response](#submitting-it) - //! - //! **Note:** Runtime APIs are only available when using V15 metadata, which is currently unstable. - //! You'll need to use `subxt metadata --version unstable` command to download the unstable V15 metadata, - //! and activate the `unstable-metadata` feature in Subxt for it to also use this metadata from a node. The - //! metadata format is unstable because it may change and break compatibility with Subxt at any moment, so - //! use at your own risk. - //! - //! ## Constructing a runtime call - //! - //! We can use the statically generated interface to build runtime calls: - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] - //! pub mod polkadot {} - //! - //! let runtime_call = polkadot::apis().metadata().metadata_versions(); - //! ``` - //! - //! Alternately, we can dynamically construct a runtime call: - //! - //! ```rust,no_run - //! use subxt::dynamic::Value; - //! - //! let runtime_call = subxt::dynamic::runtime_api_call( - //! "Metadata", - //! "metadata_versions", - //! Vec::>::new() - //! ); - //! ``` - //! - //! All valid runtime calls implement [`crate::runtime_api::RuntimeApiPayload`], a trait which - //! describes how to encode the runtime call arguments and what return type to decode from the - //! response. - //! - //! ## Submitting it - //! - //! Runtime calls can be handed to [`crate::runtime_api::RuntimeApi::call()`], which will submit - //! them and hand back the associated response. - //! - //! ### Making a static Runtime API call - //! - //! The easiest way to make a runtime API call is to use the statically generated interface. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{config::PolkadotConfig, OnlineClient}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Create a runtime API payload that calls into - // `AccountNonceApi_account_nonce` function. - let account = dev::alice().public_key().into(); - let runtime_api_call = polkadot::apis().account_nonce_api().account_nonce(account); - - // Submit the call and get back a result. - let nonce = api - .runtime_api() - .at_latest() - .await? - .call(runtime_api_call) - .await; - - println!("AccountNonceApi_account_nonce for Alice: {:?}", nonce); - Ok(()) -} -*/ - //! ``` - //! - //! ### Making a dynamic Runtime API call - //! - //! If you'd prefer to construct the call at runtime, you can do this using the - //! [`crate::dynamic::runtime_api_call`] method. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::dynamic::Value; -use subxt::{config::PolkadotConfig, OnlineClient}; -use subxt_signer::sr25519::dev; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Create a dynamically runtime API payload that calls the - // `AccountNonceApi_account_nonce` function. - let account = dev::alice().public_key(); - let runtime_api_call = subxt::dynamic::runtime_api_call( - "AccountNonceApi", - "account_nonce", - vec![Value::from_bytes(account)], - ); - - // Submit the call to get back a result. - let nonce = api - .runtime_api() - .at_latest() - .await? - .call(runtime_api_call) - .await?; - - println!("Account nonce: {:#?}", nonce.to_value()); - Ok(()) -} -*/ - //! ``` - //! - //! ### Making a raw call - //! - //! This is generally discouraged in favour of one of the above, but may be necessary (especially if - //! the node you're talking to does not yet serve V15 metadata). Here, you must manually encode - //! the argument bytes and manually provide a type for the response bytes to be decoded into. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::ext::codec::Compact; -use subxt::ext::frame_metadata::RuntimeMetadataPrefixed; -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a client to use: - let api = OnlineClient::::new().await?; - - // Use runtime APIs at the latest block: - let runtime_apis = api.runtime_api().at_latest().await?; - - // Ask for metadata and decode it: - let (_, meta): (Compact, RuntimeMetadataPrefixed) = - runtime_apis.call_raw("Metadata_metadata", None).await?; - - println!("{meta:?}"); - Ok(()) -} -*/ - //! ``` - //! - } - pub mod storage { - //! # Storage - //! - //! A Substrate based chain can be seen as a key/value database which starts off at some initial - //! state, and is modified by the extrinsics in each block. This database is referred to as the - //! node storage. With Subxt, you can query this key/value storage with the following steps: - //! - //! 1. [Constructing a storage query](#constructing-a-storage-query). - //! 2. [Submitting the query to get back the associated values](#submitting-it). - //! - //! ## Constructing a storage query - //! - //! We can use the statically generated interface to build storage queries: - //! - //! ```rust,no_run - //! use subxt_signer::sr25519::dev; - //! - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] - //! pub mod polkadot {} - //! - //! let account = dev::alice().public_key().into(); - //! let storage_query = polkadot::storage().system().account(&account); - //! ``` - //! - //! Alternately, we can dynamically construct a storage query. This will not be type checked or - //! validated until it's submitted: - //! - //! ```rust,no_run - //! use subxt_signer::sr25519::dev; - //! use subxt::dynamic::Value; - //! - //! let account = dev::alice().public_key(); - //! let storage_query = subxt::dynamic::storage("System", "Account", vec![ - //! Value::from_bytes(account) - //! ]); - //! ``` - //! - //! As well as accessing specific entries, some storage locations can also be iterated over (such as - //! the map of account information). To do this, suffix `_iter` onto the query constructor (this - //! will only be available on static constructors when iteration is actually possible): - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] - //! pub mod polkadot {} - //! - //! // A static query capable of iterating over accounts: - //! let storage_query = polkadot::storage().system().account_iter(); - //! // A dynamic query to do the same: - //! let storage_query = subxt::dynamic::storage("System", "Account", ()); - //! ``` - //! - //! Some storage entries are maps with multiple keys. As an example, we might end up with - //! an API like `runtime::storage().foo().bar(u8, bool, u16, String)` to fetch some entry "bar". - //! When this is the case, the codegen will generate multiple iterator query functions alongside - //! the function to fetch an individual value: - //! - //! - `runtime::storage().foo().bar(u8, bool, u16, String)`: fetch a single entry from the "bar" map. - //! - `runtime::storage().foo().bar_iter()`: iterate over all of the entries in the "bar" map. - //! - `runtime::storage().foo().bar_iter1(u8)`: iterate over all of the entries in the "bar" map under - //! a given `u8`. - //! - `runtime::storage().foo().bar_iter2(u8, bool)`: iterate over all of the entries in the "bar" map under - //! a given `u8` and `bool` value. - //! - `runtime::storage().foo().bar_iter3(u8, bool, u16)`: iterate over all of the entries in the "bar" map under - //! a given `u8`, `bool` and `u16` value. - //! - //! All valid storage queries implement [`crate::storage::StorageAddress`]. As well as describing - //! how to build a valid storage query, this trait also has some associated types that determine the - //! shape of the result you'll get back, and determine what you can do with it (ie, can you iterate - //! over storage entries using it). - //! - //! Static queries set appropriate values for these associated types, and can therefore only be used - //! where it makes sense. Dynamic queries don't know any better and can be used in more places, but - //! may fail at runtime instead if they are invalid in those places. - //! - //! ## Submitting it - //! - //! Storage queries can be handed to various functions in [`crate::storage::Storage`] in order to - //! obtain the associated values (also referred to as storage entries) back. - //! - //! ### Fetching storage entries - //! - //! The simplest way to access storage entries is to construct a query and then call either - //! [`crate::storage::Storage::fetch()`] or [`crate::storage::Storage::fetch_or_default()`] (the - //! latter will only work for storage queries that have a default value when empty): - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a storage query to access account information. - let account = dev::alice().public_key().into(); - let storage_query = polkadot::storage().system().account(&account); - - // Use that query to `fetch` a result. This returns an `Option<_>`, which will be - // `None` if no value exists at the given address. You can also use `fetch_default` - // where applicable, which will return the default value if none exists. - let result = api - .storage() - .at_latest() - .await? - .fetch(&storage_query) - .await?; - - println!("Alice has free balance: {}", result.unwrap().data.free); - Ok(()) -} -*/ - //! ``` - //! - //! For completeness, below is an example using a dynamic query instead. The return type from a - //! dynamic query is a [`crate::dynamic::DecodedValueThunk`], which can be decoded into a - //! [`crate::dynamic::Value`], or else the raw bytes can be accessed instead. - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::dynamic::{At, Value}; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a dynamic storage query to access account information. - let account = dev::alice().public_key(); - let storage_query = - subxt::dynamic::storage("System", "Account", vec![Value::from_bytes(account)]); - - // Use that query to `fetch` a result. Because the query is dynamic, we don't know what the result - // type will be either, and so we get a type back that can be decoded into a dynamic Value type. - let result = api - .storage() - .at_latest() - .await? - .fetch(&storage_query) - .await?; - let value = result.unwrap().to_value()?; - - println!("Alice has free balance: {:?}", value.at("data").at("free")); - Ok(()) -} -*/ - //! ``` - //! - //! ### Iterating storage entries - //! - //! Many storage entries are maps of values; as well as fetching individual values, it's possible to - //! iterate over all of the values stored at that location: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a storage query to iterate over account information. - let storage_query = polkadot::storage().system().account_iter(); - - // Get back an iterator of results (here, we are fetching 10 items at - // a time from the node, but we always iterate over one at a time). - let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - - while let Some(Ok(kv)) = results.next().await { - println!("Keys decoded: {:?}", kv.keys); - println!("Key: 0x{}", hex::encode(&kv.key_bytes)); - println!("Value: {:?}", kv.value); - } - - Ok(()) -} -*/ - //! ``` - //! - //! Here's the same logic but using dynamically constructed values instead: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a dynamic storage query to iterate account information. - // With a dynamic query, we can just provide an empty vector as the keys to iterate over all entries. - let keys: Vec = vec![]; - let storage_query = subxt::dynamic::storage("System", "Account", keys); - - // Use that query to return an iterator over the results. - let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - - while let Some(Ok(kv)) = results.next().await { - println!("Keys decoded: {:?}", kv.keys); - println!("Key: 0x{}", hex::encode(&kv.key_bytes)); - println!("Value: {:?}", kv.value.to_value()?); - } - - Ok(()) -} -*/ - //! ``` - //! - //! Here is an example of iterating over partial keys. In this example some multi-signature operations - //! are sent to the node. We can iterate over the pending multisig operations of a single multisig account: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use polkadot::multisig::events::NewMultisig; -use polkadot::runtime_types::{ - frame_system::pallet::Call, rococo_runtime::RuntimeCall, sp_weights::weight_v2::Weight, -}; -use subxt::utils::AccountId32; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::{dev, Keypair}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Prepare the chain to have 3 open multisig requests (2 of them are alice + bob): - let alice_signer = dev::alice(); - let bob = AccountId32(dev::bob().public_key().0); - let charlie = AccountId32(dev::charlie().public_key().0); - - let new_multisig_1 = submit_remark_as_multi(&alice_signer, &bob, b"Hello", &api).await?; - let new_multisig_2 = submit_remark_as_multi(&alice_signer, &bob, b"Hi", &api).await?; - let new_multisig_3 = submit_remark_as_multi(&alice_signer, &charlie, b"Hello", &api).await?; - - // Note: the NewMultisig event contains the multisig address we need to use for the storage queries: - assert_eq!(new_multisig_1.multisig, new_multisig_2.multisig); - assert_ne!(new_multisig_1.multisig, new_multisig_3.multisig); - - // Build a storage query to iterate over open multisig extrinsics from - // new_multisig_1.multisig which is the AccountId of the alice + bob multisig account - let alice_bob_account_id = &new_multisig_1.multisig; - let storage_query = polkadot::storage() - .multisig() - .multisigs_iter1(alice_bob_account_id); - - // Get back an iterator of results. - let mut results = api.storage().at_latest().await?.iter(storage_query).await?; - - while let Some(Ok(kv)) = results.next().await { - println!("Keys decoded: {:?}", kv.keys); - println!("Key: 0x{}", hex::encode(&kv.key_bytes)); - println!("Value: {:?}", kv.value); - } - Ok(()) -} - -async fn submit_remark_as_multi( - signer: &Keypair, - other: &AccountId32, - remark: &[u8], - api: &OnlineClient, -) -> Result> { - let multisig_remark_tx = polkadot::tx().multisig().as_multi( - 2, - vec![other.clone()], - None, - RuntimeCall::System(Call::remark { - remark: remark.to_vec(), - }), - Weight { - ref_time: 0, - proof_size: 0, - }, - ); - let events = api - .tx() - .sign_and_submit_then_watch_default(&multisig_remark_tx, signer) - .await? - .wait_for_finalized_success() - .await?; - let new_multisig = events - .find_first::()? - .expect("should contain event"); - Ok(new_multisig) -} -*/ - //! ``` - //! - //! ### Advanced - //! - //! For more advanced use cases, have a look at [`crate::storage::Storage::fetch_raw`] and - //! [`crate::storage::Storage::fetch_raw_keys`]. Both of these take raw bytes as arguments, which can be - //! obtained from a [`crate::storage::StorageAddress`] by using - //! [`crate::storage::StorageClient::address_bytes()`] or - //! [`crate::storage::StorageClient::address_root_bytes()`]. - //! - } - pub mod transactions { - //! # Transactions - //! - //! A transaction is an extrinsic that's signed (ie it originates from a given address). The purpose - //! of extrinsics is to modify the node storage in a deterministic way, and so being able to submit - //! transactions to a node is one of the core features of Subxt. - //! - //! > Note: the documentation tends to use the terms _extrinsic_ and _transaction_ interchangeably; - //! > An extrinsic is some data that can be added to a block, and is either signed (a _transaction_) - //! > or unsigned (an _inherent_). Subxt can construct either, but overwhelmingly you'll need to - //! > sign the payload you'd like to submit. - //! - //! Submitting a transaction to a node consists of the following steps: - //! - //! 1. [Constructing a transaction payload to submit](#constructing-a-transaction-payload). - //! 2. [Signing it](#signing-it). - //! 3. [Submitting it (optionally with some additional parameters)](#submitting-it). - //! - //! We'll look at each of these steps in turn. - //! - //! ## Constructing a transaction payload - //! - //! We can use the statically generated interface to build transaction payloads: - //! - //! ```rust,no_run - //! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] - //! pub mod polkadot {} - //! - //! let remark = "Hello there".as_bytes().to_vec(); - //! let tx_payload = polkadot::tx().system().remark(remark); - //! ``` - //! - //! > If you're not sure what types to import and use to build a given payload, you can use the - //! > `subxt` CLI tool to generate the interface by using something like `subxt codegen | rustfmt > - //! > interface.rs`, to see what types and things are available (or even just to use directly - //! > instead of the [`#[subxt]`](crate::subxt) macro). - //! - //! Alternately, we can dynamically construct a transaction payload. This will not be type checked or - //! validated until it's submitted: - //! - //! ```rust,no_run - //! use subxt::dynamic::Value; - //! - //! let tx_payload = subxt::dynamic::tx("System", "remark", vec![ - //! Value::from_bytes("Hello there") - //! ]); - //! ``` - //! - //! The [`crate::dynamic::Value`] type is a dynamic type much like a `serde_json::Value` but instead - //! represents any type of data that can be SCALE encoded or decoded. It can be serialized, - //! deserialized and parsed from/to strings. - //! - //! A valid transaction payload is just something that implements the [`crate::tx::TxPayload`] trait; - //! you can implement this trait on your own custom types if the built-in ones are not suitable for - //! your needs. - //! - //! ## Signing it - //! - //! You'll normally need to sign an extrinsic to prove that it originated from an account that you - //! control. To do this, you will typically first create a [`crate::tx::Signer`] instance, which tells - //! Subxt who the extrinsic is from, and takes care of signing the relevant details to prove this. - //! - //! There are two main ways to create a compatible signer instance: - //! 1. The `subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`] - //! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled). - //! 2. Alternately, Subxt can use instances of Substrate's `sp_core::Pair` to sign things by wrapping - //! them in a `crate::tx::PairSigner` (requires the `substrate-compat` feature to be enabled). - //! - //! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via - //! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or - //! need additional signing algorithms that `subxt_signer` doesn't support, and don't care about WASM - //! compatibility. - //! - //! Let's see how to use each of these approaches: - //! - //! ```rust - //! # #[cfg(feature = "substrate-compat")] - //! # { - //! use subxt::config::PolkadotConfig; - //! use std::str::FromStr; - //! - //! //// 1. Use a `subxt_signer` impl: - //! use subxt_signer::{ SecretUri, sr25519 }; - //! - //! // Get hold of a `Signer` for a test account: - //! let alice = sr25519::dev::alice(); - //! - //! // Or generate a keypair, here from an SURI: - //! let uri = SecretUri::from_str("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password") - //! .expect("valid URI"); - //! let keypair = sr25519::Keypair::from_uri(&uri) - //! .expect("valid keypair"); - //! - //! //// 2. Use the corresponding `sp_core::Pair` impl: - //! use subxt::tx::PairSigner; - //! use sp_core::Pair; - //! - //! // Get hold of a `Signer` for a test account: - //! let alice = sp_keyring::AccountKeyring::Alice.pair(); - //! let alice = PairSigner::::new(alice); - //! - //! // Or generate a keypair, here from an SURI: - //! let keypair = sp_core::sr25519::Pair::from_string("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password", None) - //! .expect("valid URI"); - //! let keypair = PairSigner::::new(keypair); - //! # - //! # // Test that these all impl Signer trait while we're here: - //! # - //! # fn is_subxt_signer(_signer: impl subxt::tx::Signer) {} - //! # is_subxt_signer(subxt_signer::sr25519::dev::alice()); - //! # is_subxt_signer(subxt_signer::ecdsa::dev::alice()); - //! # is_subxt_signer(PairSigner::::new(sp_keyring::AccountKeyring::Alice.pair())); - //! # } - //! ``` - //! - //! See the `subxt_signer` crate or the `sp_core::Pair` docs for more ways to construct - //! and work with key pairs. - //! - //! If this isn't suitable/available, you can either implement [`crate::tx::Signer`] yourself to use - //! custom signing logic, or you can use some external signing logic, like so: - //! - //! ```rust,no_run - //! # #[tokio::main] - //! # async fn main() -> Result<(), Box> { - //! use subxt::client::OnlineClient; - //! use subxt::config::PolkadotConfig; - //! use subxt::dynamic::Value; - //! - //! // Create client: - //! let client = OnlineClient::::new().await?; - //! - //! // Create a dummy tx payload to sign: - //! let payload = subxt::dynamic::tx("System", "remark", vec![ - //! Value::from_bytes("Hello there") - //! ]); - //! - //! // Construct the tx but don't sign it. You need to provide the nonce - //! // here, or can use `create_partial_signed` to fetch the correct nonce. - //! let partial_tx = client.tx().create_partial_signed_with_nonce( - //! &payload, - //! 0u64, - //! Default::default() - //! )?; - //! - //! // Fetch the payload that needs to be signed: - //! let signer_payload = partial_tx.signer_payload(); - //! - //! // ... At this point, we can hand off the `signer_payload` to be signed externally. - //! // Ultimately we need to be given back a `signature` (or really, anything - //! // that can be SCALE encoded) and an `address`: - //! let signature; - //! let address; - //! # use subxt::tx::Signer; - //! # let signer = subxt_signer::sr25519::dev::alice(); - //! # signature = signer.sign(&signer_payload).into(); - //! # address = signer.public_key().to_address(); - //! - //! // Now we can build an tx, which one can call `submit` or `submit_and_watch` - //! // on to submit to a node and optionally watch the status. - //! let tx = partial_tx.sign_with_address_and_signature( - //! &address, - //! &signature - //! ); - //! # Ok(()) - //! # } - //! ``` - //! - //! ## Submitting it - //! - //! Once we have signed the transaction, we need to submit it. - //! - //! ### The high level API - //! - //! The highest level approach to doing this is to call - //! [`crate::tx::TxClient::sign_and_submit_then_watch_default`]. This hands back a - //! [`crate::tx::TxProgress`] struct which will monitor the transaction status. We can then call - //! [`crate::tx::TxProgress::wait_for_finalized_success()`] to wait for this transaction to make it - //! into a finalized block, check for an `ExtrinsicSuccess` event, and then hand back the events for - //! inspection. This looks like: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let from = dev::alice(); - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} -*/ - //! ``` - //! - //! ### Providing transaction parameters - //! - //! If you'd like to provide parameters (such as mortality) to the transaction, you can use - //! [`crate::tx::TxClient::sign_and_submit_then_watch`] instead: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::config::polkadot::PolkadotExtrinsicParamsBuilder as Params; -use subxt::{OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - let latest_block = api.blocks().at_latest().await?; - - // Configure the transaction parameters; we give a small tip and set the - // transaction to live for 32 blocks from the `latest_block` above. - let tx_params = Params::new() - .tip(1_000) - .mortal(latest_block.header(), 32) - .build(); - - // submit the transaction: - let from = dev::alice(); - let hash = api.tx().sign_and_submit(&tx, &from, tx_params).await?; - println!("Balance transfer extrinsic submitted with hash : {hash}"); - - Ok(()) -} -*/ - //! ``` - //! - //! This example doesn't wait for the transaction to be included in a block; it just submits it and - //! hopes for the best! - //! - //! ### Custom handling of transaction status updates - //! - //! If you'd like more control or visibility over exactly which status updates are being emitted for - //! the transaction, you can monitor them as they are emitted and react however you choose: - //! - //! ```rust,ignore - /*!#![allow(missing_docs)] -use subxt::{tx::TxStatus, OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -// Generate an interface that we can use from the node's metadata. -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - // Build a balance transfer extrinsic. - let dest = dev::bob().public_key().into(); - let balance_transfer_tx = polkadot::tx().balances().transfer_allow_death(dest, 10_000); - - // Submit the balance transfer extrinsic from Alice, and then monitor the - // progress of it. - let from = dev::alice(); - let mut balance_transfer_progress = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) - .await?; - - while let Some(status) = balance_transfer_progress.next().await { - match status? { - // It's finalized in a block! - TxStatus::InFinalizedBlock(in_block) => { - println!( - "Transaction {:?} is finalized in block {:?}", - in_block.extrinsic_hash(), - in_block.block_hash() - ); - - // grab the events and fail if no ExtrinsicSuccess event seen: - let events = in_block.wait_for_success().await?; - // We can look for events (this uses the static interface; we can also iterate - // over them and dynamically decode them): - let transfer_event = events.find_first::()?; - - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } else { - println!("Failed to find Balances::Transfer Event"); - } - } - // Just log any other status we encounter: - other => { - println!("Status: {other:?}"); - } - } - } - Ok(()) -} -*/ - //! ``` - //! - //! Take a look at the API docs for [`crate::tx::TxProgress`], [`crate::tx::TxStatus`] and - //! [`crate::tx::TxInBlock`] for more options. - //! - } - } -} -pub mod backend { - //! This module exposes a backend trait for Subxt which allows us to get and set - //! the necessary information (probably from a JSON-RPC API, but that's up to the - //! implementation). - pub mod legacy { - //! This module exposes a legacy backend implementation, which relies - //! on the legacy RPC API methods. - pub mod rpc_methods { - //! An interface to call the raw legacy RPC methods. - use crate::backend::rpc::{rpc_params, RpcClient, RpcSubscription}; - use crate::metadata::Metadata; - use crate::{Config, Error}; - use codec::Decode; - use derivative::Derivative; - use primitive_types::U256; - use serde::{Deserialize, Serialize}; - /// An interface to call the legacy RPC methods. This interface is instantiated with - /// some `T: Config` trait which determines some of the types that the RPC methods will - /// take or hand back. - #[derivative(Clone(bound = ""), Debug(bound = ""))] - pub struct LegacyRpcMethods { - client: RpcClient, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for LegacyRpcMethods { - fn clone(&self) -> Self { - match *self { - LegacyRpcMethods { - client: ref __arg_0, - _marker: ref __arg_1, - } => { - LegacyRpcMethods { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for LegacyRpcMethods { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - LegacyRpcMethods { - client: ref __arg_0, - _marker: ref __arg_1, - } => { - let mut __debug_trait_builder = __f - .debug_struct("LegacyRpcMethods"); - let _ = __debug_trait_builder.field("client", &&(*__arg_0)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - impl LegacyRpcMethods { - /// Instantiate the legacy RPC method interface. - pub fn new(client: RpcClient) -> Self { - LegacyRpcMethods { - client, - _marker: std::marker::PhantomData, - } - } - /// Fetch the raw bytes for a given storage key - pub async fn state_get_storage( - &self, - key: &[u8], - hash: Option, - ) -> Result, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(key)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let data: Option = self - .client - .request("state_getStorage", params) - .await?; - Ok(data.map(|b| b.0)) - } - /// Returns the keys with prefix with pagination support. - /// Up to `count` keys will be returned. - /// If `start_key` is passed, return next keys in storage in lexicographic order. - pub async fn state_get_keys_paged( - &self, - key: &[u8], - count: u32, - start_key: Option<&[u8]>, - at: Option, - ) -> Result, Error> { - let start_key = start_key.map(to_hex); - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(key)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(count) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(start_key) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let data: Vec = self - .client - .request("state_getKeysPaged", params) - .await?; - Ok(data.into_iter().map(|b| b.0).collect()) - } - /// Query historical storage entries in the range from the start block to the end block, - /// defaulting the end block to the current best block if it's not given. The first - /// [`StorageChangeSet`] returned has all of the values for each key, and subsequent ones - /// only contain values for any keys which have changed since the last. - pub async fn state_query_storage( - &self, - keys: impl IntoIterator, - from: T::Hash, - to: Option, - ) -> Result>, Error> { - let keys: Vec = keys.into_iter().map(to_hex).collect(); - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(keys) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(from) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(to) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client - .request("state_queryStorage", params) - .await - .map_err(Into::into) - } - /// Query storage entries at some block, using the best block if none is given. - /// This essentially provides a way to ask for a batch of values given a batch of keys, - /// despite the name of the [`StorageChangeSet`] type. - pub async fn state_query_storage_at( - &self, - keys: impl IntoIterator, - at: Option, - ) -> Result>, Error> { - let keys: Vec = keys.into_iter().map(to_hex).collect(); - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(keys) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client - .request("state_queryStorageAt", params) - .await - .map_err(Into::into) - } - /// Fetch the genesis hash - pub async fn genesis_hash(&self) -> Result { - let block_zero = 0u32; - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(block_zero) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let genesis_hash: Option = self - .client - .request("chain_getBlockHash", params) - .await?; - genesis_hash.ok_or_else(|| "Genesis hash not found".into()) - } - /// Fetch the metadata via the legacy `state_getMetadata` RPC method. - pub async fn state_get_metadata( - &self, - at: Option, - ) -> Result { - let bytes: Bytes = self - .client - .request( - "state_getMetadata", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - let metadata = Metadata::decode(&mut &bytes[..])?; - Ok(metadata) - } - /// Fetch system health - pub async fn system_health(&self) -> Result { - self.client - .request( - "system_health", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch system chain - pub async fn system_chain(&self) -> Result { - self.client - .request( - "system_chain", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch system name - pub async fn system_name(&self) -> Result { - self.client - .request( - "system_name", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch system version - pub async fn system_version(&self) -> Result { - self.client - .request( - "system_version", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch system properties - pub async fn system_properties( - &self, - ) -> Result { - self.client - .request( - "system_properties", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Fetch next nonce for an Account - /// - /// Return account nonce adjusted for extrinsics currently in transaction pool - pub async fn system_account_next_index( - &self, - account_id: &T::AccountId, - ) -> Result - where - T::AccountId: Serialize, - { - self.client - .request( - "system_accountNextIndex", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(&account_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await - } - /// Get a header - pub async fn chain_get_header( - &self, - hash: Option, - ) -> Result, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let header = self.client.request("chain_getHeader", params).await?; - Ok(header) - } - /// Get a block hash, returns hash of latest _best_ block by default. - pub async fn chain_get_block_hash( - &self, - block_number: Option, - ) -> Result, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(block_number) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let block_hash = self - .client - .request("chain_getBlockHash", params) - .await?; - Ok(block_hash) - } - /// Get a block hash of the latest finalized block - pub async fn chain_get_finalized_head(&self) -> Result { - let hash = self - .client - .request( - "chain_getFinalizedHead", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await?; - Ok(hash) - } - /// Get a Block - pub async fn chain_get_block( - &self, - hash: Option, - ) -> Result>, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let block = self.client.request("chain_getBlock", params).await?; - Ok(block) - } - /// Reexecute the specified `block_hash` and gather statistics while doing so. - /// - /// This function requires the specified block and its parent to be available - /// at the queried node. If either the specified block or the parent is pruned, - /// this function will return `None`. - pub async fn dev_get_block_stats( - &self, - block_hash: T::Hash, - ) -> Result, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(block_hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let stats = self.client.request("dev_getBlockStats", params).await?; - Ok(stats) - } - /// Get proof of storage entries at a specific block's state. - pub async fn state_get_read_proof( - &self, - keys: impl IntoIterator, - hash: Option, - ) -> Result, Error> { - let keys: Vec = keys.into_iter().map(to_hex).collect(); - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(keys) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let proof = self.client.request("state_getReadProof", params).await?; - Ok(proof) - } - /// Fetch the runtime version - pub async fn state_get_runtime_version( - &self, - at: Option, - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let version = self - .client - .request("state_getRuntimeVersion", params) - .await?; - Ok(version) - } - /// Subscribe to all new best block headers. - pub async fn chain_subscribe_new_heads( - &self, - ) -> Result, Error> { - let subscription = self - .client - .subscribe( - "chain_subscribeNewHeads", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - "chain_unsubscribeNewHeads", - ) - .await?; - Ok(subscription) - } - /// Subscribe to all new block headers. - pub async fn chain_subscribe_all_heads( - &self, - ) -> Result, Error> { - let subscription = self - .client - .subscribe( - "chain_subscribeAllHeads", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - "chain_unsubscribeAllHeads", - ) - .await?; - Ok(subscription) - } - /// Subscribe to finalized block headers. - /// - /// Note: this may not produce _every_ block in the finalized chain; - /// sometimes multiple blocks are finalized at once, and in this case only the - /// latest one is returned. the higher level APIs that use this "fill in" the - /// gaps for us. - pub async fn chain_subscribe_finalized_heads( - &self, - ) -> Result, Error> { - let subscription = self - .client - .subscribe( - "chain_subscribeFinalizedHeads", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - "chain_unsubscribeFinalizedHeads", - ) - .await?; - Ok(subscription) - } - /// Subscribe to runtime version updates that produce changes in the metadata. - /// The first item emitted by the stream is the current runtime version. - pub async fn state_subscribe_runtime_version( - &self, - ) -> Result, Error> { - let subscription = self - .client - .subscribe( - "state_subscribeRuntimeVersion", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - "state_unsubscribeRuntimeVersion", - ) - .await?; - Ok(subscription) - } - /// Create and submit an extrinsic and return corresponding Hash if successful - pub async fn author_submit_extrinsic( - &self, - extrinsic: &[u8], - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(extrinsic)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let xt_hash = self - .client - .request("author_submitExtrinsic", params) - .await?; - Ok(xt_hash) - } - /// Create and submit an extrinsic and return a subscription to the events triggered. - pub async fn author_submit_and_watch_extrinsic( - &self, - extrinsic: &[u8], - ) -> Result>, Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(extrinsic)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let subscription = self - .client - .subscribe( - "author_submitAndWatchExtrinsic", - params, - "author_unwatchExtrinsic", - ) - .await?; - Ok(subscription) - } - /// Insert a key into the keystore. - pub async fn author_insert_key( - &self, - key_type: String, - suri: String, - public: Vec, - ) -> Result<(), Error> { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(key_type) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(suri) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(Bytes(public)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client.request("author_insertKey", params).await?; - Ok(()) - } - /// Generate new session keys and returns the corresponding public keys. - pub async fn author_rotate_keys(&self) -> Result, Error> { - let bytes: Bytes = self - .client - .request( - "author_rotateKeys", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await?; - Ok(bytes.0) - } - /// Checks if the keystore has private keys for the given session public keys. - /// - /// `session_keys` is the SCALE encoded session keys object from the runtime. - /// - /// Returns `true` if all private keys could be found. - pub async fn author_has_session_keys( - &self, - session_keys: Vec, - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(Bytes(session_keys)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client.request("author_hasSessionKeys", params).await - } - /// Checks if the keystore has private keys for the given public key and key type. - /// - /// Returns `true` if a private key could be found. - pub async fn author_has_key( - &self, - public_key: Vec, - key_type: String, - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(Bytes(public_key)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(key_type) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - self.client.request("author_hasKey", params).await - } - /// Execute a runtime API call via `state_call` RPC method. - pub async fn state_call( - &self, - function: &str, - call_parameters: Option<&[u8]>, - at: Option, - ) -> Result, Error> { - let call_parameters = call_parameters.unwrap_or_default(); - let bytes: Bytes = self - .client - .request( - "state_call", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(function) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(to_hex(call_parameters)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(bytes.0) - } - /// Submits the extrinsic to the dry_run RPC, to test if it would succeed. - /// - /// Returns a [`DryRunResult`], which is the result of performing the dry run. - pub async fn dry_run( - &self, - encoded_signed: &[u8], - at: Option, - ) -> Result { - let params = { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(encoded_signed)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(at) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }; - let result_bytes: Bytes = self - .client - .request("system_dryRun", params) - .await?; - Ok(DryRunResultBytes(result_bytes.0)) - } - } - /// Storage key. - pub type StorageKey = Vec; - /// Storage data. - pub type StorageData = Vec; - /// Health struct returned by the RPC - #[serde(rename_all = "camelCase")] - pub struct SystemHealth { - /// Number of connected peers - pub peers: usize, - /// Is the node syncing - pub is_syncing: bool, - /// Should this node have any peers - /// - /// Might be false for local chains or when running without discovery. - pub should_have_peers: bool, - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for SystemHealth { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "peers" => _serde::__private::Ok(__Field::__field0), - "isSyncing" => _serde::__private::Ok(__Field::__field1), - "shouldHavePeers" => { - _serde::__private::Ok(__Field::__field2) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"peers" => _serde::__private::Ok(__Field::__field0), - b"isSyncing" => _serde::__private::Ok(__Field::__field1), - b"shouldHavePeers" => { - _serde::__private::Ok(__Field::__field2) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = SystemHealth; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct SystemHealth", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - usize, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SystemHealth with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - bool, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct SystemHealth with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - bool, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct SystemHealth with 3 elements", - ), - ); - } - }; - _serde::__private::Ok(SystemHealth { - peers: __field0, - is_syncing: __field1, - should_have_peers: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("peers"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "isSyncing", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "shouldHavePeers", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("peers")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("isSyncing")? - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("shouldHavePeers")? - } - }; - _serde::__private::Ok(SystemHealth { - peers: __field0, - is_syncing: __field1, - should_have_peers: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "peers", - "isSyncing", - "shouldHavePeers", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SystemHealth", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for SystemHealth { - #[inline] - fn clone(&self) -> SystemHealth { - SystemHealth { - peers: ::core::clone::Clone::clone(&self.peers), - is_syncing: ::core::clone::Clone::clone(&self.is_syncing), - should_have_peers: ::core::clone::Clone::clone( - &self.should_have_peers, - ), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for SystemHealth { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "SystemHealth", - "peers", - &self.peers, - "is_syncing", - &self.is_syncing, - "should_have_peers", - &&self.should_have_peers, - ) - } - } - /// System properties; an arbitrary JSON object. - pub type SystemProperties = serde_json::Map; - /// A block number - pub type BlockNumber = NumberOrHex; - /// The response from `chain_getBlock` - #[serde(bound = "T: Config")] - pub struct BlockDetails { - /// The block itself. - pub block: Block, - /// Block justification. - pub justifications: Option>, - } - #[automatically_derived] - impl ::core::fmt::Debug for BlockDetails { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "BlockDetails", - "block", - &self.block, - "justifications", - &&self.justifications, - ) - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, T: Config> _serde::Deserialize<'de> for BlockDetails - where - T: Config, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "block" => _serde::__private::Ok(__Field::__field0), - "justifications" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"block" => _serde::__private::Ok(__Field::__field0), - b"justifications" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, T: Config> - where - T: Config, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, T: Config> _serde::de::Visitor<'de> - for __Visitor<'de, T> - where - T: Config, - { - type Value = BlockDetails; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct BlockDetails", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Block, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct BlockDetails with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Option>, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct BlockDetails with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(BlockDetails { - block: __field0, - justifications: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option> = _serde::__private::None; - let mut __field1: _serde::__private::Option< - Option>, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("block"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "justifications", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option>, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("block")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("justifications")? - } - }; - _serde::__private::Ok(BlockDetails { - block: __field0, - justifications: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "block", - "justifications", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "BlockDetails", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Block details in the [`BlockDetails`]. - pub struct Block { - /// The block header. - pub header: T::Header, - /// The accompanying extrinsics. - pub extrinsics: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for Block - where - T::Header: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Block", - "header", - &self.header, - "extrinsics", - &&self.extrinsics, - ) - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, T: Config> _serde::Deserialize<'de> for Block - where - T::Header: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "header" => _serde::__private::Ok(__Field::__field0), - "extrinsics" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"header" => _serde::__private::Ok(__Field::__field0), - b"extrinsics" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, T: Config> - where - T::Header: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, T: Config> _serde::de::Visitor<'de> - for __Visitor<'de, T> - where - T::Header: _serde::Deserialize<'de>, - { - type Value = Block; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct Block", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - T::Header, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Block with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Block with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(Block { - header: __field0, - extrinsics: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option> = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("header"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "extrinsics", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("header")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("extrinsics")? - } - }; - _serde::__private::Ok(Block { - header: __field0, - extrinsics: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "header", - "extrinsics", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Block", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// An abstraction over justification for a block's validity under a consensus algorithm. - pub type BlockJustification = (ConsensusEngineId, EncodedJustification); - /// Consensus engine unique ID. - pub type ConsensusEngineId = [u8; 4]; - /// The encoded justification specific to a consensus engine. - pub type EncodedJustification = Vec; - /// This contains the runtime version information necessary to make transactions, as obtained from - /// the RPC call `state_getRuntimeVersion`, - #[serde(rename_all = "camelCase")] - pub struct RuntimeVersion { - /// Version of the runtime specification. A full-node will not attempt to use its native - /// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, - /// `spec_version` and `authoring_version` are the same between Wasm and native. - pub spec_version: u32, - /// All existing dispatches are fully compatible when this number doesn't change. If this - /// number changes, then `spec_version` must change, also. - /// - /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, - /// either through an alteration in its user-level semantics, a parameter - /// added/removed/changed, a dispatchable being removed, a module being removed, or a - /// dispatchable/module changing its index. - /// - /// It need *not* change when a new module is added or when a dispatchable is added. - pub transaction_version: u32, - /// Fields unnecessary to Subxt are written out to this map. - #[serde(flatten)] - pub other: std::collections::HashMap, - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeVersion { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "RuntimeVersion", - "spec_version", - &self.spec_version, - "transaction_version", - &self.transaction_version, - "other", - &&self.other, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeVersion { - #[inline] - fn clone(&self) -> RuntimeVersion { - RuntimeVersion { - spec_version: ::core::clone::Clone::clone(&self.spec_version), - transaction_version: ::core::clone::Clone::clone( - &self.transaction_version, - ), - other: ::core::clone::Clone::clone(&self.other), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeVersion {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeVersion { - #[inline] - fn eq(&self, other: &RuntimeVersion) -> bool { - self.spec_version == other.spec_version - && self.transaction_version == other.transaction_version - && self.other == other.other - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeVersion { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq< - std::collections::HashMap, - >; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RuntimeVersion { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field<'de> { - __field0, - __field1, - __other(_serde::__private::de::Content<'de>), - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field<'de>; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_bool<__E>( - self, - __value: bool, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::Bool(__value), - ), - ) - } - fn visit_i8<__E>( - self, - __value: i8, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I8(__value), - ), - ) - } - fn visit_i16<__E>( - self, - __value: i16, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I16(__value), - ), - ) - } - fn visit_i32<__E>( - self, - __value: i32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I32(__value), - ), - ) - } - fn visit_i64<__E>( - self, - __value: i64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I64(__value), - ), - ) - } - fn visit_u8<__E>( - self, - __value: u8, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U8(__value), - ), - ) - } - fn visit_u16<__E>( - self, - __value: u16, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U16(__value), - ), - ) - } - fn visit_u32<__E>( - self, - __value: u32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U32(__value), - ), - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U64(__value), - ), - ) - } - fn visit_f32<__E>( - self, - __value: f32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::F32(__value), - ), - ) - } - fn visit_f64<__E>( - self, - __value: f64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::F64(__value), - ), - ) - } - fn visit_char<__E>( - self, - __value: char, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::Char(__value), - ), - ) - } - fn visit_unit<__E>( - self, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other(_serde::__private::de::Content::Unit), - ) - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "specVersion" => _serde::__private::Ok(__Field::__field0), - "transactionVersion" => { - _serde::__private::Ok(__Field::__field1) - } - _ => { - let __value = _serde::__private::de::Content::String( - _serde::__private::ToString::to_string(__value), - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"specVersion" => _serde::__private::Ok(__Field::__field0), - b"transactionVersion" => { - _serde::__private::Ok(__Field::__field1) - } - _ => { - let __value = _serde::__private::de::Content::ByteBuf( - __value.to_vec(), - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_borrowed_str<__E>( - self, - __value: &'de str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "specVersion" => _serde::__private::Ok(__Field::__field0), - "transactionVersion" => { - _serde::__private::Ok(__Field::__field1) - } - _ => { - let __value = _serde::__private::de::Content::Str(__value); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_borrowed_bytes<__E>( - self, - __value: &'de [u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"specVersion" => _serde::__private::Ok(__Field::__field0), - b"transactionVersion" => { - _serde::__private::Ok(__Field::__field1) - } - _ => { - let __value = _serde::__private::de::Content::Bytes( - __value, - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field<'de> { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = RuntimeVersion; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct RuntimeVersion", - ) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __collect = _serde::__private::Vec::< - _serde::__private::Option< - ( - _serde::__private::de::Content, - _serde::__private::de::Content, - ), - >, - >::new(); - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "specVersion", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "transactionVersion", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__other(__name) => { - __collect - .push( - _serde::__private::Some(( - __name, - _serde::de::MapAccess::next_value(&mut __map)?, - )), - ); - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("specVersion")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("transactionVersion")? - } - }; - let __field2: std::collections::HashMap< - String, - serde_json::Value, - > = _serde::de::Deserialize::deserialize( - _serde::__private::de::FlatMapDeserializer( - &mut __collect, - _serde::__private::PhantomData, - ), - )?; - _serde::__private::Ok(RuntimeVersion { - spec_version: __field0, - transaction_version: __field1, - other: __field2, - }) - } - } - _serde::Deserializer::deserialize_map( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Possible transaction status events. - /// - /// # Note - /// - /// This is copied from `sp-transaction-pool` to avoid a dependency on that crate. Therefore it - /// must be kept compatible with that type from the target substrate version. - #[serde(rename_all = "camelCase")] - pub enum TransactionStatus { - /// Transaction is part of the future queue. - Future, - /// Transaction is part of the ready queue. - Ready, - /// The transaction has been broadcast to the given peers. - Broadcast(Vec), - /// Transaction has been included in block with given hash. - InBlock(Hash), - /// The block this transaction was included in has been retracted. - Retracted(Hash), - /// Maximum number of finality watchers has been reached, - /// old watchers are being removed. - FinalityTimeout(Hash), - /// Transaction has been finalized by a finality-gadget, e.g GRANDPA - Finalized(Hash), - /// Transaction has been replaced in the pool, by another transaction - /// that provides the same tags. (e.g. same (sender, nonce)). - Usurped(Hash), - /// Transaction has been dropped from the pool because of the limit. - Dropped, - /// Transaction is no longer valid in the current state. - Invalid, - } - #[automatically_derived] - impl ::core::fmt::Debug - for TransactionStatus { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionStatus::Future => { - ::core::fmt::Formatter::write_str(f, "Future") - } - TransactionStatus::Ready => { - ::core::fmt::Formatter::write_str(f, "Ready") - } - TransactionStatus::Broadcast(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Broadcast", - &__self_0, - ) - } - TransactionStatus::InBlock(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InBlock", - &__self_0, - ) - } - TransactionStatus::Retracted(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Retracted", - &__self_0, - ) - } - TransactionStatus::FinalityTimeout(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "FinalityTimeout", - &__self_0, - ) - } - TransactionStatus::Finalized(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Finalized", - &__self_0, - ) - } - TransactionStatus::Usurped(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Usurped", - &__self_0, - ) - } - TransactionStatus::Dropped => { - ::core::fmt::Formatter::write_str(f, "Dropped") - } - TransactionStatus::Invalid => { - ::core::fmt::Formatter::write_str(f, "Invalid") - } - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for TransactionStatus - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __field6, - __field7, - __field8, - __field9, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - 5u64 => _serde::__private::Ok(__Field::__field5), - 6u64 => _serde::__private::Ok(__Field::__field6), - 7u64 => _serde::__private::Ok(__Field::__field7), - 8u64 => _serde::__private::Ok(__Field::__field8), - 9u64 => _serde::__private::Ok(__Field::__field9), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 10", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "future" => _serde::__private::Ok(__Field::__field0), - "ready" => _serde::__private::Ok(__Field::__field1), - "broadcast" => _serde::__private::Ok(__Field::__field2), - "inBlock" => _serde::__private::Ok(__Field::__field3), - "retracted" => _serde::__private::Ok(__Field::__field4), - "finalityTimeout" => { - _serde::__private::Ok(__Field::__field5) - } - "finalized" => _serde::__private::Ok(__Field::__field6), - "usurped" => _serde::__private::Ok(__Field::__field7), - "dropped" => _serde::__private::Ok(__Field::__field8), - "invalid" => _serde::__private::Ok(__Field::__field9), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"future" => _serde::__private::Ok(__Field::__field0), - b"ready" => _serde::__private::Ok(__Field::__field1), - b"broadcast" => _serde::__private::Ok(__Field::__field2), - b"inBlock" => _serde::__private::Ok(__Field::__field3), - b"retracted" => _serde::__private::Ok(__Field::__field4), - b"finalityTimeout" => { - _serde::__private::Ok(__Field::__field5) - } - b"finalized" => _serde::__private::Ok(__Field::__field6), - b"usurped" => _serde::__private::Ok(__Field::__field7), - b"dropped" => _serde::__private::Ok(__Field::__field8), - b"invalid" => _serde::__private::Ok(__Field::__field9), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "enum TransactionStatus", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(TransactionStatus::Future) - } - (__Field::__field1, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(TransactionStatus::Ready) - } - (__Field::__field2, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Vec, - >(__variant), - TransactionStatus::Broadcast, - ) - } - (__Field::__field3, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::InBlock, - ) - } - (__Field::__field4, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::Retracted, - ) - } - (__Field::__field5, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::FinalityTimeout, - ) - } - (__Field::__field6, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::Finalized, - ) - } - (__Field::__field7, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Hash, - >(__variant), - TransactionStatus::Usurped, - ) - } - (__Field::__field8, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(TransactionStatus::Dropped) - } - (__Field::__field9, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(TransactionStatus::Invalid) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "future", - "ready", - "broadcast", - "inBlock", - "retracted", - "finalityTimeout", - "finalized", - "usurped", - "dropped", - "invalid", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "TransactionStatus", - VARIANTS, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The decoded result returned from calling `system_dryRun` on some extrinsic. - pub enum DryRunResult { - /// The transaction could be included in the block and executed. - Success, - /// The transaction could be included in the block, but the call failed to dispatch. - DispatchError(crate::error::DispatchError), - /// The transaction could not be included in the block. - TransactionValidityError, - } - #[automatically_derived] - impl ::core::fmt::Debug for DryRunResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - DryRunResult::Success => { - ::core::fmt::Formatter::write_str(f, "Success") - } - DryRunResult::DispatchError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "DispatchError", - &__self_0, - ) - } - DryRunResult::TransactionValidityError => { - ::core::fmt::Formatter::write_str( - f, - "TransactionValidityError", - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DryRunResult {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DryRunResult { - #[inline] - fn eq(&self, other: &DryRunResult) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - DryRunResult::DispatchError(__self_0), - DryRunResult::DispatchError(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DryRunResult { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - /// The bytes representing an error dry running an extrinsic. call [`DryRunResultBytes::into_dry_run_result`] - /// to attempt to decode this into something more meaningful. - pub struct DryRunResultBytes(pub Vec); - impl DryRunResultBytes { - /// Attempt to decode the error bytes into a [`DryRunResult`] using the provided [`Metadata`]. - pub fn into_dry_run_result( - self, - metadata: &crate::metadata::Metadata, - ) -> Result { - let bytes = self.0; - if bytes[0] == 0 && bytes[1] == 0 { - Ok(DryRunResult::Success) - } else if bytes[0] == 0 && bytes[1] == 1 { - let dispatch_error = crate::error::DispatchError::decode_from( - &bytes[2..], - metadata.clone(), - )?; - Ok(DryRunResult::DispatchError(dispatch_error)) - } else if bytes[0] == 1 { - Ok(DryRunResult::TransactionValidityError) - } else { - Err(crate::Error::Unknown(bytes)) - } - } - } - /// Storage change set - #[serde(rename_all = "camelCase")] - pub struct StorageChangeSet { - /// Block hash - pub block: Hash, - /// A list of changes; tuples of storage key and optional storage data. - pub changes: Vec<(Bytes, Option)>, - } - #[automatically_derived] - impl ::core::clone::Clone - for StorageChangeSet { - #[inline] - fn clone(&self) -> StorageChangeSet { - StorageChangeSet { - block: ::core::clone::Clone::clone(&self.block), - changes: ::core::clone::Clone::clone(&self.changes), - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for StorageChangeSet - where - Hash: _serde::Serialize, - { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "StorageChangeSet", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "block", - &self.block, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "changes", - &self.changes, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for StorageChangeSet - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "block" => _serde::__private::Ok(__Field::__field0), - "changes" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"block" => _serde::__private::Ok(__Field::__field0), - b"changes" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - StorageChangeSet, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = StorageChangeSet; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct StorageChangeSet", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct StorageChangeSet with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec<(Bytes, Option)>, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct StorageChangeSet with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(StorageChangeSet { - block: __field0, - changes: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - Vec<(Bytes, Option)>, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("block"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "changes", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Vec<(Bytes, Option)>, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("block")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("changes")? - } - }; - _serde::__private::Ok(StorageChangeSet { - block: __field0, - changes: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["block", "changes"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "StorageChangeSet", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - StorageChangeSet, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageChangeSet {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for StorageChangeSet { - #[inline] - fn eq(&self, other: &StorageChangeSet) -> bool { - self.block == other.block && self.changes == other.changes - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageChangeSet { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq)>>; - } - } - #[automatically_derived] - impl ::core::fmt::Debug - for StorageChangeSet { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "StorageChangeSet", - "block", - &self.block, - "changes", - &&self.changes, - ) - } - } - /// Statistics of a block returned by the `dev_getBlockStats` RPC. - #[serde(rename_all = "camelCase")] - pub struct BlockStats { - /// The length in bytes of the storage proof produced by executing the block. - pub witness_len: u64, - /// The length in bytes of the storage proof after compaction. - pub witness_compact_len: u64, - /// Length of the block in bytes. - /// - /// This information can also be acquired by downloading the whole block. This merely - /// saves some complexity on the client side. - pub block_len: u64, - /// Number of extrinsics in the block. - /// - /// This information can also be acquired by downloading the whole block. This merely - /// saves some complexity on the client side. - pub num_extrinsics: u64, - } - #[automatically_derived] - impl ::core::clone::Clone for BlockStats { - #[inline] - fn clone(&self) -> BlockStats { - BlockStats { - witness_len: ::core::clone::Clone::clone(&self.witness_len), - witness_compact_len: ::core::clone::Clone::clone( - &self.witness_compact_len, - ), - block_len: ::core::clone::Clone::clone(&self.block_len), - num_extrinsics: ::core::clone::Clone::clone(&self.num_extrinsics), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for BlockStats { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "BlockStats", - "witness_len", - &self.witness_len, - "witness_compact_len", - &self.witness_compact_len, - "block_len", - &self.block_len, - "num_extrinsics", - &&self.num_extrinsics, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BlockStats {} - #[automatically_derived] - impl ::core::cmp::PartialEq for BlockStats { - #[inline] - fn eq(&self, other: &BlockStats) -> bool { - self.witness_len == other.witness_len - && self.witness_compact_len == other.witness_compact_len - && self.block_len == other.block_len - && self.num_extrinsics == other.num_extrinsics - } - } - #[automatically_derived] - impl ::core::cmp::Eq for BlockStats { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for BlockStats { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "BlockStats", - false as usize + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "witnessLen", - &self.witness_len, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "witnessCompactLen", - &self.witness_compact_len, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "blockLen", - &self.block_len, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "numExtrinsics", - &self.num_extrinsics, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for BlockStats { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "witnessLen" => _serde::__private::Ok(__Field::__field0), - "witnessCompactLen" => { - _serde::__private::Ok(__Field::__field1) - } - "blockLen" => _serde::__private::Ok(__Field::__field2), - "numExtrinsics" => _serde::__private::Ok(__Field::__field3), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"witnessLen" => _serde::__private::Ok(__Field::__field0), - b"witnessCompactLen" => { - _serde::__private::Ok(__Field::__field1) - } - b"blockLen" => _serde::__private::Ok(__Field::__field2), - b"numExtrinsics" => _serde::__private::Ok(__Field::__field3), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = BlockStats; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct BlockStats", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct BlockStats with 4 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct BlockStats with 4 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct BlockStats with 4 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct BlockStats with 4 elements", - ), - ); - } - }; - _serde::__private::Ok(BlockStats { - witness_len: __field0, - witness_compact_len: __field1, - block_len: __field2, - num_extrinsics: __field3, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option = _serde::__private::None; - let mut __field3: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "witnessLen", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "witnessCompactLen", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "blockLen", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private::Option::is_some(&__field3) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "numExtrinsics", - ), - ); - } - __field3 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("witnessLen")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("witnessCompactLen")? - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("blockLen")? - } - }; - let __field3 = match __field3 { - _serde::__private::Some(__field3) => __field3, - _serde::__private::None => { - _serde::__private::de::missing_field("numExtrinsics")? - } - }; - _serde::__private::Ok(BlockStats { - witness_len: __field0, - witness_compact_len: __field1, - block_len: __field2, - num_extrinsics: __field3, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "witnessLen", - "witnessCompactLen", - "blockLen", - "numExtrinsics", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "BlockStats", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// ReadProof struct returned by the RPC - /// - /// # Note - /// - /// This is copied from `sc-rpc-api` to avoid a dependency on that crate. Therefore it - /// must be kept compatible with that type from the target substrate version. - #[serde(rename_all = "camelCase")] - pub struct ReadProof { - /// Block hash used to generate the proof - pub at: Hash, - /// A proof used to prove that storage entries are included in the storage trie - pub proof: Vec, - } - #[automatically_derived] - impl ::core::clone::Clone for ReadProof { - #[inline] - fn clone(&self) -> ReadProof { - ReadProof { - at: ::core::clone::Clone::clone(&self.at), - proof: ::core::clone::Clone::clone(&self.proof), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ReadProof { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "ReadProof", - "at", - &self.at, - "proof", - &&self.proof, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ReadProof {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for ReadProof { - #[inline] - fn eq(&self, other: &ReadProof) -> bool { - self.at == other.at && self.proof == other.proof - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ReadProof { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for ReadProof - where - Hash: _serde::Serialize, - { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "ReadProof", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "at", - &self.at, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "proof", - &self.proof, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for ReadProof - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "at" => _serde::__private::Ok(__Field::__field0), - "proof" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"at" => _serde::__private::Ok(__Field::__field0), - b"proof" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = ReadProof; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct ReadProof", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ReadProof with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct ReadProof with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(ReadProof { - at: __field0, - proof: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option> = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("at"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("proof"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("at")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("proof")? - } - }; - _serde::__private::Ok(ReadProof { - at: __field0, - proof: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["at", "proof"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ReadProof", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// A number type that can be serialized both as a number or a string that encodes a number in a - /// string. - /// - /// We allow two representations of the block number as input. Either we deserialize to the type - /// that is specified in the block type or we attempt to parse given hex value. - /// - /// The primary motivation for having this type is to avoid overflows when using big integers in - /// JavaScript (which we consider as an important RPC API consumer). - #[serde(untagged)] - pub enum NumberOrHex { - /// The number represented directly. - Number(u64), - /// Hex representation of the number. - Hex(U256), - } - #[automatically_derived] - impl ::core::marker::Copy for NumberOrHex {} - #[automatically_derived] - impl ::core::clone::Clone for NumberOrHex { - #[inline] - fn clone(&self) -> NumberOrHex { - let _: ::core::clone::AssertParamIsClone; - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for NumberOrHex { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - NumberOrHex::Number(ref __field0) => { - _serde::Serialize::serialize(__field0, __serializer) - } - NumberOrHex::Hex(ref __field0) => { - _serde::Serialize::serialize(__field0, __serializer) - } - } - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for NumberOrHex { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - let __content = <_serde::__private::de::Content as _serde::Deserialize>::deserialize( - __deserializer, - )?; - let __deserializer = _serde::__private::de::ContentRefDeserializer::< - __D::Error, - >::new(&__content); - if let _serde::__private::Ok(__ok) - = _serde::__private::Result::map( - ::deserialize(__deserializer), - NumberOrHex::Number, - ) { - return _serde::__private::Ok(__ok); - } - if let _serde::__private::Ok(__ok) - = _serde::__private::Result::map( - ::deserialize(__deserializer), - NumberOrHex::Hex, - ) { - return _serde::__private::Ok(__ok); - } - _serde::__private::Err( - _serde::de::Error::custom( - "data did not match any variant of untagged enum NumberOrHex", - ), - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for NumberOrHex { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - NumberOrHex::Number(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Number", - &__self_0, - ) - } - NumberOrHex::Hex(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Hex", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for NumberOrHex {} - #[automatically_derived] - impl ::core::cmp::PartialEq for NumberOrHex { - #[inline] - fn eq(&self, other: &NumberOrHex) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - NumberOrHex::Number(__self_0), - NumberOrHex::Number(__arg1_0), - ) => *__self_0 == *__arg1_0, - (NumberOrHex::Hex(__self_0), NumberOrHex::Hex(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for NumberOrHex { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - impl NumberOrHex { - /// Converts this number into an U256. - pub fn into_u256(self) -> U256 { - match self { - NumberOrHex::Number(n) => n.into(), - NumberOrHex::Hex(h) => h, - } - } - } - impl From for U256 { - fn from(num_or_hex: NumberOrHex) -> U256 { - num_or_hex.into_u256() - } - } - impl From for NumberOrHex { - fn from(x: u8) -> Self { - NumberOrHex::Number(x.into()) - } - } - impl From for NumberOrHex { - fn from(x: u16) -> Self { - NumberOrHex::Number(x.into()) - } - } - impl From for NumberOrHex { - fn from(x: u32) -> Self { - NumberOrHex::Number(x.into()) - } - } - impl From for NumberOrHex { - fn from(x: u64) -> Self { - NumberOrHex::Number(x.into()) - } - } - impl From for NumberOrHex { - fn from(n: u128) -> Self { - NumberOrHex::Hex(n.into()) - } - } - impl From for NumberOrHex { - fn from(n: U256) -> Self { - NumberOrHex::Hex(n) - } - } - /// A quick helper to encode some bytes to hex. - fn to_hex(bytes: impl AsRef<[u8]>) -> String { - { - let res = ::alloc::fmt::format( - format_args!("0x{0}", hex::encode(bytes.as_ref())), - ); - res - } - } - /// Hex-serialized shim for `Vec`. - pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec); - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Bytes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Bytes { - #[inline] - fn eq(&self, other: &Bytes) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Bytes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Bytes { - #[inline] - fn clone(&self) -> Bytes { - Bytes(::core::clone::Clone::clone(&self.0)) - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Bytes { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "Bytes", - { - #[doc(hidden)] - struct __SerializeWith<'__a> { - values: (&'__a Vec,), - phantom: _serde::__private::PhantomData, - } - impl<'__a> _serde::Serialize for __SerializeWith<'__a> { - fn serialize<__S>( - &self, - __s: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - impl_serde::serialize::serialize(self.values.0, __s) - } - } - &__SerializeWith { - values: (&self.0,), - phantom: _serde::__private::PhantomData::, - } - }, - ) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Bytes { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Bytes; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "tuple struct Bytes", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: Vec = impl_serde::serialize::deserialize( - __e, - )?; - _serde::__private::Ok(Bytes(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match { - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: Vec, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: impl_serde::serialize::deserialize(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct Bytes with 1 element", - ), - ); - } - }; - _serde::__private::Ok(Bytes(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "Bytes", - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::hash::Hash for Bytes { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Bytes { - #[inline] - fn partial_cmp( - &self, - other: &Bytes, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Bytes { - #[inline] - fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Bytes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Bytes", - &&self.0, - ) - } - } - impl std::ops::Deref for Bytes { - type Target = [u8]; - fn deref(&self) -> &[u8] { - &self.0[..] - } - } - impl From> for Bytes { - fn from(s: Vec) -> Self { - Bytes(s) - } - } - } - use self::rpc_methods::TransactionStatus as RpcTransactionStatus; - use crate::backend::{ - rpc::RpcClient, Backend, BlockRef, RuntimeVersion, StorageResponse, StreamOf, - StreamOfResults, TransactionStatus, - }; - use crate::{config::Header, Config, Error}; - use async_trait::async_trait; - use futures::{ - future, future::Either, stream, Future, FutureExt, Stream, StreamExt, - }; - use std::collections::VecDeque; - use std::pin::Pin; - use std::task::{Context, Poll}; - pub use rpc_methods::LegacyRpcMethods; - /// The legacy backend. - pub struct LegacyBackend { - methods: LegacyRpcMethods, - } - #[automatically_derived] - impl ::core::fmt::Debug for LegacyBackend { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "LegacyBackend", - "methods", - &&self.methods, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for LegacyBackend { - #[inline] - fn clone(&self) -> LegacyBackend { - LegacyBackend { - methods: ::core::clone::Clone::clone(&self.methods), - } - } - } - impl LegacyBackend { - /// Instantiate a new backend which uses the legacy API methods. - pub fn new(client: RpcClient) -> Self { - Self { - methods: LegacyRpcMethods::new(client), - } - } - } - impl super::sealed::Sealed for LegacyBackend {} - impl Backend for LegacyBackend { - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_values<'life0, 'async_trait>( - &'life0 self, - keys: Vec>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let keys = keys; - let at = at; - let __ret: Result, Error> = { - let methods = __self.methods.clone(); - let iter = keys - .into_iter() - .map(move |key| { - let methods = methods.clone(); - async move { - let res = methods.state_get_storage(&key, Some(at)).await?; - Ok(res.map(|value| StorageResponse { key, value })) - } - }); - let s = stream::iter(iter) - .then(|fut| fut) - .filter_map(|r| future::ready(r.transpose())); - Ok(StreamOf(Box::pin(s))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_descendant_keys<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>, Error>, - > { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result>, Error> = { - let keys = StorageFetchDescendantKeysStream { - at, - key, - methods: __self.methods.clone(), - done: Default::default(), - keys_fut: Default::default(), - pagination_start_key: None, - }; - let keys = keys - .flat_map(|keys| { - match keys { - Err(e) => { - Either::Left(stream::iter(std::iter::once(Err(e)))) - } - Ok(keys) => { - Either::Right(stream::iter(keys.into_iter().map(Ok))) - } - } - }); - Ok(StreamOf(Box::pin(keys))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_descendant_values<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result, Error> = { - let keys_stream = StorageFetchDescendantKeysStream { - at, - key, - methods: __self.methods.clone(), - done: Default::default(), - keys_fut: Default::default(), - pagination_start_key: None, - }; - Ok( - StreamOf( - Box::pin(StorageFetchDescendantValuesStream { - keys: keys_stream, - results_fut: None, - results: Default::default(), - }), - ), - ) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn genesis_hash<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let __ret: Result = { - __self.methods.genesis_hash().await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn block_header<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result, Error> = { - __self.methods.chain_get_header(Some(at)).await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn block_body<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>>, Error>, - > { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result>>, Error> = { - let Some(details) = __self - .methods - .chain_get_block(Some(at)) - .await? else { return Ok(None); - }; - Ok( - Some( - details.block.extrinsics.into_iter().map(|b| b.0).collect(), - ), - ) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn latest_finalized_block_ref<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result, Error> = { - let hash = __self.methods.chain_get_finalized_head().await?; - Ok(BlockRef::from_hash(hash)) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn current_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let __ret: Result = { - let details = __self - .methods - .state_get_runtime_version(None) - .await?; - Ok(RuntimeVersion { - spec_version: details.spec_version, - transaction_version: details.transaction_version, - }) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result, Error> = { - let sub = __self - .methods - .state_subscribe_runtime_version() - .await?; - let sub = sub - .map(|r| { - r.map(|v| RuntimeVersion { - spec_version: v.spec_version, - transaction_version: v.transaction_version, - }) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_all_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - let sub = __self.methods.chain_subscribe_all_heads().await?; - let sub = sub - .map(|r| { - r.map(|h| { - let hash = h.hash(); - (h, BlockRef::from_hash(hash)) - }) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_best_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - let sub = __self.methods.chain_subscribe_new_heads().await?; - let sub = sub - .map(|r| { - r.map(|h| { - let hash = h.hash(); - (h, BlockRef::from_hash(hash)) - }) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_finalized_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - let sub: super::rpc::RpcSubscription<::Header> = __self - .methods - .chain_subscribe_finalized_heads() - .await?; - let last_finalized_block_ref = __self - .latest_finalized_block_ref() - .await?; - let last_finalized_block_num = __self - .block_header(last_finalized_block_ref.hash()) - .await? - .map(|h| h.number().into()); - let sub = subscribe_to_block_headers_filling_in_gaps( - __self.methods.clone(), - sub, - last_finalized_block_num, - ); - let sub = sub - .map(|r| { - r.map(|h| { - let hash = h.hash(); - (h, BlockRef::from_hash(hash)) - }) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn submit_transaction<'life0, 'life1, 'async_trait>( - &'life0 self, - extrinsic: &'life1 [u8], - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults>, - Error, - > = { - let sub = __self - .methods - .author_submit_and_watch_extrinsic(extrinsic) - .await?; - let sub = sub - .filter_map(|r| { - let mapped = r - .map(|tx| { - match tx { - RpcTransactionStatus::Future => None, - RpcTransactionStatus::Retracted(_) => None, - RpcTransactionStatus::Ready => { - Some(TransactionStatus::Validated) - } - RpcTransactionStatus::Broadcast(peers) => { - Some(TransactionStatus::Broadcasted { - num_peers: peers.len() as u32, - }) - } - RpcTransactionStatus::InBlock(hash) => { - Some(TransactionStatus::InBestBlock { - hash: BlockRef::from_hash(hash), - }) - } - RpcTransactionStatus::FinalityTimeout(_) => { - Some(TransactionStatus::Invalid { - message: "Finality timeout".into(), - }) - } - RpcTransactionStatus::Finalized(hash) => { - Some(TransactionStatus::InFinalizedBlock { - hash: BlockRef::from_hash(hash), - }) - } - RpcTransactionStatus::Usurped(_) => { - Some(TransactionStatus::Invalid { - message: "Transaction was usurped by another with the same nonce" - .into(), - }) - } - RpcTransactionStatus::Dropped => { - Some(TransactionStatus::Dropped { - message: "Transaction was dropped".into(), - }) - } - RpcTransactionStatus::Invalid => { - Some(TransactionStatus::Invalid { - message: "Transaction is invalid (eg because of a bad nonce, signature etc)" - .into(), - }) - } - } - }) - .transpose(); - future::ready(mapped) - }); - Ok(StreamOf(Box::pin(sub))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn call<'life0, 'life1, 'life2, 'async_trait>( - &'life0 self, - method: &'life1 str, - call_parameters: Option<&'life2 [u8]>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - 'life2: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::, Error>> { - return __ret; - } - let __self = self; - let call_parameters = call_parameters; - let at = at; - let __ret: Result, Error> = { - __self - .methods - .state_call(method, call_parameters, Some(at)) - .await - }; - #[allow(unreachable_code)] __ret - }) - } - } - /// Note: This is exposed for testing but is not considered stable and may change - /// without notice in a patch release. - #[doc(hidden)] - pub fn subscribe_to_block_headers_filling_in_gaps( - methods: LegacyRpcMethods, - sub: S, - mut last_block_num: Option, - ) -> impl Stream> + Send - where - T: Config, - S: Stream> + Send, - E: Into + Send + 'static, - { - sub.flat_map(move |s| { - let header = match s { - Ok(header) => header, - Err(e) => return Either::Left(stream::once(async { Err(e.into()) })), - }; - let end_block_num = header.number().into(); - let start_block_num = last_block_num - .map(|n| n + 1) - .unwrap_or(end_block_num); - let methods = methods.clone(); - let previous_headers = stream::iter(start_block_num..end_block_num) - .then(move |n| { - let methods = methods.clone(); - async move { - let hash = methods - .chain_get_block_hash(Some(n.into())) - .await?; - let header = methods.chain_get_header(hash).await?; - Ok::<_, Error>(header) - } - }) - .filter_map(|h| async { h.transpose() }); - last_block_num = Some(end_block_num); - Either::Right(previous_headers.chain(stream::once(async { Ok(header) }))) - }) - } - /// How many keys/values to fetch at once. - const STORAGE_PAGE_SIZE: u32 = 32; - /// This provides a stream of values given some prefix `key`. It - /// internally manages pagination and such. - #[allow(clippy::type_complexity)] - pub struct StorageFetchDescendantKeysStream { - methods: LegacyRpcMethods, - key: Vec, - at: T::Hash, - pagination_start_key: Option>, - keys_fut: Option< - Pin< - Box< - dyn Future>, Error>> + Send + 'static, - >, - >, - >, - done: bool, - } - impl std::marker::Unpin for StorageFetchDescendantKeysStream {} - impl Stream for StorageFetchDescendantKeysStream { - type Item = Result>, Error>; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - let mut this = self.as_mut(); - loop { - if this.done { - return Poll::Ready(None); - } - if let Some(mut keys_fut) = this.keys_fut.take() { - let Poll::Ready(keys) = keys_fut.poll_unpin(cx) else { - this.keys_fut = Some(keys_fut); - return Poll::Pending; - }; - match keys { - Ok(keys) => { - if keys.is_empty() { - this.done = true; - return Poll::Ready(None); - } - this.pagination_start_key = keys.last().cloned(); - return Poll::Ready(Some(Ok(keys))); - } - Err(e) => { - return Poll::Ready(Some(Err(e))); - } - } - } - let methods = this.methods.clone(); - let key = this.key.clone(); - let at = this.at; - let pagination_start_key = this.pagination_start_key.take(); - let keys_fut = async move { - methods - .state_get_keys_paged( - &key, - STORAGE_PAGE_SIZE, - pagination_start_key.as_deref(), - Some(at), - ) - .await - }; - this.keys_fut = Some(Box::pin(keys_fut)); - } - } - } - /// This provides a stream of values given some stream of keys. - #[allow(clippy::type_complexity)] - pub struct StorageFetchDescendantValuesStream { - keys: StorageFetchDescendantKeysStream, - results_fut: Option< - Pin< - Box< - dyn Future< - Output = Result, Vec)>>, Error>, - > + Send + 'static, - >, - >, - >, - results: VecDeque<(Vec, Vec)>, - } - impl Stream for StorageFetchDescendantValuesStream { - type Item = Result; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - let mut this = self.as_mut(); - loop { - if let Some((key, value)) = this.results.pop_front() { - let res = StorageResponse { key, value }; - return Poll::Ready(Some(Ok(res))); - } - if let Some(mut results_fut) = this.results_fut.take() { - match results_fut.poll_unpin(cx) { - Poll::Ready(Ok(Some(results))) => { - this.results = results; - continue; - } - Poll::Ready(Ok(None)) => { - continue; - } - Poll::Ready(Err(e)) => return Poll::Ready(Some(Err(e))), - Poll::Pending => { - this.results_fut = Some(results_fut); - return Poll::Pending; - } - } - } - match this.keys.poll_next_unpin(cx) { - Poll::Ready(Some(Ok(keys))) => { - let methods = this.keys.methods.clone(); - let at = this.keys.at; - let results_fut = async move { - let keys = keys.iter().map(|k| &**k); - let values = methods - .state_query_storage_at(keys, Some(at)) - .await?; - let values: VecDeque<_> = values - .into_iter() - .flat_map(|v| { - v.changes - .into_iter() - .filter_map(|(k, v)| { - let v = v?; - Some((k.0, v.0)) - }) - }) - .collect(); - Ok(Some(values)) - }; - this.results_fut = Some(Box::pin(results_fut)); - continue; - } - Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(e))), - Poll::Ready(None) => return Poll::Ready(None), - Poll::Pending => return Poll::Pending, - } - } - } - } - } - pub mod rpc { - //! RPC types and client for interacting with a substrate node. - //! - //! These are used behind the scenes by Subxt backend implementations, for - //! example [`crate::backend::legacy::LegacyBackend`]. If you need an RPC client, - //! then you can manually instantiate one, and then hand it to Subxt if you'd like - //! to re-use it for the Subxt connection. - //! - //! - [`RpcClientT`] is the underlying dynamic RPC implementation. This provides - //! the low level [`RpcClientT::request_raw`] and [`RpcClientT::subscribe_raw`] - //! methods. - //! - [`RpcClient`] is the higher level wrapper around this, offering - //! the [`RpcClient::request`] and [`RpcClient::subscribe`] methods. - //! - //! # Example - //! - //! Fetching the genesis hash. - //! - //! ```no_run - //! # #[tokio::main] - //! # async fn main() { - //! use subxt::{ - //! client::OnlineClient, - //! config::SubstrateConfig, - //! backend::rpc::RpcClient, - //! backend::legacy::LegacyRpcMethods, - //! }; - //! - //! // Instantiate a default RPC client pointing at some URL. - //! let rpc_client = RpcClient::from_url("ws://localhost:9944") - //! .await - //! .unwrap(); - //! - //! // Instantiate the legacy RPC interface, providing an appropriate - //! // config so that it uses the correct types for your chain. - //! let rpc_methods = LegacyRpcMethods::::new(rpc_client.clone()); - //! - //! // Use it to make RPC calls, here using the legacy genesis_hash method. - //! let genesis_hash = rpc_methods - //! .genesis_hash() - //! .await - //! .unwrap(); - //! - //! println!("{genesis_hash}"); - //! - //! // Instantiate the Subxt interface using the same client and config if you - //! // want to reuse the same connection: - //! let client = OnlineClient::::from_rpc_client(rpc_client); - //! # } - //! ``` - #![allow(clippy::module_inception)] - #[cfg(feature = "jsonrpsee")] - mod jsonrpsee_impl { - use super::{RawRpcFuture, RawRpcSubscription, RpcClientT}; - use crate::error::RpcError; - use futures::stream::{StreamExt, TryStreamExt}; - use jsonrpsee::{ - core::{ - client::{Client, ClientT, SubscriptionClientT, SubscriptionKind}, - traits::ToRpcParams, - }, - types::SubscriptionId, - }; - use serde_json::value::RawValue; - struct Params(Option>); - impl ToRpcParams for Params { - fn to_rpc_params( - self, - ) -> Result>, serde_json::Error> { - Ok(self.0) - } - } - impl RpcClientT for Client { - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box> { - Box::pin(async move { - let res = ClientT::request(self, method, Params(params)) - .await - .map_err(|e| RpcError::ClientError(Box::new(e)))?; - Ok(res) - }) - } - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription> { - Box::pin(async move { - let stream = SubscriptionClientT::subscribe::< - Box, - _, - >(self, sub, Params(params), unsub) - .await - .map_err(|e| RpcError::ClientError(Box::new(e)))?; - let id = match stream.kind() { - SubscriptionKind::Subscription(SubscriptionId::Str(id)) => { - Some(id.clone().into_owned()) - } - _ => None, - }; - let stream = stream - .map_err(|e| RpcError::ClientError(Box::new(e))) - .boxed(); - Ok(RawRpcSubscription { stream, id }) - }) - } - } - } - mod rpc_client { - use super::{RawRpcSubscription, RpcClientT}; - use crate::error::Error; - use futures::{Stream, StreamExt}; - use serde::{de::DeserializeOwned, Serialize}; - use serde_json::value::RawValue; - use std::{pin::Pin, sync::Arc, task::Poll}; - /// A concrete wrapper around an [`RpcClientT`] which provides some higher level helper methods, - /// is cheaply cloneable, and can be handed to things like [`crate::client::OnlineClient`] to - /// instantiate it. - pub struct RpcClient { - client: Arc, - } - #[automatically_derived] - impl ::core::clone::Clone for RpcClient { - #[inline] - fn clone(&self) -> RpcClient { - RpcClient { - client: ::core::clone::Clone::clone(&self.client), - } - } - } - impl RpcClient { - #[cfg(feature = "jsonrpsee")] - /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. - /// - /// Errors if an insecure URL is provided. In this case, use [`RpcClient::from_insecure_url`] instead. - pub async fn from_url>(url: U) -> Result { - crate::utils::validate_url_is_secure(url.as_ref())?; - RpcClient::from_insecure_url(url).await - } - #[cfg(feature = "jsonrpsee")] - /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. - /// - /// Allows insecure URLs without SSL encryption, e.g. (http:// and ws:// URLs). - pub async fn from_insecure_url>( - url: U, - ) -> Result { - let client = jsonrpsee_helpers::client(url.as_ref()) - .await - .map_err(|e| crate::error::RpcError::ClientError(Box::new(e)))?; - Ok(Self::new(client)) - } - /// Create a new [`RpcClient`] from an arbitrary [`RpcClientT`] implementation. - pub fn new(client: R) -> Self { - RpcClient { - client: Arc::new(client), - } - } - /// Make an RPC request, given a method name and some parameters. - /// - /// See [`RpcParams`] and the [`rpc_params!`] macro for an example of how to - /// construct the parameters. - pub async fn request( - &self, - method: &str, - params: RpcParams, - ) -> Result { - let res = self.client.request_raw(method, params.build()).await?; - let val = serde_json::from_str(res.get())?; - Ok(val) - } - /// Subscribe to an RPC endpoint, providing the parameters and the method to call to - /// unsubscribe from it again. - /// - /// See [`RpcParams`] and the [`rpc_params!`] macro for an example of how to - /// construct the parameters. - pub async fn subscribe( - &self, - sub: &str, - params: RpcParams, - unsub: &str, - ) -> Result, Error> { - let sub = self - .client - .subscribe_raw(sub, params.build(), unsub) - .await?; - Ok(RpcSubscription::new(sub)) - } - } - impl std::fmt::Debug for RpcClient { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("RpcClient").finish() - } - } - impl std::ops::Deref for RpcClient { - type Target = dyn RpcClientT; - fn deref(&self) -> &Self::Target { - &*self.client - } - } - pub use rpc_params; - /// This represents the parameters passed to an [`RpcClient`], and exists to - /// enforce that parameters are provided in the correct format. - /// - /// Prefer to use the [`rpc_params!`] macro for simpler creation of these. - /// - /// # Example - /// - /// ```rust - /// use subxt::backend::rpc::RpcParams; - /// - /// let mut params = RpcParams::new(); - /// params.push(1).unwrap(); - /// params.push(true).unwrap(); - /// params.push("foo").unwrap(); - /// - /// assert_eq!(params.build().unwrap().get(), "[1,true,\"foo\"]"); - /// ``` - pub struct RpcParams(Vec); - #[automatically_derived] - impl ::core::fmt::Debug for RpcParams { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "RpcParams", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RpcParams { - #[inline] - fn clone(&self) -> RpcParams { - RpcParams(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::default::Default for RpcParams { - #[inline] - fn default() -> RpcParams { - RpcParams(::core::default::Default::default()) - } - } - impl RpcParams { - /// Create a new empty set of [`RpcParams`]. - pub fn new() -> Self { - Self(Vec::new()) - } - /// Push a parameter into our [`RpcParams`]. This serializes it to JSON - /// in the process, and so will return an error if this is not possible. - pub fn push(&mut self, param: P) -> Result<(), Error> { - if self.0.is_empty() { - self.0.push(b'['); - } else { - self.0.push(b',') - } - serde_json::to_writer(&mut self.0, ¶m)?; - Ok(()) - } - /// Build a [`RawValue`] from our params, returning `None` if no parameters - /// were provided. - pub fn build(mut self) -> Option> { - if self.0.is_empty() { - None - } else { - self.0.push(b']'); - let s = unsafe { String::from_utf8_unchecked(self.0) }; - Some(RawValue::from_string(s).expect("Should be valid JSON")) - } - } - } - /// A generic RPC Subscription. This implements [`Stream`], and so most of - /// the functionality you'll need to interact with it comes from the - /// [`StreamExt`] extension trait. - pub struct RpcSubscription { - inner: RawRpcSubscription, - _marker: std::marker::PhantomData, - } - impl std::fmt::Debug for RpcSubscription { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("RpcSubscription") - .field("inner", &"RawRpcSubscription") - .field("_marker", &self._marker) - .finish() - } - } - impl RpcSubscription { - /// Creates a new [`RpcSubscription`]. - pub fn new(inner: RawRpcSubscription) -> Self { - Self { - inner, - _marker: std::marker::PhantomData, - } - } - /// Obtain the ID associated with this subscription. - pub fn subscription_id(&self) -> Option<&str> { - self.inner.id.as_deref() - } - } - impl RpcSubscription { - /// Returns the next item in the stream. This is just a wrapper around - /// [`StreamExt::next()`] so that you can avoid the extra import. - pub async fn next(&mut self) -> Option> { - StreamExt::next(self).await - } - } - impl std::marker::Unpin for RpcSubscription {} - impl Stream for RpcSubscription { - type Item = Result; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> Poll> { - let res = match self.inner.stream.poll_next_unpin(cx) { - ::futures_core::task::Poll::Ready(t) => t, - ::futures_core::task::Poll::Pending => { - return ::futures_core::task::Poll::Pending; - } - }; - let res = res - .map(|r| { - r.map_err(|e| e.into()) - .and_then(|raw_val| { - serde_json::from_str(raw_val.get()).map_err(|e| e.into()) - }) - }); - Poll::Ready(res) - } - } - #[cfg(all(feature = "jsonrpsee", feature = "native"))] - mod jsonrpsee_helpers { - pub use jsonrpsee::{ - client_transport::ws::{ - self, EitherStream, Url, WsTransportClientBuilder, - }, - core::client::{Client, Error}, - }; - use tokio_util::compat::Compat; - pub type Sender = ws::Sender>; - pub type Receiver = ws::Receiver>; - /// Build WS RPC client from URL - pub async fn client(url: &str) -> Result { - let (sender, receiver) = ws_transport(url).await?; - Ok( - Client::builder() - .max_buffer_capacity_per_subscription(4096) - .build_with_tokio(sender, receiver), - ) - } - async fn ws_transport(url: &str) -> Result<(Sender, Receiver), Error> { - let url = Url::parse(url).map_err(|e| Error::Transport(e.into()))?; - WsTransportClientBuilder::default() - .build(url) - .await - .map_err(|e| Error::Transport(e.into())) - } - } - } - mod rpc_client_t { - use crate::error::RpcError; - use futures::Stream; - use std::{future::Future, pin::Pin}; - pub use serde_json::value::RawValue; - /// A trait describing low level JSON-RPC interactions. Implementations of this can be - /// used to instantiate a [`super::RpcClient`], which can be passed to [`crate::OnlineClient`] - /// or used for lower level RPC calls via eg [`crate::backend::legacy::LegacyRpcMethods`]. - /// - /// This is a low level interface whose methods expect an already-serialized set of params, - /// and return an owned but still-serialized [`RawValue`], deferring deserialization to - /// the caller. This is the case because we want the methods to be object-safe (which prohibits - /// generics), and want to avoid any unnecessary allocations in serializing/deserializing - /// parameters. - /// - /// # Panics - /// - /// Implementations are free to panic if the `RawValue`'s passed to `request_raw` or - /// `subscribe_raw` are not JSON arrays. Internally, we ensure that this is always the case. - pub trait RpcClientT: Send + Sync + 'static { - /// Make a raw request for which we expect a single response back from. Implementations - /// should expect that the params will either be `None`, or be an already-serialized - /// JSON array of parameters. - /// - /// See [`super::RpcParams`] and the [`super::rpc_params!`] macro for an example of how to - /// construct the parameters. - /// - /// Prefer to use the interface provided on [`super::RpcClient`] where possible. - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box>; - /// Subscribe to some method. Implementations should expect that the params will - /// either be `None`, or be an already-serialized JSON array of parameters. - /// - /// See [`super::RpcParams`] and the [`super::rpc_params!`] macro for an example of how to - /// construct the parameters. - /// - /// Prefer to use the interface provided on [`super::RpcClient`] where possible. - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription>; - } - /// A boxed future that is returned from the [`RpcClientT`] methods. - pub type RawRpcFuture<'a, T> = Pin< - Box> + Send + 'a>, - >; - /// The RPC subscription returned from [`RpcClientT`]'s `subscription` method. - pub struct RawRpcSubscription { - /// The subscription stream. - pub stream: Pin< - Box< - dyn Stream< - Item = Result, RpcError>, - > + Send + 'static, - >, - >, - /// The ID associated with the subscription. - pub id: Option, - } - impl RpcClientT for std::sync::Arc { - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box> { - (**self).request_raw(method, params) - } - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription> { - (**self).subscribe_raw(sub, params, unsub) - } - } - impl RpcClientT for Box { - fn request_raw<'a>( - &'a self, - method: &'a str, - params: Option>, - ) -> RawRpcFuture<'a, Box> { - (**self).request_raw(method, params) - } - fn subscribe_raw<'a>( - &'a self, - sub: &'a str, - params: Option>, - unsub: &'a str, - ) -> RawRpcFuture<'a, RawRpcSubscription> { - (**self).subscribe_raw(sub, params, unsub) - } - } - } - pub use rpc_client::{rpc_params, RpcClient, RpcParams, RpcSubscription}; - pub use rpc_client_t::{RawRpcFuture, RawRpcSubscription, RawValue, RpcClientT}; - } - pub mod unstable { - //! This module will expose a backend implementation based on the new APIs - //! described at . See - //! [`rpc_methods`] for the raw API calls. - //! - //! # Warning - //! - //! Everything in this module is **unstable**, meaning that it could change without - //! warning at any time. - mod follow_stream { - use super::rpc_methods::{FollowEvent, UnstableRpcMethods}; - use crate::config::Config; - use crate::error::Error; - use futures::{FutureExt, Stream, StreamExt}; - use std::future::Future; - use std::pin::Pin; - use std::task::{Context, Poll}; - /// A `Stream` whose goal is to remain subscribed to `chainHead_follow`. It will re-subscribe if the subscription - /// is ended for any reason, and it will return the current `subscription_id` as an event, along with the other - /// follow events. - pub struct FollowStream { - stream_getter: FollowEventStreamGetter, - stream: InnerStreamState, - } - impl std::fmt::Debug for FollowStream { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("FollowStream") - .field("stream_getter", &"..") - .field("stream", &self.stream) - .finish() - } - } - /// A getter function that returns an [`FollowEventStreamFut`]. - pub type FollowEventStreamGetter = Box< - dyn FnMut() -> FollowEventStreamFut + Send, - >; - /// The future which will return a stream of follow events and the subscription ID for it. - pub type FollowEventStreamFut = Pin< - Box< - dyn Future< - Output = Result<(FollowEventStream, String), Error>, - > + Send + 'static, - >, - >; - /// The stream of follow events. - pub type FollowEventStream = Pin< - Box, Error>> + Send + 'static>, - >; - /// Either a ready message with the current subscription ID, or - /// an event from the stream itself. - pub enum FollowStreamMsg { - /// The stream is ready (and has a subscription ID) - Ready(String), - /// An event from the stream. - Event(FollowEvent), - } - #[automatically_derived] - impl ::core::fmt::Debug for FollowStreamMsg { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - FollowStreamMsg::Ready(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Ready", - &__self_0, - ) - } - FollowStreamMsg::Event(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Event", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone - for FollowStreamMsg { - #[inline] - fn clone(&self) -> FollowStreamMsg { - match self { - FollowStreamMsg::Ready(__self_0) => { - FollowStreamMsg::Ready(::core::clone::Clone::clone(__self_0)) - } - FollowStreamMsg::Event(__self_0) => { - FollowStreamMsg::Event(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for FollowStreamMsg {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for FollowStreamMsg { - #[inline] - fn eq(&self, other: &FollowStreamMsg) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - FollowStreamMsg::Ready(__self_0), - FollowStreamMsg::Ready(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowStreamMsg::Event(__self_0), - FollowStreamMsg::Event(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for FollowStreamMsg { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - impl FollowStreamMsg { - /// Return an event, or none if the message is a "ready" one. - pub fn into_event(self) -> Option> { - match self { - FollowStreamMsg::Ready(_) => None, - FollowStreamMsg::Event(e) => Some(e), - } - } - } - enum InnerStreamState { - /// We've just created the stream; we'll start Initializing it - New, - /// We're fetching the inner subscription. Move to Ready when we have one. - Initializing(FollowEventStreamFut), - /// Report back the subscription ID here, and then start ReceivingEvents. - Ready(Option<(FollowEventStream, String)>), - /// We are polling for, and receiving events from the stream. - ReceivingEvents(FollowEventStream), - /// We received a stop event. We'll send one on and restart the stream. - Stopped, - /// The stream is finished and will not restart (likely due to an error). - Finished, - } - impl std::fmt::Debug for InnerStreamState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::New => f.write_fmt(format_args!("New")), - Self::Initializing(_) => { - f.write_fmt(format_args!("Initializing(..)")) - } - Self::Ready(_) => f.write_fmt(format_args!("Ready(..)")), - Self::ReceivingEvents(_) => { - f.write_fmt(format_args!("ReceivingEvents(..)")) - } - Self::Stopped => f.write_fmt(format_args!("Stopped")), - Self::Finished => f.write_fmt(format_args!("Finished")), - } - } - } - impl FollowStream { - /// Create a new [`FollowStream`] given a function which returns the stream. - pub fn new(stream_getter: FollowEventStreamGetter) -> Self { - Self { - stream_getter, - stream: InnerStreamState::New, - } - } - /// Create a new [`FollowStream`] given the RPC methods. - pub fn from_methods( - methods: UnstableRpcMethods, - ) -> FollowStream { - FollowStream { - stream_getter: Box::new(move || { - let methods = methods.clone(); - Box::pin(async move { - let stream = methods.chainhead_unstable_follow(true).await?; - let Some(sub_id) = stream - .subscription_id() - .map(ToOwned::to_owned) else { - return Err( - Error::Other( - "Subscription ID expected for chainHead_follow response, but not given" - .to_owned(), - ), - ); - }; - let stream: FollowEventStream = Box::pin(stream); - Ok((stream, sub_id)) - }) - }), - stream: InnerStreamState::New, - } - } - } - impl std::marker::Unpin for FollowStream {} - impl Stream for FollowStream { - type Item = Result, Error>; - fn poll_next( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - let this = self.get_mut(); - loop { - match &mut this.stream { - InnerStreamState::New => { - let fut = (this.stream_getter)(); - this.stream = InnerStreamState::Initializing(fut); - continue; - } - InnerStreamState::Initializing(fut) => { - match fut.poll_unpin(cx) { - Poll::Pending => { - return Poll::Pending; - } - Poll::Ready(Ok(sub_with_id)) => { - this.stream = InnerStreamState::Ready(Some(sub_with_id)); - continue; - } - Poll::Ready(Err(e)) => { - this.stream = InnerStreamState::Finished; - return Poll::Ready(Some(Err(e))); - } - } - } - InnerStreamState::Ready(stream) => { - let (sub, sub_id) = stream - .take() - .expect("should always be Some"); - this.stream = InnerStreamState::ReceivingEvents(sub); - return Poll::Ready( - Some(Ok(FollowStreamMsg::Ready(sub_id))), - ); - } - InnerStreamState::ReceivingEvents(stream) => { - match stream.poll_next_unpin(cx) { - Poll::Pending => { - return Poll::Pending; - } - Poll::Ready(None) => { - this.stream = InnerStreamState::Stopped; - continue; - } - Poll::Ready(Some(Ok(ev))) => { - if let FollowEvent::Stop = ev { - this.stream = InnerStreamState::Stopped; - continue; - } - return Poll::Ready(Some(Ok(FollowStreamMsg::Event(ev)))); - } - Poll::Ready(Some(Err(e))) => { - this.stream = InnerStreamState::Finished; - return Poll::Ready(Some(Err(e))); - } - } - } - InnerStreamState::Stopped => { - this.stream = InnerStreamState::New; - return Poll::Ready( - Some(Ok(FollowStreamMsg::Event(FollowEvent::Stop))), - ); - } - InnerStreamState::Finished => { - return Poll::Ready(None); - } - } - } - } - } - } - mod follow_stream_driver { - use super::follow_stream_unpin::{ - BlockRef, FollowStreamMsg, FollowStreamUnpin, - }; - use crate::backend::unstable::rpc_methods::{ - FollowEvent, Initialized, RuntimeEvent, - }; - use crate::config::BlockHash; - use crate::error::Error; - use futures::stream::{Stream, StreamExt}; - use std::collections::{HashMap, HashSet, VecDeque}; - use std::ops::DerefMut; - use std::pin::Pin; - use std::sync::{Arc, Mutex}; - use std::task::{Context, Poll, Waker}; - /// A `Stream` which builds on `FollowStreamDriver`, and allows multiple subscribers to obtain events - /// from the single underlying subscription (each being provided an `Initialized` message and all new - /// blocks since then, as if they were each creating a unique `chainHead_follow` subscription). This - /// is the "top" layer of our follow stream subscriptions, and the one that's interacted with elsewhere. - pub struct FollowStreamDriver { - inner: FollowStreamUnpin, - shared: Shared, - } - #[automatically_derived] - impl ::core::fmt::Debug - for FollowStreamDriver { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "FollowStreamDriver", - "inner", - &self.inner, - "shared", - &&self.shared, - ) - } - } - impl FollowStreamDriver { - /// Create a new [`FollowStreamDriver`]. This must be polled by some executor - /// in order for any progress to be made. Things can subscribe to events. - pub fn new(follow_unpin: FollowStreamUnpin) -> Self { - Self { - inner: follow_unpin, - shared: Shared::default(), - } - } - /// Return a handle from which we can create new subscriptions to follow events. - pub fn handle(&self) -> FollowStreamDriverHandle { - FollowStreamDriverHandle { - shared: self.shared.clone(), - } - } - } - impl Stream for FollowStreamDriver { - type Item = Result<(), Error>; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - match self.inner.poll_next_unpin(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(None) => { - self.shared.done(); - Poll::Ready(None) - } - Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))), - Poll::Ready(Some(Ok(item))) => { - self.shared.push_item(item); - Poll::Ready(Some(Ok(()))) - } - } - } - } - /// A handle that can be used to create subscribers, but that doesn't - /// itself subscribe to events. - pub struct FollowStreamDriverHandle { - shared: Shared, - } - #[automatically_derived] - impl ::core::fmt::Debug - for FollowStreamDriverHandle { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "FollowStreamDriverHandle", - "shared", - &&self.shared, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for FollowStreamDriverHandle { - #[inline] - fn clone(&self) -> FollowStreamDriverHandle { - FollowStreamDriverHandle { - shared: ::core::clone::Clone::clone(&self.shared), - } - } - } - impl FollowStreamDriverHandle { - /// Subscribe to follow events. - pub fn subscribe(&self) -> FollowStreamDriverSubscription { - self.shared.subscribe() - } - } - /// A subscription to events from the [`FollowStreamDriver`]. All subscriptions - /// begin first with a `Ready` event containing the current subscription ID, and - /// then with an `Initialized` event containing the latest finalized block and latest - /// runtime information, and then any new/best block events and so on received since - /// the latest finalized block. - pub struct FollowStreamDriverSubscription { - id: usize, - done: bool, - shared: Shared, - local_items: VecDeque>>, - } - #[automatically_derived] - impl ::core::fmt::Debug - for FollowStreamDriverSubscription { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "FollowStreamDriverSubscription", - "id", - &self.id, - "done", - &self.done, - "shared", - &self.shared, - "local_items", - &&self.local_items, - ) - } - } - impl Stream for FollowStreamDriverSubscription { - type Item = FollowStreamMsg>; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - if self.done { - return Poll::Ready(None); - } - loop { - if let Some(item) = self.local_items.pop_front() { - return Poll::Ready(Some(item)); - } - let items = self - .shared - .take_items_and_save_waker(self.id, cx.waker()); - let Some(items) = items else { self.done = true; - return Poll::Ready(None); - }; - if items.is_empty() { - return Poll::Pending; - } else { - self.local_items = items; - } - } - } - } - impl FollowStreamDriverSubscription { - /// Return the current subscription ID. If the subscription has stopped, then this will - /// wait until a new subscription has started with a new ID. - pub async fn subscription_id(self) -> Option { - let ready_event = self - .skip_while(|ev| std::future::ready( - !match ev { - FollowStreamMsg::Ready(_) => true, - _ => false, - }, - )) - .next() - .await?; - match ready_event { - FollowStreamMsg::Ready(sub_id) => Some(sub_id), - _ => None, - } - } - /// Subscribe to the follow events, ignoring any other messages. - pub fn events( - self, - ) -> impl Stream>> + Send + Sync { - self.filter_map(|ev| std::future::ready(ev.into_event())) - } - } - impl Clone for FollowStreamDriverSubscription { - fn clone(&self) -> Self { - self.shared.subscribe() - } - } - impl Drop for FollowStreamDriverSubscription { - fn drop(&mut self) { - self.shared.remove_sub(self.id); - } - } - /// Locked shared state. The driver stream will access this state to push - /// events to any subscribers, and subscribers will access it to pull the - /// events destined for themselves. - struct Shared(Arc>>); - #[automatically_derived] - impl ::core::fmt::Debug - for Shared { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Shared", - &&self.0, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for Shared { - #[inline] - fn clone(&self) -> Shared { - Shared(::core::clone::Clone::clone(&self.0)) - } - } - struct SharedState { - done: bool, - next_id: usize, - subscribers: HashMap>, - /// Keep a buffer of all events that should be handed to a new subscription. - block_events_for_new_subscriptions: VecDeque< - FollowEvent>, - >, - current_subscription_id: Option, - current_init_message: Option>>, - seen_runtime_events: HashMap, - } - #[automatically_derived] - impl ::core::fmt::Debug - for SharedState { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "done", - "next_id", - "subscribers", - "block_events_for_new_subscriptions", - "current_subscription_id", - "current_init_message", - "seen_runtime_events", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.done, - &self.next_id, - &self.subscribers, - &self.block_events_for_new_subscriptions, - &self.current_subscription_id, - &self.current_init_message, - &&self.seen_runtime_events, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "SharedState", - names, - values, - ) - } - } - impl Default for Shared { - fn default() -> Self { - Shared( - Arc::new( - Mutex::new(SharedState { - next_id: 1, - done: false, - subscribers: HashMap::new(), - current_init_message: None, - current_subscription_id: None, - seen_runtime_events: HashMap::new(), - block_events_for_new_subscriptions: VecDeque::new(), - }), - ), - ) - } - } - impl Shared { - /// Set the shared state to "done"; no more items will be handed to it. - pub fn done(&self) { - let mut shared = self.0.lock().unwrap(); - shared.done = true; - } - /// Cleanup a subscription. - pub fn remove_sub(&self, sub_id: usize) { - let mut shared = self.0.lock().unwrap(); - shared.subscribers.remove(&sub_id); - } - /// Take items for some subscription ID and save the waker. - pub fn take_items_and_save_waker( - &self, - sub_id: usize, - waker: &Waker, - ) -> Option>>> { - let mut shared = self.0.lock().unwrap(); - let is_done = shared.done; - let details = shared.subscribers.get_mut(&sub_id)?; - if details.items.is_empty() && is_done { - return None; - } - let items = std::mem::take(&mut details.items); - if !is_done { - details.waker = Some(waker.clone()); - } - Some(items) - } - /// Push a new item out to subscribers. - pub fn push_item(&self, item: FollowStreamMsg>) { - let mut shared = self.0.lock().unwrap(); - let shared = shared.deref_mut(); - for details in shared.subscribers.values_mut() { - details.items.push_back(item.clone()); - if let Some(waker) = details.waker.take() { - waker.wake(); - } - } - match item { - FollowStreamMsg::Ready(sub_id) => { - shared.current_subscription_id = Some(sub_id); - } - FollowStreamMsg::Event(FollowEvent::Initialized(ev)) => { - shared.current_init_message = Some(ev.clone()); - shared.block_events_for_new_subscriptions.clear(); - } - FollowStreamMsg::Event(FollowEvent::Finalized(finalized_ev)) => { - if let Some(init_message) = &mut shared.current_init_message - { - let newest_runtime = finalized_ev - .finalized_block_hashes - .iter() - .rev() - .filter_map(|h| { - shared.seen_runtime_events.get(&h.hash()).cloned() - }) - .next(); - shared.seen_runtime_events.clear(); - if let Some(finalized) - = finalized_ev.finalized_block_hashes.last() - { - init_message.finalized_block_hash = finalized.clone(); - } - if let Some(runtime_ev) = newest_runtime { - init_message.finalized_block_runtime = Some(runtime_ev); - } - } - let to_remove: HashSet = finalized_ev - .finalized_block_hashes - .iter() - .chain(finalized_ev.pruned_block_hashes.iter()) - .map(|h| h.hash()) - .collect(); - shared - .block_events_for_new_subscriptions - .retain(|ev| match ev { - FollowEvent::NewBlock(new_block_ev) => { - !to_remove.contains(&new_block_ev.block_hash.hash()) - } - FollowEvent::BestBlockChanged(best_block_ev) => { - !to_remove.contains(&best_block_ev.best_block_hash.hash()) - } - _ => true, - }); - } - FollowStreamMsg::Event(FollowEvent::NewBlock(new_block_ev)) => { - if let Some(runtime_event) = &new_block_ev.new_runtime { - shared - .seen_runtime_events - .insert( - new_block_ev.block_hash.hash(), - runtime_event.clone(), - ); - } - shared - .block_events_for_new_subscriptions - .push_back(FollowEvent::NewBlock(new_block_ev)); - } - FollowStreamMsg::Event( - ev @ FollowEvent::BestBlockChanged(_), - ) => { - shared.block_events_for_new_subscriptions.push_back(ev); - } - FollowStreamMsg::Event(FollowEvent::Stop) => { - shared.block_events_for_new_subscriptions.clear(); - shared.current_subscription_id = None; - shared.current_init_message = None; - } - _ => {} - } - } - /// Create a new subscription. - pub fn subscribe(&self) -> FollowStreamDriverSubscription { - let mut shared = self.0.lock().unwrap(); - let id = shared.next_id; - shared.next_id += 1; - shared - .subscribers - .insert( - id, - SubscriberDetails { - items: VecDeque::new(), - waker: None, - }, - ); - let mut local_items = VecDeque::new(); - if let Some(sub_id) = &shared.current_subscription_id { - local_items.push_back(FollowStreamMsg::Ready(sub_id.clone())); - } - if let Some(init_msg) = &shared.current_init_message { - local_items - .push_back( - FollowStreamMsg::Event( - FollowEvent::Initialized(init_msg.clone()), - ), - ); - } - for ev in &shared.block_events_for_new_subscriptions { - local_items.push_back(FollowStreamMsg::Event(ev.clone())); - } - drop(shared); - FollowStreamDriverSubscription { - id, - done: false, - shared: self.clone(), - local_items, - } - } - } - /// Details for a given subscriber: any items it's not yet claimed, - /// and a way to wake it up when there are more items for it. - struct SubscriberDetails { - items: VecDeque>>, - waker: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug - for SubscriberDetails { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "SubscriberDetails", - "items", - &self.items, - "waker", - &&self.waker, - ) - } - } - } - mod follow_stream_unpin { - use super::follow_stream::FollowStream; - use super::UnstableRpcMethods; - use crate::backend::unstable::rpc_methods::{ - BestBlockChanged, Finalized, FollowEvent, Initialized, NewBlock, - }; - use crate::config::{BlockHash, Config}; - use crate::error::Error; - use futures::stream::{FuturesUnordered, Stream, StreamExt}; - use std::collections::{HashMap, HashSet}; - use std::future::Future; - use std::pin::Pin; - use std::sync::{Arc, Mutex}; - use std::task::{Context, Poll, Waker}; - /// The type of stream item. - pub use super::follow_stream::FollowStreamMsg; - /// A `Stream` which builds on `FollowStream`, and handles pinning. It replaces any block hash seen in - /// the follow events with a `BlockRef` which, when all clones are dropped, will lead to an "unpin" call - /// for that block hash being queued. It will also automatically unpin any blocks that exceed a given max - /// age, to try and prevent the underlying stream from ending (and _all_ blocks from being unpinned as a - /// result). Put simply, it tries to keep every block pinned as long as possible until the block is no longer - /// used anywhere. - pub struct FollowStreamUnpin { - inner: FollowStream, - unpin_method: UnpinMethodHolder, - unpin_futs: FuturesUnordered, - rel_block_num: usize, - subscription_id: Option>, - max_block_life: usize, - pinned: HashMap>, - unpin_flags: UnpinFlags, - } - #[automatically_derived] - impl ::core::fmt::Debug - for FollowStreamUnpin { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "inner", - "unpin_method", - "unpin_futs", - "rel_block_num", - "subscription_id", - "max_block_life", - "pinned", - "unpin_flags", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.inner, - &self.unpin_method, - &self.unpin_futs, - &self.rel_block_num, - &self.subscription_id, - &self.max_block_life, - &self.pinned, - &&self.unpin_flags, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "FollowStreamUnpin", - names, - values, - ) - } - } - struct UnpinMethodHolder(UnpinMethod); - impl std::fmt::Debug for UnpinMethodHolder { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt( - format_args!( - "UnpinMethodHolder(Box) -> UnpinFut>)" - ), - ) - } - } - /// The type of the unpin method that we need to provide. - pub type UnpinMethod = Box< - dyn FnMut(Hash, Arc) -> UnpinFut + Send, - >; - /// The future returned from [`UnpinMethod`]. - pub type UnpinFut = Pin + Send + 'static>>; - impl std::marker::Unpin for FollowStreamUnpin {} - impl Stream for FollowStreamUnpin { - type Item = Result>, Error>; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - let mut this = self.as_mut(); - loop { - let unpin_futs_are_pending = match this - .unpin_futs - .poll_next_unpin(cx) - { - Poll::Ready(Some(())) => continue, - Poll::Ready(None) => false, - Poll::Pending => true, - }; - let Poll::Ready(ev) = this.inner.poll_next_unpin(cx) else { - return Poll::Pending; - }; - let Some(ev) = ev else { - return match unpin_futs_are_pending { - true => Poll::Pending, - false => Poll::Ready(None), - }; - }; - let ev = match ev { - Ok(ev) => ev, - Err(e) => { - return Poll::Ready(Some(Err(e))); - } - }; - let ev = match ev { - FollowStreamMsg::Ready(subscription_id) => { - this.subscription_id = Some(subscription_id.clone().into()); - FollowStreamMsg::Ready(subscription_id) - } - FollowStreamMsg::Event( - FollowEvent::Initialized(details), - ) => { - let rel_block_num = this.rel_block_num; - let block_ref = this - .pin_unpinnable_block_at( - rel_block_num, - details.finalized_block_hash, - ); - FollowStreamMsg::Event( - FollowEvent::Initialized(Initialized { - finalized_block_hash: block_ref, - finalized_block_runtime: details.finalized_block_runtime, - }), - ) - } - FollowStreamMsg::Event(FollowEvent::NewBlock(details)) => { - let parent_rel_block_num = this - .pinned - .get(&details.parent_block_hash) - .map(|p| p.rel_block_num) - .unwrap_or(this.rel_block_num); - let block_ref = this - .pin_block_at(parent_rel_block_num + 1, details.block_hash); - let parent_block_ref = this - .pin_block_at( - parent_rel_block_num, - details.parent_block_hash, - ); - FollowStreamMsg::Event( - FollowEvent::NewBlock(NewBlock { - block_hash: block_ref, - parent_block_hash: parent_block_ref, - new_runtime: details.new_runtime, - }), - ) - } - FollowStreamMsg::Event( - FollowEvent::BestBlockChanged(details), - ) => { - let rel_block_num = this.rel_block_num + 1; - let block_ref = this - .pin_block_at(rel_block_num, details.best_block_hash); - FollowStreamMsg::Event( - FollowEvent::BestBlockChanged(BestBlockChanged { - best_block_hash: block_ref, - }), - ) - } - FollowStreamMsg::Event(FollowEvent::Finalized(details)) => { - let finalized_block_refs: Vec<_> = details - .finalized_block_hashes - .into_iter() - .enumerate() - .map(|(idx, hash)| { - let rel_block_num = this.rel_block_num + idx + 1; - this.pin_unpinnable_block_at(rel_block_num, hash) - }) - .collect(); - this.rel_block_num += finalized_block_refs.len(); - let pruned_block_refs: Vec<_> = details - .pruned_block_hashes - .into_iter() - .map(|hash| { - let rel_block_num = this.rel_block_num + 1; - this.pin_unpinnable_block_at(rel_block_num, hash) - }) - .collect(); - this.unpin_blocks(cx.waker()); - FollowStreamMsg::Event( - FollowEvent::Finalized(Finalized { - finalized_block_hashes: finalized_block_refs, - pruned_block_hashes: pruned_block_refs, - }), - ) - } - FollowStreamMsg::Event(FollowEvent::Stop) => { - this.subscription_id = None; - this.pinned.clear(); - this.unpin_futs.clear(); - this.unpin_flags.lock().unwrap().clear(); - this.rel_block_num = 0; - FollowStreamMsg::Event(FollowEvent::Stop) - } - FollowStreamMsg::Event( - FollowEvent::OperationBodyDone(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationBodyDone(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationCallDone(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationCallDone(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationStorageItems(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationStorageItems(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationWaitingForContinue(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationWaitingForContinue(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationStorageDone(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationStorageDone(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationInaccessible(details), - ) => { - FollowStreamMsg::Event( - FollowEvent::OperationInaccessible(details), - ) - } - FollowStreamMsg::Event( - FollowEvent::OperationError(details), - ) => { - FollowStreamMsg::Event(FollowEvent::OperationError(details)) - } - }; - return Poll::Ready(Some(Ok(ev))); - } - } - } - impl FollowStreamUnpin { - /// Create a new [`FollowStreamUnpin`]. - pub fn new( - follow_stream: FollowStream, - unpin_method: UnpinMethod, - max_block_life: usize, - ) -> Self { - Self { - inner: follow_stream, - unpin_method: UnpinMethodHolder(unpin_method), - max_block_life, - pinned: Default::default(), - subscription_id: None, - rel_block_num: 0, - unpin_flags: Default::default(), - unpin_futs: Default::default(), - } - } - /// Create a new [`FollowStreamUnpin`] given the RPC methods. - pub fn from_methods( - follow_stream: FollowStream, - methods: UnstableRpcMethods, - max_block_life: usize, - ) -> FollowStreamUnpin { - let unpin_method = Box::new(move |hash: T::Hash, sub_id: Arc| { - let methods = methods.clone(); - let fut: UnpinFut = Box::pin(async move { - let _ = methods - .chainhead_unstable_unpin(&sub_id, hash) - .await; - }); - fut - }); - FollowStreamUnpin::new(follow_stream, unpin_method, max_block_life) - } - /// Is the block hash currently pinned. - pub fn is_pinned(&self, hash: &Hash) -> bool { - self.pinned.contains_key(hash) - } - /// Pin a block, or return the reference to an already-pinned block. If the block has been registered to - /// be unpinned, we'll clear those flags, so that it won't be unpinned. If the unpin request has already - /// been sent though, then the block will be unpinned. - fn pin_block_at( - &mut self, - rel_block_num: usize, - hash: Hash, - ) -> BlockRef { - self.pin_block_at_setting_unpinnable_flag(rel_block_num, hash, false) - } - /// Pin a block, or return the reference to an already-pinned block. - /// - /// This is the same as [`Self::pin_block_at`], except that it also marks the block as being unpinnable now, - /// which should be done for any block that will no longer be seen in future events. - fn pin_unpinnable_block_at( - &mut self, - rel_block_num: usize, - hash: Hash, - ) -> BlockRef { - self.pin_block_at_setting_unpinnable_flag(rel_block_num, hash, true) - } - fn pin_block_at_setting_unpinnable_flag( - &mut self, - rel_block_num: usize, - hash: Hash, - can_be_unpinned: bool, - ) -> BlockRef { - let entry = self - .pinned - .entry(hash) - .and_modify(|entry| { - entry - .can_be_unpinned = entry.can_be_unpinned || can_be_unpinned; - self.unpin_flags.lock().unwrap().remove(&hash); - }) - .or_insert_with(|| PinnedDetails { - rel_block_num, - block_ref: BlockRef { - inner: Arc::new(BlockRefInner { - hash, - unpin_flags: self.unpin_flags.clone(), - }), - }, - can_be_unpinned, - }); - entry.block_ref.clone() - } - /// Unpin any blocks that are either too old, or have the unpin flag set and are old enough. - fn unpin_blocks(&mut self, waker: &Waker) { - let mut unpin_flags = self.unpin_flags.lock().unwrap(); - let rel_block_num = self.rel_block_num; - let Some(sub_id) = &self.subscription_id else { return; - }; - let mut blocks_to_unpin = ::alloc::vec::Vec::new(); - for (hash, details) in &self.pinned { - if rel_block_num.saturating_sub(details.rel_block_num) - >= self.max_block_life - || (unpin_flags.contains(hash) && details.can_be_unpinned) - { - blocks_to_unpin.push(*hash); - unpin_flags.remove(hash); - } - } - drop(unpin_flags); - if blocks_to_unpin.is_empty() { - return; - } - for hash in blocks_to_unpin { - self.pinned.remove(&hash); - let fut = (self.unpin_method.0)(hash, sub_id.clone()); - self.unpin_futs.push(fut); - } - waker.wake_by_ref(); - } - } - type UnpinFlags = Arc>>; - struct PinnedDetails { - /// How old is the block? - rel_block_num: usize, - /// A block ref we can hand out to keep blocks pinned. - /// Because we store one here until it's unpinned, the live count - /// will only drop to 1 when no external refs are left. - block_ref: BlockRef, - /// Has this block showed up in the list of pruned blocks, or has it - /// been finalized? In this case, it can now been pinned as it won't - /// show up again in future events (except as a "parent block" of some - /// new block, which we're currently ignoring). - can_be_unpinned: bool, - } - #[automatically_derived] - impl ::core::fmt::Debug - for PinnedDetails { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "PinnedDetails", - "rel_block_num", - &self.rel_block_num, - "block_ref", - &self.block_ref, - "can_be_unpinned", - &&self.can_be_unpinned, - ) - } - } - /// All blocks reported will be wrapped in this. - pub struct BlockRef { - inner: Arc>, - } - #[automatically_derived] - impl ::core::fmt::Debug - for BlockRef { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "BlockRef", - "inner", - &&self.inner, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for BlockRef { - #[inline] - fn clone(&self) -> BlockRef { - BlockRef { - inner: ::core::clone::Clone::clone(&self.inner), - } - } - } - struct BlockRefInner { - hash: Hash, - unpin_flags: UnpinFlags, - } - #[automatically_derived] - impl ::core::fmt::Debug for BlockRefInner { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "BlockRefInner", - "hash", - &self.hash, - "unpin_flags", - &&self.unpin_flags, - ) - } - } - impl BlockRef { - /// Return the hash for this block. - pub fn hash(&self) -> Hash { - self.inner.hash - } - } - impl PartialEq for BlockRef { - fn eq(&self, other: &Self) -> bool { - self.inner.hash == other.inner.hash - } - } - impl PartialEq for BlockRef { - fn eq(&self, other: &Hash) -> bool { - &self.inner.hash == other - } - } - impl Drop for BlockRef { - fn drop(&mut self) { - if Arc::strong_count(&self.inner) == 2 { - if let Ok(mut unpin_flags) = self.inner.unpin_flags.lock() { - unpin_flags.insert(self.inner.hash); - } - } - } - } - } - mod storage_items { - use super::follow_stream_driver::FollowStreamDriverHandle; - use super::follow_stream_unpin::BlockRef; - use super::rpc_methods::{ - FollowEvent, MethodResponse, StorageQuery, StorageResult, - UnstableRpcMethods, - }; - use crate::config::Config; - use crate::error::{Error, RpcError}; - use futures::{FutureExt, Stream, StreamExt}; - use std::collections::VecDeque; - use std::future::Future; - use std::pin::Pin; - use std::sync::Arc; - use std::task::{Context, Poll}; - /// Obtain a stream of storage items given some query. this handles continuing - /// and stopping under the hood, and returns a stream of `StorageResult`s. - pub struct StorageItems { - done: bool, - operation_id: Arc, - buffered_responses: VecDeque, - continue_call: ContinueFutGetter, - continue_fut: Option, - follow_event_stream: FollowEventStream, - } - impl StorageItems { - pub async fn from_methods( - queries: impl Iterator>, - at: T::Hash, - follow_handle: &FollowStreamDriverHandle, - methods: UnstableRpcMethods, - ) -> Result { - let sub_id = super::get_subscription_id(follow_handle).await?; - let follow_events = follow_handle.subscribe().events(); - let status = methods - .chainhead_unstable_storage(&sub_id, at, queries, None) - .await?; - let operation_id: Arc = match status { - MethodResponse::LimitReached => { - return Err( - RpcError::request_rejected("limit reached").into(), - ); - } - MethodResponse::Started(s) => s.operation_id.into(), - }; - let continue_call: ContinueFutGetter = { - let operation_id = operation_id.clone(); - Box::new(move || { - let sub_id = sub_id.clone(); - let operation_id = operation_id.clone(); - let methods = methods.clone(); - Box::pin(async move { - methods - .chainhead_unstable_continue(&sub_id, &operation_id) - .await - }) - }) - }; - Ok( - StorageItems::new( - operation_id, - continue_call, - Box::pin(follow_events), - ), - ) - } - fn new( - operation_id: Arc, - continue_call: ContinueFutGetter, - follow_event_stream: FollowEventStream, - ) -> Self { - Self { - done: false, - buffered_responses: VecDeque::new(), - operation_id, - continue_call, - continue_fut: None, - follow_event_stream, - } - } - } - pub type FollowEventStream = Pin< - Box>> + Send + 'static>, - >; - pub type ContinueFutGetter = Box ContinueFut + Send + 'static>; - pub type ContinueFut = Pin< - Box> + Send + 'static>, - >; - impl Stream for StorageItems { - type Item = Result; - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - loop { - if self.done { - return Poll::Ready(None); - } - if let Some(item) = self.buffered_responses.pop_front() { - return Poll::Ready(Some(Ok(item))); - } - if let Some(mut fut) = self.continue_fut.take() { - match fut.poll_unpin(cx) { - Poll::Pending => { - self.continue_fut = Some(fut); - return Poll::Pending; - } - Poll::Ready(Err(e)) => { - self.done = true; - return Poll::Ready(Some(Err(e))); - } - Poll::Ready(Ok(())) => {} - } - } - let ev = match self.follow_event_stream.poll_next_unpin(cx) { - Poll::Pending => return Poll::Pending, - Poll::Ready(None) => return Poll::Ready(None), - Poll::Ready(Some(ev)) => ev, - }; - match ev { - FollowEvent::OperationWaitingForContinue( - id, - ) if id.operation_id == *self.operation_id => { - self.continue_fut = Some((self.continue_call)()); - continue; - } - FollowEvent::OperationStorageDone( - id, - ) if id.operation_id == *self.operation_id => { - self.done = true; - return Poll::Ready(None); - } - FollowEvent::OperationStorageItems( - items, - ) if items.operation_id == *self.operation_id => { - self.buffered_responses = items.items; - continue; - } - _ => { - continue; - } - } - } - } - } - } - pub mod rpc_methods { - //! An interface to call the API methods. See - //! for details of the API - //! methods exposed here. - use crate::backend::rpc::{rpc_params, RpcClient, RpcSubscription}; - use crate::config::BlockHash; - use crate::{Config, Error}; - use derivative::Derivative; - use futures::{Stream, StreamExt}; - use serde::{Deserialize, Serialize}; - use std::collections::{HashMap, VecDeque}; - use std::task::Poll; - /// An interface to call the unstable RPC methods. This interface is instantiated with - /// some `T: Config` trait which determines some of the types that the RPC methods will - /// take or hand back. - #[derivative(Clone(bound = ""), Debug(bound = ""))] - pub struct UnstableRpcMethods { - client: RpcClient, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for UnstableRpcMethods { - fn clone(&self) -> Self { - match *self { - UnstableRpcMethods { - client: ref __arg_0, - _marker: ref __arg_1, - } => { - UnstableRpcMethods { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for UnstableRpcMethods { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - UnstableRpcMethods { - client: ref __arg_0, - _marker: ref __arg_1, - } => { - let mut __debug_trait_builder = __f - .debug_struct("UnstableRpcMethods"); - let _ = __debug_trait_builder.field("client", &&(*__arg_0)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - impl UnstableRpcMethods { - /// Instantiate the legacy RPC method interface. - pub fn new(client: RpcClient) -> Self { - UnstableRpcMethods { - client, - _marker: std::marker::PhantomData, - } - } - /// Subscribe to `chainHead_unstable_follow` to obtain all reported blocks by the chain. - /// - /// The subscription ID can be used to make queries for the - /// block's body ([`chainhead_unstable_body`](UnstableRpcMethods::chainhead_unstable_follow)), - /// block's header ([`chainhead_unstable_header`](UnstableRpcMethods::chainhead_unstable_header)), - /// block's storage ([`chainhead_unstable_storage`](UnstableRpcMethods::chainhead_unstable_storage)) and submitting - /// runtime API calls at this block ([`chainhead_unstable_call`](UnstableRpcMethods::chainhead_unstable_call)). - /// - /// # Note - /// - /// When the user is no longer interested in a block, the user is responsible - /// for calling the [`chainhead_unstable_unpin`](UnstableRpcMethods::chainhead_unstable_unpin) method. - /// Failure to do so will result in the subscription being stopped by generating the `Stop` event. - pub async fn chainhead_unstable_follow( - &self, - with_runtime: bool, - ) -> Result, Error> { - let sub = self - .client - .subscribe( - "chainHead_unstable_follow", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(with_runtime) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - "chainHead_unstable_unfollow", - ) - .await?; - Ok(FollowSubscription { - sub, - done: false, - }) - } - /// Resumes a storage fetch started with chainHead_unstable_storage after it has generated an - /// `operationWaitingForContinue` event. - /// - /// Has no effect if the operationId is invalid or refers to an operation that has emitted a - /// `{"event": "operationInaccessible"` event, or if the followSubscription is invalid or stale. - pub async fn chainhead_unstable_continue( - &self, - follow_subscription: &str, - operation_id: &str, - ) -> Result<(), Error> { - self.client - .request( - "chainHead_unstable_continue", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(follow_subscription) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(operation_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(()) - } - /// Stops an operation started with `chainHead_unstable_body`, `chainHead_unstable_call`, or - /// `chainHead_unstable_storage¦. If the operation was still in progress, this interrupts it. - /// If the operation was already finished, this call has no effect. - /// - /// Has no effect if the `followSubscription` is invalid or stale. - pub async fn chainhead_unstable_stop_operation( - &self, - follow_subscription: &str, - operation_id: &str, - ) -> Result<(), Error> { - self.client - .request( - "chainHead_unstable_stopOperation", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(follow_subscription) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(operation_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(()) - } - /// Call the `chainHead_unstable_body` method and return an operation ID to obtain the block's body. - /// - /// The response events are provided on the `chainHead_follow` subscription and identified by - /// the returned operation ID. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_body( - &self, - subscription_id: &str, - hash: T::Hash, - ) -> Result { - let response = self - .client - .request( - "chainHead_unstable_body", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(response) - } - /// Get the block's header using the `chainHead_unstable_header` method. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_header( - &self, - subscription_id: &str, - hash: T::Hash, - ) -> Result, Error> { - let header: Option = self - .client - .request( - "chainHead_unstable_header", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - let header = header - .map(|h| codec::Decode::decode(&mut &*h.0)) - .transpose()?; - Ok(header) - } - /// Call the `chainhead_unstable_storage` method and return an operation ID to obtain the block's storage. - /// - /// The response events are provided on the `chainHead_follow` subscription and identified by - /// the returned operation ID. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_storage( - &self, - subscription_id: &str, - hash: T::Hash, - items: impl IntoIterator>, - child_key: Option<&[u8]>, - ) -> Result { - let items: Vec> = items - .into_iter() - .map(|item| StorageQuery { - key: to_hex(item.key), - query_type: item.query_type, - }) - .collect(); - let response = self - .client - .request( - "chainHead_unstable_storage", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(items) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(child_key.map(to_hex)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(response) - } - /// Call the `chainhead_unstable_storage` method and return an operation ID to obtain the runtime API result. - /// - /// The response events are provided on the `chainHead_follow` subscription and identified by - /// the returned operation ID. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_call( - &self, - subscription_id: &str, - hash: T::Hash, - function: &str, - call_parameters: &[u8], - ) -> Result { - let response = self - .client - .request( - "chainHead_unstable_call", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(function) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(to_hex(call_parameters)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(response) - } - /// Unpin a block reported by the `chainHead_follow` subscription. - /// - /// # Note - /// - /// The subscription ID is obtained from an open subscription created by - /// [`chainhead_unstable_follow`](UnstableRpcMethods::chainhead_unstable_follow). - pub async fn chainhead_unstable_unpin( - &self, - subscription_id: &str, - hash: T::Hash, - ) -> Result<(), Error> { - self.client - .request( - "chainHead_unstable_unpin", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(subscription_id) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - .push(hash) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - ) - .await?; - Ok(()) - } - /// Return the genesis hash. - pub async fn chainspec_v1_genesis_hash(&self) -> Result { - let hash = self - .client - .request( - "chainSpec_v1_genesisHash", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await?; - Ok(hash) - } - /// Return a string containing the human-readable name of the chain. - pub async fn chainspec_v1_chain_name(&self) -> Result { - let hash = self - .client - .request( - "chainSpec_v1_chainName", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await?; - Ok(hash) - } - /// Returns the JSON payload found in the chain specification under the key properties. - /// No guarantee is offered about the content of this object, and so it's up to the caller - /// to decide what to deserialize it into. - pub async fn chainspec_v1_properties( - &self, - ) -> Result { - self.client - .request( - "chainSpec_v1_properties", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Returns an array of strings indicating the names of all the JSON-RPC functions supported by - /// the JSON-RPC server. - pub async fn rpc_methods(&self) -> Result, Error> { - self.client - .request( - "rpc_methods", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - }, - ) - .await - } - /// Attempt to submit a transaction, returning events about its progress. - pub async fn transaction_unstable_submit_and_watch( - &self, - tx: &[u8], - ) -> Result, Error> { - let sub = self - .client - .subscribe( - "transactionWatch_unstable_submitAndWatch", - { - #[allow(unused_mut)] - let mut params = crate::backend::rpc::RpcParams::new(); - params - .push(to_hex(tx)) - .expect( - "values passed to rpc_params! must be serializable to JSON", - ); - params - }, - "transactionWatch_unstable_unwatch", - ) - .await?; - Ok(TransactionSubscription { - sub, - done: false, - }) - } - } - /// This represents events generated by the `follow` method. - /// - /// The block events are generated in the following order: - /// 1. Initialized - generated only once to signal the latest finalized block - /// 2. NewBlock - a new block was added. - /// 3. BestBlockChanged - indicate that the best block is now the one from this event. The block was - /// announced priorly with the `NewBlock` event. - /// 4. Finalized - State the finalized and pruned blocks. - /// - /// The following events are related to operations: - /// - OperationBodyDone: The response of the `chainHead_body` - /// - OperationCallDone: The response of the `chainHead_call` - /// - OperationStorageItems: Items produced by the `chianHead_storage` - /// - OperationWaitingForContinue: Generated after OperationStorageItems and requires the user to - /// call `chainHead_continue` - /// - OperationStorageDone: The `chainHead_storage` method has produced all the results - /// - OperationInaccessible: The server was unable to provide the result, retries might succeed in - /// the future - /// - OperationError: The server encountered an error, retries will not succeed - /// - /// The stop event indicates that the JSON-RPC server was unable to provide a consistent list of - /// the blocks at the head of the chain. - #[serde(rename_all = "camelCase")] - #[serde(tag = "event")] - pub enum FollowEvent { - /// The latest finalized block. - /// - /// This event is generated only once. - Initialized(Initialized), - /// A new non-finalized block was added. - NewBlock(NewBlock), - /// The best block of the chain. - BestBlockChanged(BestBlockChanged), - /// A list of finalized and pruned blocks. - Finalized(Finalized), - /// The response of the `chainHead_body` method. - OperationBodyDone(OperationBodyDone), - /// The response of the `chainHead_call` method. - OperationCallDone(OperationCallDone), - /// Yield one or more items found in the storage. - OperationStorageItems(OperationStorageItems), - /// Ask the user to call `chainHead_continue` to produce more events - /// regarding the operation id. - OperationWaitingForContinue(OperationId), - /// The responses of the `chainHead_storage` method have been produced. - OperationStorageDone(OperationId), - /// The RPC server was unable to provide the response of the following operation id. - /// - /// Repeating the same operation in the future might succeed. - OperationInaccessible(OperationId), - /// The RPC server encountered an error while processing an operation id. - /// - /// Repeating the same operation in the future will not succeed. - OperationError(OperationError), - /// The subscription is dropped and no further events - /// will be generated. - Stop, - } - #[automatically_derived] - impl ::core::fmt::Debug for FollowEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - FollowEvent::Initialized(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Initialized", - &__self_0, - ) - } - FollowEvent::NewBlock(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "NewBlock", - &__self_0, - ) - } - FollowEvent::BestBlockChanged(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "BestBlockChanged", - &__self_0, - ) - } - FollowEvent::Finalized(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Finalized", - &__self_0, - ) - } - FollowEvent::OperationBodyDone(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationBodyDone", - &__self_0, - ) - } - FollowEvent::OperationCallDone(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationCallDone", - &__self_0, - ) - } - FollowEvent::OperationStorageItems(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationStorageItems", - &__self_0, - ) - } - FollowEvent::OperationWaitingForContinue(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationWaitingForContinue", - &__self_0, - ) - } - FollowEvent::OperationStorageDone(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationStorageDone", - &__self_0, - ) - } - FollowEvent::OperationInaccessible(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationInaccessible", - &__self_0, - ) - } - FollowEvent::OperationError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "OperationError", - &__self_0, - ) - } - FollowEvent::Stop => ::core::fmt::Formatter::write_str(f, "Stop"), - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for FollowEvent { - #[inline] - fn clone(&self) -> FollowEvent { - match self { - FollowEvent::Initialized(__self_0) => { - FollowEvent::Initialized( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::NewBlock(__self_0) => { - FollowEvent::NewBlock(::core::clone::Clone::clone(__self_0)) - } - FollowEvent::BestBlockChanged(__self_0) => { - FollowEvent::BestBlockChanged( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::Finalized(__self_0) => { - FollowEvent::Finalized(::core::clone::Clone::clone(__self_0)) - } - FollowEvent::OperationBodyDone(__self_0) => { - FollowEvent::OperationBodyDone( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationCallDone(__self_0) => { - FollowEvent::OperationCallDone( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationStorageItems(__self_0) => { - FollowEvent::OperationStorageItems( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationWaitingForContinue(__self_0) => { - FollowEvent::OperationWaitingForContinue( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationStorageDone(__self_0) => { - FollowEvent::OperationStorageDone( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationInaccessible(__self_0) => { - FollowEvent::OperationInaccessible( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::OperationError(__self_0) => { - FollowEvent::OperationError( - ::core::clone::Clone::clone(__self_0), - ) - } - FollowEvent::Stop => FollowEvent::Stop, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for FollowEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for FollowEvent { - #[inline] - fn eq(&self, other: &FollowEvent) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - FollowEvent::Initialized(__self_0), - FollowEvent::Initialized(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::NewBlock(__self_0), - FollowEvent::NewBlock(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::BestBlockChanged(__self_0), - FollowEvent::BestBlockChanged(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::Finalized(__self_0), - FollowEvent::Finalized(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationBodyDone(__self_0), - FollowEvent::OperationBodyDone(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationCallDone(__self_0), - FollowEvent::OperationCallDone(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationStorageItems(__self_0), - FollowEvent::OperationStorageItems(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationWaitingForContinue(__self_0), - FollowEvent::OperationWaitingForContinue(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationStorageDone(__self_0), - FollowEvent::OperationStorageDone(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationInaccessible(__self_0), - FollowEvent::OperationInaccessible(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - FollowEvent::OperationError(__self_0), - FollowEvent::OperationError(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for FollowEvent { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for FollowEvent - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __field6, - __field7, - __field8, - __field9, - __field10, - __field11, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - 5u64 => _serde::__private::Ok(__Field::__field5), - 6u64 => _serde::__private::Ok(__Field::__field6), - 7u64 => _serde::__private::Ok(__Field::__field7), - 8u64 => _serde::__private::Ok(__Field::__field8), - 9u64 => _serde::__private::Ok(__Field::__field9), - 10u64 => _serde::__private::Ok(__Field::__field10), - 11u64 => _serde::__private::Ok(__Field::__field11), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 12", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "initialized" => _serde::__private::Ok(__Field::__field0), - "newBlock" => _serde::__private::Ok(__Field::__field1), - "bestBlockChanged" => { - _serde::__private::Ok(__Field::__field2) - } - "finalized" => _serde::__private::Ok(__Field::__field3), - "operationBodyDone" => { - _serde::__private::Ok(__Field::__field4) - } - "operationCallDone" => { - _serde::__private::Ok(__Field::__field5) - } - "operationStorageItems" => { - _serde::__private::Ok(__Field::__field6) - } - "operationWaitingForContinue" => { - _serde::__private::Ok(__Field::__field7) - } - "operationStorageDone" => { - _serde::__private::Ok(__Field::__field8) - } - "operationInaccessible" => { - _serde::__private::Ok(__Field::__field9) - } - "operationError" => { - _serde::__private::Ok(__Field::__field10) - } - "stop" => _serde::__private::Ok(__Field::__field11), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"initialized" => _serde::__private::Ok(__Field::__field0), - b"newBlock" => _serde::__private::Ok(__Field::__field1), - b"bestBlockChanged" => { - _serde::__private::Ok(__Field::__field2) - } - b"finalized" => _serde::__private::Ok(__Field::__field3), - b"operationBodyDone" => { - _serde::__private::Ok(__Field::__field4) - } - b"operationCallDone" => { - _serde::__private::Ok(__Field::__field5) - } - b"operationStorageItems" => { - _serde::__private::Ok(__Field::__field6) - } - b"operationWaitingForContinue" => { - _serde::__private::Ok(__Field::__field7) - } - b"operationStorageDone" => { - _serde::__private::Ok(__Field::__field8) - } - b"operationInaccessible" => { - _serde::__private::Ok(__Field::__field9) - } - b"operationError" => { - _serde::__private::Ok(__Field::__field10) - } - b"stop" => _serde::__private::Ok(__Field::__field11), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "initialized", - "newBlock", - "bestBlockChanged", - "finalized", - "operationBodyDone", - "operationCallDone", - "operationStorageItems", - "operationWaitingForContinue", - "operationStorageDone", - "operationInaccessible", - "operationError", - "stop", - ]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::TaggedContentVisitor::< - __Field, - >::new("event", "internally tagged enum FollowEvent"), - )?; - let __deserializer = _serde::__private::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::__private::Result::map( - as _serde::Deserialize>::deserialize(__deserializer), - FollowEvent::Initialized, - ) - } - __Field::__field1 => { - _serde::__private::Result::map( - as _serde::Deserialize>::deserialize(__deserializer), - FollowEvent::NewBlock, - ) - } - __Field::__field2 => { - _serde::__private::Result::map( - as _serde::Deserialize>::deserialize(__deserializer), - FollowEvent::BestBlockChanged, - ) - } - __Field::__field3 => { - _serde::__private::Result::map( - as _serde::Deserialize>::deserialize(__deserializer), - FollowEvent::Finalized, - ) - } - __Field::__field4 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationBodyDone, - ) - } - __Field::__field5 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationCallDone, - ) - } - __Field::__field6 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationStorageItems, - ) - } - __Field::__field7 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationWaitingForContinue, - ) - } - __Field::__field8 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationStorageDone, - ) - } - __Field::__field9 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationInaccessible, - ) - } - __Field::__field10 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - FollowEvent::OperationError, - ) - } - __Field::__field11 => { - _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::InternallyTaggedUnitVisitor::new( - "FollowEvent", - "Stop", - ), - )?; - _serde::__private::Ok(FollowEvent::Stop) - } - } - } - } - }; - /// Contain information about the latest finalized block. - /// - /// # Note - /// - /// This is the first event generated by the `follow` subscription - /// and is submitted only once. - #[serde(rename_all = "camelCase")] - pub struct Initialized { - /// The hash of the latest finalized block. - pub finalized_block_hash: Hash, - /// The runtime version of the finalized block. - /// - /// # Note - /// - /// This is present only if the `with_runtime` flag is set for - /// the `follow` subscription. - pub finalized_block_runtime: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug for Initialized { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Initialized", - "finalized_block_hash", - &self.finalized_block_hash, - "finalized_block_runtime", - &&self.finalized_block_runtime, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for Initialized { - #[inline] - fn clone(&self) -> Initialized { - Initialized { - finalized_block_hash: ::core::clone::Clone::clone( - &self.finalized_block_hash, - ), - finalized_block_runtime: ::core::clone::Clone::clone( - &self.finalized_block_runtime, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Initialized {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for Initialized { - #[inline] - fn eq(&self, other: &Initialized) -> bool { - self.finalized_block_hash == other.finalized_block_hash - && self.finalized_block_runtime == other.finalized_block_runtime - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Initialized { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for Initialized - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "finalizedBlockHash" => { - _serde::__private::Ok(__Field::__field0) - } - "finalizedBlockRuntime" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"finalizedBlockHash" => { - _serde::__private::Ok(__Field::__field0) - } - b"finalizedBlockRuntime" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = Initialized; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct Initialized", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Initialized with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Initialized with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(Initialized { - finalized_block_hash: __field0, - finalized_block_runtime: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - Option, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "finalizedBlockHash", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "finalizedBlockRuntime", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("finalizedBlockHash")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field( - "finalizedBlockRuntime", - )? - } - }; - _serde::__private::Ok(Initialized { - finalized_block_hash: __field0, - finalized_block_runtime: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "finalizedBlockHash", - "finalizedBlockRuntime", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Initialized", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The runtime event generated if the `follow` subscription - /// has set the `with_runtime` flag. - #[serde(rename_all = "camelCase")] - #[serde(tag = "type")] - pub enum RuntimeEvent { - /// The runtime version of this block. - Valid(RuntimeVersionEvent), - /// The runtime could not be obtained due to an error. - Invalid(ErrorEvent), - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - RuntimeEvent::Valid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Valid", - &__self_0, - ) - } - RuntimeEvent::Invalid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Invalid", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeEvent { - #[inline] - fn clone(&self) -> RuntimeEvent { - match self { - RuntimeEvent::Valid(__self_0) => { - RuntimeEvent::Valid(::core::clone::Clone::clone(__self_0)) - } - RuntimeEvent::Invalid(__self_0) => { - RuntimeEvent::Invalid(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeEvent { - #[inline] - fn eq(&self, other: &RuntimeEvent) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - RuntimeEvent::Valid(__self_0), - RuntimeEvent::Valid(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - RuntimeEvent::Invalid(__self_0), - RuntimeEvent::Invalid(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeEvent { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RuntimeEvent { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "valid" => _serde::__private::Ok(__Field::__field0), - "invalid" => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"valid" => _serde::__private::Ok(__Field::__field0), - b"invalid" => _serde::__private::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &["valid", "invalid"]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::TaggedContentVisitor::< - __Field, - >::new("type", "internally tagged enum RuntimeEvent"), - )?; - let __deserializer = _serde::__private::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - RuntimeEvent::Valid, - ) - } - __Field::__field1 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - RuntimeEvent::Invalid, - ) - } - } - } - } - }; - /// The runtime specification of the current block. - /// - /// This event is generated for: - /// - the first announced block by the follow subscription - /// - blocks that suffered a change in runtime compared with their parents - #[serde(rename_all = "camelCase")] - pub struct RuntimeVersionEvent { - /// Details about this runtime. - pub spec: RuntimeSpec, - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeVersionEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "RuntimeVersionEvent", - "spec", - &&self.spec, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeVersionEvent { - #[inline] - fn clone(&self) -> RuntimeVersionEvent { - RuntimeVersionEvent { - spec: ::core::clone::Clone::clone(&self.spec), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeVersionEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeVersionEvent { - #[inline] - fn eq(&self, other: &RuntimeVersionEvent) -> bool { - self.spec == other.spec - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeVersionEvent { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RuntimeVersionEvent { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "spec" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"spec" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = RuntimeVersionEvent; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct RuntimeVersionEvent", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - RuntimeSpec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct RuntimeVersionEvent with 1 element", - ), - ); - } - }; - _serde::__private::Ok(RuntimeVersionEvent { - spec: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("spec"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - RuntimeSpec, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("spec")? - } - }; - _serde::__private::Ok(RuntimeVersionEvent { - spec: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["spec"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "RuntimeVersionEvent", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - RuntimeVersionEvent, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// This contains the runtime version information necessary to make transactions, and is obtained from - /// the "initialized" event of `chainHead_follow` if the `withRuntime` flag is set. - #[serde(rename_all = "camelCase")] - pub struct RuntimeSpec { - /// Opaque string indicating the name of the chain. - pub spec_name: String, - /// Opaque string indicating the name of the implementation of the chain. - pub impl_name: String, - /// Opaque integer. The JSON-RPC client can assume that the Runtime API call to `Metadata_metadata` - /// will always produce the same output as long as the specVersion is the same. - pub spec_version: u32, - /// Opaque integer. Whenever the runtime code changes in a backwards-compatible way, the implVersion - /// is modified while the specVersion is left untouched. - pub impl_version: u32, - /// Opaque integer. Necessary when building the bytes of a transaction. Transactions that have been - /// generated with a different `transaction_version` are incompatible. - pub transaction_version: u32, - /// Object containing a list of "entry point APIs" supported by the runtime. Each key is an opaque string - /// indicating the API, and each value is an integer version number. Before making a runtime call (using - /// chainHead_call), you should make sure that this list contains the entry point API corresponding to the - /// call and with a known version number. - /// - /// **Note:** In Substrate, the keys in the apis field consists of the hexadecimal-encoded 8-bytes blake2 - /// hash of the name of the API. For example, the `TaggedTransactionQueue` API is 0xd2bc9897eed08f15. - #[serde(with = "hashmap_as_tuple_list")] - pub apis: HashMap, - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeSpec { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "spec_name", - "impl_name", - "spec_version", - "impl_version", - "transaction_version", - "apis", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.spec_name, - &self.impl_name, - &self.spec_version, - &self.impl_version, - &self.transaction_version, - &&self.apis, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "RuntimeSpec", - names, - values, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeSpec { - #[inline] - fn clone(&self) -> RuntimeSpec { - RuntimeSpec { - spec_name: ::core::clone::Clone::clone(&self.spec_name), - impl_name: ::core::clone::Clone::clone(&self.impl_name), - spec_version: ::core::clone::Clone::clone(&self.spec_version), - impl_version: ::core::clone::Clone::clone(&self.impl_version), - transaction_version: ::core::clone::Clone::clone( - &self.transaction_version, - ), - apis: ::core::clone::Clone::clone(&self.apis), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeSpec {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeSpec { - #[inline] - fn eq(&self, other: &RuntimeSpec) -> bool { - self.spec_name == other.spec_name - && self.impl_name == other.impl_name - && self.spec_version == other.spec_version - && self.impl_version == other.impl_version - && self.transaction_version == other.transaction_version - && self.apis == other.apis - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeSpec { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for RuntimeSpec { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - 5u64 => _serde::__private::Ok(__Field::__field5), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "specName" => _serde::__private::Ok(__Field::__field0), - "implName" => _serde::__private::Ok(__Field::__field1), - "specVersion" => _serde::__private::Ok(__Field::__field2), - "implVersion" => _serde::__private::Ok(__Field::__field3), - "transactionVersion" => { - _serde::__private::Ok(__Field::__field4) - } - "apis" => _serde::__private::Ok(__Field::__field5), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"specName" => _serde::__private::Ok(__Field::__field0), - b"implName" => _serde::__private::Ok(__Field::__field1), - b"specVersion" => _serde::__private::Ok(__Field::__field2), - b"implVersion" => _serde::__private::Ok(__Field::__field3), - b"transactionVersion" => { - _serde::__private::Ok(__Field::__field4) - } - b"apis" => _serde::__private::Ok(__Field::__field5), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = RuntimeSpec; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct RuntimeSpec", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - let __field5 = match { - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: HashMap, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: hashmap_as_tuple_list::deserialize(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 5usize, - &"struct RuntimeSpec with 6 elements", - ), - ); - } - }; - _serde::__private::Ok(RuntimeSpec { - spec_name: __field0, - impl_name: __field1, - spec_version: __field2, - impl_version: __field3, - transaction_version: __field4, - apis: __field5, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option = _serde::__private::None; - let mut __field3: _serde::__private::Option = _serde::__private::None; - let mut __field4: _serde::__private::Option = _serde::__private::None; - let mut __field5: _serde::__private::Option< - HashMap, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "specName", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "implName", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "specVersion", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private::Option::is_some(&__field3) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "implVersion", - ), - ); - } - __field3 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private::Option::is_some(&__field4) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "transactionVersion", - ), - ); - } - __field4 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field5 => { - if _serde::__private::Option::is_some(&__field5) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("apis"), - ); - } - __field5 = _serde::__private::Some({ - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: HashMap, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: hashmap_as_tuple_list::deserialize(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - match _serde::de::MapAccess::next_value::< - __DeserializeWith<'de>, - >(&mut __map) { - _serde::__private::Ok(__wrapper) => __wrapper.value, - _serde::__private::Err(__err) => { - return _serde::__private::Err(__err); - } - } - }); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("specName")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("implName")? - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("specVersion")? - } - }; - let __field3 = match __field3 { - _serde::__private::Some(__field3) => __field3, - _serde::__private::None => { - _serde::__private::de::missing_field("implVersion")? - } - }; - let __field4 = match __field4 { - _serde::__private::Some(__field4) => __field4, - _serde::__private::None => { - _serde::__private::de::missing_field("transactionVersion")? - } - }; - let __field5 = match __field5 { - _serde::__private::Some(__field5) => __field5, - _serde::__private::None => { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::missing_field("apis"), - ); - } - }; - _serde::__private::Ok(RuntimeSpec { - spec_name: __field0, - impl_name: __field1, - spec_version: __field2, - impl_version: __field3, - transaction_version: __field4, - apis: __field5, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "specName", - "implName", - "specVersion", - "implVersion", - "transactionVersion", - "apis", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "RuntimeSpec", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The operation could not be processed due to an error. - #[serde(rename_all = "camelCase")] - pub struct ErrorEvent { - /// Reason of the error. - pub error: String, - } - #[automatically_derived] - impl ::core::fmt::Debug for ErrorEvent { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "ErrorEvent", - "error", - &&self.error, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for ErrorEvent { - #[inline] - fn clone(&self) -> ErrorEvent { - ErrorEvent { - error: ::core::clone::Clone::clone(&self.error), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ErrorEvent {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ErrorEvent { - #[inline] - fn eq(&self, other: &ErrorEvent) -> bool { - self.error == other.error - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ErrorEvent { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for ErrorEvent { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = ErrorEvent; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct ErrorEvent", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct ErrorEvent with 1 element", - ), - ); - } - }; - _serde::__private::Ok(ErrorEvent { error: __field0 }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(ErrorEvent { error: __field0 }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["error"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "ErrorEvent", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate a new non-finalized block. - #[serde(rename_all = "camelCase")] - pub struct NewBlock { - /// The hash of the new block. - pub block_hash: Hash, - /// The parent hash of the new block. - pub parent_block_hash: Hash, - /// The runtime version of the new block. - /// - /// # Note - /// - /// This is present only if the `with_runtime` flag is set for - /// the `follow` subscription. - pub new_runtime: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug for NewBlock { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "NewBlock", - "block_hash", - &self.block_hash, - "parent_block_hash", - &self.parent_block_hash, - "new_runtime", - &&self.new_runtime, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for NewBlock { - #[inline] - fn clone(&self) -> NewBlock { - NewBlock { - block_hash: ::core::clone::Clone::clone(&self.block_hash), - parent_block_hash: ::core::clone::Clone::clone( - &self.parent_block_hash, - ), - new_runtime: ::core::clone::Clone::clone(&self.new_runtime), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for NewBlock {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for NewBlock { - #[inline] - fn eq(&self, other: &NewBlock) -> bool { - self.block_hash == other.block_hash - && self.parent_block_hash == other.parent_block_hash - && self.new_runtime == other.new_runtime - } - } - #[automatically_derived] - impl ::core::cmp::Eq for NewBlock { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for NewBlock - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "blockHash" => _serde::__private::Ok(__Field::__field0), - "parentBlockHash" => { - _serde::__private::Ok(__Field::__field1) - } - "newRuntime" => _serde::__private::Ok(__Field::__field2), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"blockHash" => _serde::__private::Ok(__Field::__field0), - b"parentBlockHash" => { - _serde::__private::Ok(__Field::__field1) - } - b"newRuntime" => _serde::__private::Ok(__Field::__field2), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = NewBlock; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct NewBlock", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct NewBlock with 3 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct NewBlock with 3 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct NewBlock with 3 elements", - ), - ); - } - }; - _serde::__private::Ok(NewBlock { - block_hash: __field0, - parent_block_hash: __field1, - new_runtime: __field2, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option< - Option, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "blockHash", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "parentBlockHash", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "newRuntime", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("blockHash")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("parentBlockHash")? - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("newRuntime")? - } - }; - _serde::__private::Ok(NewBlock { - block_hash: __field0, - parent_block_hash: __field1, - new_runtime: __field2, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "blockHash", - "parentBlockHash", - "newRuntime", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "NewBlock", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate the block hash of the new best block. - #[serde(rename_all = "camelCase")] - pub struct BestBlockChanged { - /// The block hash of the new best block. - pub best_block_hash: Hash, - } - #[automatically_derived] - impl ::core::fmt::Debug - for BestBlockChanged { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "BestBlockChanged", - "best_block_hash", - &&self.best_block_hash, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for BestBlockChanged { - #[inline] - fn clone(&self) -> BestBlockChanged { - BestBlockChanged { - best_block_hash: ::core::clone::Clone::clone( - &self.best_block_hash, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BestBlockChanged {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for BestBlockChanged { - #[inline] - fn eq(&self, other: &BestBlockChanged) -> bool { - self.best_block_hash == other.best_block_hash - } - } - #[automatically_derived] - impl ::core::cmp::Eq for BestBlockChanged { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for BestBlockChanged - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "bestBlockHash" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"bestBlockHash" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - BestBlockChanged, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = BestBlockChanged; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct BestBlockChanged", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct BestBlockChanged with 1 element", - ), - ); - } - }; - _serde::__private::Ok(BestBlockChanged { - best_block_hash: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "bestBlockHash", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("bestBlockHash")? - } - }; - _serde::__private::Ok(BestBlockChanged { - best_block_hash: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["bestBlockHash"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "BestBlockChanged", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - BestBlockChanged, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate the finalized and pruned block hashes. - #[serde(rename_all = "camelCase")] - pub struct Finalized { - /// Block hashes that are finalized. - pub finalized_block_hashes: Vec, - /// Block hashes that are pruned (removed). - pub pruned_block_hashes: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for Finalized { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Finalized", - "finalized_block_hashes", - &self.finalized_block_hashes, - "pruned_block_hashes", - &&self.pruned_block_hashes, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for Finalized { - #[inline] - fn clone(&self) -> Finalized { - Finalized { - finalized_block_hashes: ::core::clone::Clone::clone( - &self.finalized_block_hashes, - ), - pruned_block_hashes: ::core::clone::Clone::clone( - &self.pruned_block_hashes, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Finalized {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for Finalized { - #[inline] - fn eq(&self, other: &Finalized) -> bool { - self.finalized_block_hashes == other.finalized_block_hashes - && self.pruned_block_hashes == other.pruned_block_hashes - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Finalized { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for Finalized - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "finalizedBlockHashes" => { - _serde::__private::Ok(__Field::__field0) - } - "prunedBlockHashes" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"finalizedBlockHashes" => { - _serde::__private::Ok(__Field::__field0) - } - b"prunedBlockHashes" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = Finalized; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct Finalized", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Finalized with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct Finalized with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(Finalized { - finalized_block_hashes: __field0, - pruned_block_hashes: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option> = _serde::__private::None; - let mut __field1: _serde::__private::Option> = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "finalizedBlockHashes", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "prunedBlockHashes", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field( - "finalizedBlockHashes", - )? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("prunedBlockHashes")? - } - }; - _serde::__private::Ok(Finalized { - finalized_block_hashes: __field0, - pruned_block_hashes: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "finalizedBlockHashes", - "prunedBlockHashes", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Finalized", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate the operation id of the event. - #[serde(rename_all = "camelCase")] - pub struct OperationId { - /// The operation id of the event. - pub operation_id: String, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationId { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "OperationId", - "operation_id", - &&self.operation_id, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationId { - #[inline] - fn clone(&self) -> OperationId { - OperationId { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationId {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationId { - #[inline] - fn eq(&self, other: &OperationId) -> bool { - self.operation_id == other.operation_id - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationId { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationId { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationId; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationId", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationId with 1 element", - ), - ); - } - }; - _serde::__private::Ok(OperationId { - operation_id: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - _serde::__private::Ok(OperationId { - operation_id: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["operationId"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationId", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The response of the `chainHead_body` method. - #[serde(rename_all = "camelCase")] - pub struct OperationBodyDone { - /// The operation id of the event. - pub operation_id: String, - /// Array of hexadecimal-encoded scale-encoded extrinsics found in the block. - pub value: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationBodyDone { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "OperationBodyDone", - "operation_id", - &self.operation_id, - "value", - &&self.value, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationBodyDone { - #[inline] - fn clone(&self) -> OperationBodyDone { - OperationBodyDone { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - value: ::core::clone::Clone::clone(&self.value), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationBodyDone {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationBodyDone { - #[inline] - fn eq(&self, other: &OperationBodyDone) -> bool { - self.operation_id == other.operation_id && self.value == other.value - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationBodyDone { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationBodyDone { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "value" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"value" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationBodyDone; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationBodyDone", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationBodyDone with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct OperationBodyDone with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(OperationBodyDone { - operation_id: __field0, - value: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option> = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("value"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::>(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("value")? - } - }; - _serde::__private::Ok(OperationBodyDone { - operation_id: __field0, - value: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "value", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationBodyDone", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The response of the `chainHead_call` method. - #[serde(rename_all = "camelCase")] - pub struct OperationCallDone { - /// The operation id of the event. - pub operation_id: String, - /// Hexadecimal-encoded output of the runtime function call. - pub output: Bytes, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationCallDone { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "OperationCallDone", - "operation_id", - &self.operation_id, - "output", - &&self.output, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationCallDone { - #[inline] - fn clone(&self) -> OperationCallDone { - OperationCallDone { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - output: ::core::clone::Clone::clone(&self.output), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationCallDone {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationCallDone { - #[inline] - fn eq(&self, other: &OperationCallDone) -> bool { - self.operation_id == other.operation_id - && self.output == other.output - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationCallDone { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationCallDone { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "output" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"output" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationCallDone; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationCallDone", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationCallDone with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Bytes, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct OperationCallDone with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(OperationCallDone { - operation_id: __field0, - output: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("output"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("output")? - } - }; - _serde::__private::Ok(OperationCallDone { - operation_id: __field0, - output: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "output", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationCallDone", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The response of the `chainHead_call` method. - #[serde(rename_all = "camelCase")] - pub struct OperationStorageItems { - /// The operation id of the event. - pub operation_id: String, - /// The resulting items. - pub items: VecDeque, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationStorageItems { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "OperationStorageItems", - "operation_id", - &self.operation_id, - "items", - &&self.items, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationStorageItems { - #[inline] - fn clone(&self) -> OperationStorageItems { - OperationStorageItems { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - items: ::core::clone::Clone::clone(&self.items), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationStorageItems {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationStorageItems { - #[inline] - fn eq(&self, other: &OperationStorageItems) -> bool { - self.operation_id == other.operation_id && self.items == other.items - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationStorageItems { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationStorageItems { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "items" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"items" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData< - OperationStorageItems, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationStorageItems; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationStorageItems", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationStorageItems with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - VecDeque, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct OperationStorageItems with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(OperationStorageItems { - operation_id: __field0, - items: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - VecDeque, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("items"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - VecDeque, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("items")? - } - }; - _serde::__private::Ok(OperationStorageItems { - operation_id: __field0, - items: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "items", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationStorageItems", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - OperationStorageItems, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Indicate a problem during the operation. - #[serde(rename_all = "camelCase")] - pub struct OperationError { - /// The operation id of the event. - pub operation_id: String, - /// The reason of the error. - pub error: String, - } - #[automatically_derived] - impl ::core::fmt::Debug for OperationError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "OperationError", - "operation_id", - &self.operation_id, - "error", - &&self.error, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for OperationError { - #[inline] - fn clone(&self) -> OperationError { - OperationError { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - error: ::core::clone::Clone::clone(&self.error), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for OperationError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for OperationError { - #[inline] - fn eq(&self, other: &OperationError) -> bool { - self.operation_id == other.operation_id && self.error == other.error - } - } - #[automatically_derived] - impl ::core::cmp::Eq for OperationError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for OperationError { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "error" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"error" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = OperationError; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct OperationError", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct OperationError with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct OperationError with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(OperationError { - operation_id: __field0, - error: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(OperationError { - operation_id: __field0, - error: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "error", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "OperationError", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The storage result. - #[serde(rename_all = "camelCase")] - pub struct StorageResult { - /// The hex-encoded key of the result. - pub key: Bytes, - /// The result of the query. - #[serde(flatten)] - pub result: StorageResultType, - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "StorageResult", - "key", - &self.key, - "result", - &&self.result, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageResult { - #[inline] - fn clone(&self) -> StorageResult { - StorageResult { - key: ::core::clone::Clone::clone(&self.key), - result: ::core::clone::Clone::clone(&self.result), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageResult {} - #[automatically_derived] - impl ::core::cmp::PartialEq for StorageResult { - #[inline] - fn eq(&self, other: &StorageResult) -> bool { - self.key == other.key && self.result == other.result - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageResult { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for StorageResult { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field<'de> { - __field0, - __other(_serde::__private::de::Content<'de>), - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field<'de>; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_bool<__E>( - self, - __value: bool, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::Bool(__value), - ), - ) - } - fn visit_i8<__E>( - self, - __value: i8, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I8(__value), - ), - ) - } - fn visit_i16<__E>( - self, - __value: i16, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I16(__value), - ), - ) - } - fn visit_i32<__E>( - self, - __value: i32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I32(__value), - ), - ) - } - fn visit_i64<__E>( - self, - __value: i64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::I64(__value), - ), - ) - } - fn visit_u8<__E>( - self, - __value: u8, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U8(__value), - ), - ) - } - fn visit_u16<__E>( - self, - __value: u16, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U16(__value), - ), - ) - } - fn visit_u32<__E>( - self, - __value: u32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U32(__value), - ), - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::U64(__value), - ), - ) - } - fn visit_f32<__E>( - self, - __value: f32, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::F32(__value), - ), - ) - } - fn visit_f64<__E>( - self, - __value: f64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::F64(__value), - ), - ) - } - fn visit_char<__E>( - self, - __value: char, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other( - _serde::__private::de::Content::Char(__value), - ), - ) - } - fn visit_unit<__E>( - self, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - _serde::__private::Ok( - __Field::__other(_serde::__private::de::Content::Unit), - ) - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "key" => _serde::__private::Ok(__Field::__field0), - _ => { - let __value = _serde::__private::de::Content::String( - _serde::__private::ToString::to_string(__value), - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"key" => _serde::__private::Ok(__Field::__field0), - _ => { - let __value = _serde::__private::de::Content::ByteBuf( - __value.to_vec(), - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_borrowed_str<__E>( - self, - __value: &'de str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "key" => _serde::__private::Ok(__Field::__field0), - _ => { - let __value = _serde::__private::de::Content::Str(__value); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - fn visit_borrowed_bytes<__E>( - self, - __value: &'de [u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"key" => _serde::__private::Ok(__Field::__field0), - _ => { - let __value = _serde::__private::de::Content::Bytes( - __value, - ); - _serde::__private::Ok(__Field::__other(__value)) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field<'de> { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = StorageResult; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct StorageResult", - ) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __collect = _serde::__private::Vec::< - _serde::__private::Option< - ( - _serde::__private::de::Content, - _serde::__private::de::Content, - ), - >, - >::new(); - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("key"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__other(__name) => { - __collect - .push( - _serde::__private::Some(( - __name, - _serde::de::MapAccess::next_value(&mut __map)?, - )), - ); - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("key")? - } - }; - let __field1: StorageResultType = _serde::de::Deserialize::deserialize( - _serde::__private::de::FlatMapDeserializer( - &mut __collect, - _serde::__private::PhantomData, - ), - )?; - _serde::__private::Ok(StorageResult { - key: __field0, - result: __field1, - }) - } - } - _serde::Deserializer::deserialize_map( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The type of the storage query. - #[serde(rename_all = "camelCase")] - pub enum StorageResultType { - /// Fetch the value of the provided key. - Value(Bytes), - /// Fetch the hash of the value of the provided key. - Hash(Bytes), - /// Fetch the closest descendant merkle value. - ClosestDescendantMerkleValue(Bytes), - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageResultType { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - StorageResultType::Value(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Value", - &__self_0, - ) - } - StorageResultType::Hash(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Hash", - &__self_0, - ) - } - StorageResultType::ClosestDescendantMerkleValue(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ClosestDescendantMerkleValue", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageResultType { - #[inline] - fn clone(&self) -> StorageResultType { - match self { - StorageResultType::Value(__self_0) => { - StorageResultType::Value( - ::core::clone::Clone::clone(__self_0), - ) - } - StorageResultType::Hash(__self_0) => { - StorageResultType::Hash( - ::core::clone::Clone::clone(__self_0), - ) - } - StorageResultType::ClosestDescendantMerkleValue(__self_0) => { - StorageResultType::ClosestDescendantMerkleValue( - ::core::clone::Clone::clone(__self_0), - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageResultType {} - #[automatically_derived] - impl ::core::cmp::PartialEq for StorageResultType { - #[inline] - fn eq(&self, other: &StorageResultType) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - StorageResultType::Value(__self_0), - StorageResultType::Value(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - StorageResultType::Hash(__self_0), - StorageResultType::Hash(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - StorageResultType::ClosestDescendantMerkleValue(__self_0), - StorageResultType::ClosestDescendantMerkleValue(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageResultType { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for StorageResultType { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 3", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "value" => _serde::__private::Ok(__Field::__field0), - "hash" => _serde::__private::Ok(__Field::__field1), - "closestDescendantMerkleValue" => { - _serde::__private::Ok(__Field::__field2) - } - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"value" => _serde::__private::Ok(__Field::__field0), - b"hash" => _serde::__private::Ok(__Field::__field1), - b"closestDescendantMerkleValue" => { - _serde::__private::Ok(__Field::__field2) - } - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = StorageResultType; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "enum StorageResultType", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Bytes, - >(__variant), - StorageResultType::Value, - ) - } - (__Field::__field1, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Bytes, - >(__variant), - StorageResultType::Hash, - ) - } - (__Field::__field2, __variant) => { - _serde::__private::Result::map( - _serde::de::VariantAccess::newtype_variant::< - Bytes, - >(__variant), - StorageResultType::ClosestDescendantMerkleValue, - ) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "value", - "hash", - "closestDescendantMerkleValue", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "StorageResultType", - VARIANTS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The method response of `chainHead_body`, `chainHead_call` and `chainHead_storage`. - #[serde(rename_all = "camelCase")] - #[serde(tag = "result")] - pub enum MethodResponse { - /// The method has started. - Started(MethodResponseStarted), - /// The RPC server cannot handle the request at the moment. - LimitReached, - } - #[automatically_derived] - impl ::core::fmt::Debug for MethodResponse { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - MethodResponse::Started(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Started", - &__self_0, - ) - } - MethodResponse::LimitReached => { - ::core::fmt::Formatter::write_str(f, "LimitReached") - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for MethodResponse { - #[inline] - fn clone(&self) -> MethodResponse { - match self { - MethodResponse::Started(__self_0) => { - MethodResponse::Started( - ::core::clone::Clone::clone(__self_0), - ) - } - MethodResponse::LimitReached => MethodResponse::LimitReached, - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for MethodResponse {} - #[automatically_derived] - impl ::core::cmp::PartialEq for MethodResponse { - #[inline] - fn eq(&self, other: &MethodResponse) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - MethodResponse::Started(__self_0), - MethodResponse::Started(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for MethodResponse { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for MethodResponse { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "started" => _serde::__private::Ok(__Field::__field0), - "limitReached" => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"started" => _serde::__private::Ok(__Field::__field0), - b"limitReached" => _serde::__private::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "started", - "limitReached", - ]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::TaggedContentVisitor::< - __Field, - >::new("result", "internally tagged enum MethodResponse"), - )?; - let __deserializer = _serde::__private::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::__private::Result::map( - ::deserialize( - __deserializer, - ), - MethodResponse::Started, - ) - } - __Field::__field1 => { - _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::InternallyTaggedUnitVisitor::new( - "MethodResponse", - "LimitReached", - ), - )?; - _serde::__private::Ok(MethodResponse::LimitReached) - } - } - } - } - }; - /// The `started` result of a method. - #[serde(rename_all = "camelCase")] - pub struct MethodResponseStarted { - /// The operation id of the response. - pub operation_id: String, - /// The number of items from the back of the `chainHead_storage` that have been discarded. - pub discarded_items: Option, - } - #[automatically_derived] - impl ::core::fmt::Debug for MethodResponseStarted { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "MethodResponseStarted", - "operation_id", - &self.operation_id, - "discarded_items", - &&self.discarded_items, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for MethodResponseStarted { - #[inline] - fn clone(&self) -> MethodResponseStarted { - MethodResponseStarted { - operation_id: ::core::clone::Clone::clone(&self.operation_id), - discarded_items: ::core::clone::Clone::clone( - &self.discarded_items, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for MethodResponseStarted {} - #[automatically_derived] - impl ::core::cmp::PartialEq for MethodResponseStarted { - #[inline] - fn eq(&self, other: &MethodResponseStarted) -> bool { - self.operation_id == other.operation_id - && self.discarded_items == other.discarded_items - } - } - #[automatically_derived] - impl ::core::cmp::Eq for MethodResponseStarted { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for MethodResponseStarted { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "operationId" => _serde::__private::Ok(__Field::__field0), - "discardedItems" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"operationId" => _serde::__private::Ok(__Field::__field0), - b"discardedItems" => { - _serde::__private::Ok(__Field::__field1) - } - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData< - MethodResponseStarted, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = MethodResponseStarted; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct MethodResponseStarted", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct MethodResponseStarted with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - Option, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct MethodResponseStarted with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(MethodResponseStarted { - operation_id: __field0, - discarded_items: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - Option, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "operationId", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "discardedItems", - ), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("operationId")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("discardedItems")? - } - }; - _serde::__private::Ok(MethodResponseStarted { - operation_id: __field0, - discarded_items: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "operationId", - "discardedItems", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "MethodResponseStarted", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - MethodResponseStarted, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The storage item received as parameter. - #[serde(rename_all = "camelCase")] - pub struct StorageQuery { - /// The provided key. - pub key: Key, - /// The type of the storage query. - #[serde(rename = "type")] - pub query_type: StorageQueryType, - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageQuery { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "StorageQuery", - "key", - &self.key, - "query_type", - &&self.query_type, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageQuery { - #[inline] - fn clone(&self) -> StorageQuery { - StorageQuery { - key: ::core::clone::Clone::clone(&self.key), - query_type: ::core::clone::Clone::clone(&self.query_type), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageQuery {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for StorageQuery { - #[inline] - fn eq(&self, other: &StorageQuery) -> bool { - self.key == other.key && self.query_type == other.query_type - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageQuery { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for StorageQuery - where - Key: _serde::Serialize, - { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "StorageQuery", - false as usize + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "key", - &self.key, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "type", - &self.query_type, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Key> _serde::Deserialize<'de> for StorageQuery - where - Key: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "key" => _serde::__private::Ok(__Field::__field0), - "type" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"key" => _serde::__private::Ok(__Field::__field0), - b"type" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Key> - where - Key: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Key> _serde::de::Visitor<'de> for __Visitor<'de, Key> - where - Key: _serde::Deserialize<'de>, - { - type Value = StorageQuery; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct StorageQuery", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Key, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct StorageQuery with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - StorageQueryType, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct StorageQuery with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(StorageQuery { - key: __field0, - query_type: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option< - StorageQueryType, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("key"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("type"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - StorageQueryType, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("key")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("type")? - } - }; - _serde::__private::Ok(StorageQuery { - key: __field0, - query_type: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["key", "type"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "StorageQuery", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::>, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// The type of the storage query. - #[serde(rename_all = "camelCase")] - pub enum StorageQueryType { - /// Fetch the value of the provided key. - Value, - /// Fetch the hash of the value of the provided key. - Hash, - /// Fetch the closest descendant merkle value. - ClosestDescendantMerkleValue, - /// Fetch the values of all descendants of they provided key. - DescendantsValues, - /// Fetch the hashes of the values of all descendants of they provided key. - DescendantsHashes, - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageQueryType { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - StorageQueryType::Value => "Value", - StorageQueryType::Hash => "Hash", - StorageQueryType::ClosestDescendantMerkleValue => { - "ClosestDescendantMerkleValue" - } - StorageQueryType::DescendantsValues => "DescendantsValues", - StorageQueryType::DescendantsHashes => "DescendantsHashes", - }, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for StorageQueryType { - #[inline] - fn clone(&self) -> StorageQueryType { - match self { - StorageQueryType::Value => StorageQueryType::Value, - StorageQueryType::Hash => StorageQueryType::Hash, - StorageQueryType::ClosestDescendantMerkleValue => { - StorageQueryType::ClosestDescendantMerkleValue - } - StorageQueryType::DescendantsValues => { - StorageQueryType::DescendantsValues - } - StorageQueryType::DescendantsHashes => { - StorageQueryType::DescendantsHashes - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for StorageQueryType {} - #[automatically_derived] - impl ::core::cmp::PartialEq for StorageQueryType { - #[inline] - fn eq(&self, other: &StorageQueryType) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - impl ::core::cmp::Eq for StorageQueryType { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for StorageQueryType { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - StorageQueryType::Value => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 0u32, - "value", - ) - } - StorageQueryType::Hash => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 1u32, - "hash", - ) - } - StorageQueryType::ClosestDescendantMerkleValue => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 2u32, - "closestDescendantMerkleValue", - ) - } - StorageQueryType::DescendantsValues => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 3u32, - "descendantsValues", - ) - } - StorageQueryType::DescendantsHashes => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "StorageQueryType", - 4u32, - "descendantsHashes", - ) - } - } - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for StorageQueryType { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 5", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "value" => _serde::__private::Ok(__Field::__field0), - "hash" => _serde::__private::Ok(__Field::__field1), - "closestDescendantMerkleValue" => { - _serde::__private::Ok(__Field::__field2) - } - "descendantsValues" => { - _serde::__private::Ok(__Field::__field3) - } - "descendantsHashes" => { - _serde::__private::Ok(__Field::__field4) - } - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"value" => _serde::__private::Ok(__Field::__field0), - b"hash" => _serde::__private::Ok(__Field::__field1), - b"closestDescendantMerkleValue" => { - _serde::__private::Ok(__Field::__field2) - } - b"descendantsValues" => { - _serde::__private::Ok(__Field::__field3) - } - b"descendantsHashes" => { - _serde::__private::Ok(__Field::__field4) - } - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = StorageQueryType; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "enum StorageQueryType", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(StorageQueryType::Value) - } - (__Field::__field1, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(StorageQueryType::Hash) - } - (__Field::__field2, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok( - StorageQueryType::ClosestDescendantMerkleValue, - ) - } - (__Field::__field3, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(StorageQueryType::DescendantsValues) - } - (__Field::__field4, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(StorageQueryType::DescendantsHashes) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "value", - "hash", - "closestDescendantMerkleValue", - "descendantsValues", - "descendantsHashes", - ]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "StorageQueryType", - VARIANTS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// A subscription which returns follow events, and ends when a Stop event occurs. - pub struct FollowSubscription { - sub: RpcSubscription>, - done: bool, - } - impl FollowSubscription { - /// Fetch the next item in the stream. - pub async fn next(&mut self) -> Option<::Item> { - ::next(self).await - } - /// Fetch the subscription ID for the stream. - pub fn subscription_id(&self) -> Option<&str> { - self.sub.subscription_id() - } - } - impl Stream for FollowSubscription { - type Item = > as Stream>::Item; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - if self.done { - return Poll::Ready(None); - } - let res = self.sub.poll_next_unpin(cx); - if let Poll::Ready(Some(Ok(FollowEvent::Stop))) = &res { - self.done = true; - } - res - } - } - /// A subscription which returns transaction status events, stopping - /// when no more events will be sent. - pub struct TransactionSubscription { - sub: RpcSubscription>, - done: bool, - } - impl TransactionSubscription { - /// Fetch the next item in the stream. - pub async fn next(&mut self) -> Option<::Item> { - ::next(self).await - } - } - impl Stream for TransactionSubscription { - type Item = > as Stream>::Item; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - if self.done { - return Poll::Ready(None); - } - let res = self.sub.poll_next_unpin(cx); - if let Poll::Ready(Some(Ok(res))) = &res { - if match res { - TransactionStatus::Dropped { .. } - | TransactionStatus::Error { .. } - | TransactionStatus::Invalid { .. } - | TransactionStatus::Finalized { .. } => true, - _ => false, - } { - self.done = true; - } - } - res - } - } - /// Transaction progress events - #[serde(rename_all = "camelCase")] - #[serde(tag = "event")] - pub enum TransactionStatus { - /// Transaction is part of the future queue. - Validated, - /// The transaction has been broadcast to other nodes. - Broadcasted { - /// Number of peers it's been broadcast to. - num_peers: u32, - }, - /// Transaction has been included in block with given details. - /// Null is returned if the transaction is no longer in any block - /// of the best chain. - BestChainBlockIncluded { - /// Details of the block it's been seen in. - block: Option>, - }, - /// The transaction is in a block that's been finalized. - Finalized { - /// Details of the block it's been seen in. - block: TransactionBlockDetails, - }, - /// Something went wrong in the node. - Error { - /// Human readable message; what went wrong. - error: String, - }, - /// Transaction is invalid (bad nonce, signature etc). - Invalid { - /// Human readable message; why was it invalid. - error: String, - }, - /// The transaction was dropped. - Dropped { - /// Was the transaction broadcasted to other nodes before being dropped? - broadcasted: bool, - /// Human readable message; why was it dropped. - error: String, - }, - } - #[automatically_derived] - impl ::core::fmt::Debug - for TransactionStatus { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionStatus::Validated => { - ::core::fmt::Formatter::write_str(f, "Validated") - } - TransactionStatus::Broadcasted { num_peers: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Broadcasted", - "num_peers", - &__self_0, - ) - } - TransactionStatus::BestChainBlockIncluded { block: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "BestChainBlockIncluded", - "block", - &__self_0, - ) - } - TransactionStatus::Finalized { block: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Finalized", - "block", - &__self_0, - ) - } - TransactionStatus::Error { error: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Error", - "error", - &__self_0, - ) - } - TransactionStatus::Invalid { error: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Invalid", - "error", - &__self_0, - ) - } - TransactionStatus::Dropped { - broadcasted: __self_0, - error: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Dropped", - "broadcasted", - __self_0, - "error", - &__self_1, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone - for TransactionStatus { - #[inline] - fn clone(&self) -> TransactionStatus { - match self { - TransactionStatus::Validated => TransactionStatus::Validated, - TransactionStatus::Broadcasted { num_peers: __self_0 } => { - TransactionStatus::Broadcasted { - num_peers: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::BestChainBlockIncluded { block: __self_0 } => { - TransactionStatus::BestChainBlockIncluded { - block: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Finalized { block: __self_0 } => { - TransactionStatus::Finalized { - block: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Error { error: __self_0 } => { - TransactionStatus::Error { - error: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Invalid { error: __self_0 } => { - TransactionStatus::Invalid { - error: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Dropped { - broadcasted: __self_0, - error: __self_1, - } => { - TransactionStatus::Dropped { - broadcasted: ::core::clone::Clone::clone(__self_0), - error: ::core::clone::Clone::clone(__self_1), - } - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionStatus {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for TransactionStatus { - #[inline] - fn eq(&self, other: &TransactionStatus) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionStatus::Broadcasted { num_peers: __self_0 }, - TransactionStatus::Broadcasted { num_peers: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::BestChainBlockIncluded { - block: __self_0, - }, - TransactionStatus::BestChainBlockIncluded { - block: __arg1_0, - }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Finalized { block: __self_0 }, - TransactionStatus::Finalized { block: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Error { error: __self_0 }, - TransactionStatus::Error { error: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Invalid { error: __self_0 }, - TransactionStatus::Invalid { error: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Dropped { - broadcasted: __self_0, - error: __self_1, - }, - TransactionStatus::Dropped { - broadcasted: __arg1_0, - error: __arg1_1, - }, - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TransactionStatus { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq< - Option>, - >; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> for TransactionStatus - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __field5, - __field6, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - 5u64 => _serde::__private::Ok(__Field::__field5), - 6u64 => _serde::__private::Ok(__Field::__field6), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 7", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "validated" => _serde::__private::Ok(__Field::__field0), - "broadcasted" => _serde::__private::Ok(__Field::__field1), - "bestChainBlockIncluded" => { - _serde::__private::Ok(__Field::__field2) - } - "finalized" => _serde::__private::Ok(__Field::__field3), - "error" => _serde::__private::Ok(__Field::__field4), - "invalid" => _serde::__private::Ok(__Field::__field5), - "dropped" => _serde::__private::Ok(__Field::__field6), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"validated" => _serde::__private::Ok(__Field::__field0), - b"broadcasted" => _serde::__private::Ok(__Field::__field1), - b"bestChainBlockIncluded" => { - _serde::__private::Ok(__Field::__field2) - } - b"finalized" => _serde::__private::Ok(__Field::__field3), - b"error" => _serde::__private::Ok(__Field::__field4), - b"invalid" => _serde::__private::Ok(__Field::__field5), - b"dropped" => _serde::__private::Ok(__Field::__field6), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &[ - "validated", - "broadcasted", - "bestChainBlockIncluded", - "finalized", - "error", - "invalid", - "dropped", - ]; - let (__tag, __content) = _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::TaggedContentVisitor::< - __Field, - >::new("event", "internally tagged enum TransactionStatus"), - )?; - let __deserializer = _serde::__private::de::ContentDeserializer::< - __D::Error, - >::new(__content); - match __tag { - __Field::__field0 => { - _serde::Deserializer::deserialize_any( - __deserializer, - _serde::__private::de::InternallyTaggedUnitVisitor::new( - "TransactionStatus", - "Validated", - ), - )?; - _serde::__private::Ok(TransactionStatus::Validated) - } - __Field::__field1 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "num_peers" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"num_peers" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Broadcasted", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u32, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Broadcasted with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Broadcasted { - num_peers: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "num_peers", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("num_peers")? - } - }; - _serde::__private::Ok(TransactionStatus::Broadcasted { - num_peers: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["num_peers"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field2 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "block" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"block" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::BestChainBlockIncluded", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Option>, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::BestChainBlockIncluded with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::BestChainBlockIncluded { - block: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option< - Option>, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("block"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Option>, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("block")? - } - }; - _serde::__private::Ok(TransactionStatus::BestChainBlockIncluded { - block: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["block"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field3 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "block" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"block" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Finalized", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - TransactionBlockDetails, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Finalized with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Finalized { - block: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option< - TransactionBlockDetails, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("block"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - TransactionBlockDetails, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("block")? - } - }; - _serde::__private::Ok(TransactionStatus::Finalized { - block: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["block"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field4 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Error", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Error with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Error { - error: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(TransactionStatus::Error { - error: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["error"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field5 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"error" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Invalid", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Invalid with 1 element", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Invalid { - error: __field0, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(TransactionStatus::Invalid { - error: __field0, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["error"]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - __Field::__field6 => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "broadcasted" => _serde::__private::Ok(__Field::__field0), - "error" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"broadcasted" => _serde::__private::Ok(__Field::__field0), - b"error" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> - for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionStatus; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant TransactionStatus::Dropped", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - bool, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant TransactionStatus::Dropped with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - String, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct variant TransactionStatus::Dropped with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(TransactionStatus::Dropped { - broadcasted: __field0, - error: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "broadcasted", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("error"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("broadcasted")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("error")? - } - }; - _serde::__private::Ok(TransactionStatus::Dropped { - broadcasted: __field0, - error: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "broadcasted", - "error", - ]; - _serde::Deserializer::deserialize_any( - __deserializer, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionStatus, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - } - } - }; - /// Details of a block that a transaction is seen in. - pub struct TransactionBlockDetails { - /// The block hash. - pub hash: Hash, - /// The index of the transaction in the block. - #[serde(with = "unsigned_number_as_string")] - pub index: u64, - } - #[automatically_derived] - impl ::core::fmt::Debug - for TransactionBlockDetails { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "TransactionBlockDetails", - "hash", - &self.hash, - "index", - &&self.index, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for TransactionBlockDetails { - #[inline] - fn clone(&self) -> TransactionBlockDetails { - TransactionBlockDetails { - hash: ::core::clone::Clone::clone(&self.hash), - index: ::core::clone::Clone::clone(&self.index), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for TransactionBlockDetails {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for TransactionBlockDetails { - #[inline] - fn eq(&self, other: &TransactionBlockDetails) -> bool { - self.hash == other.hash && self.index == other.index - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for TransactionBlockDetails { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de, Hash> _serde::Deserialize<'de> - for TransactionBlockDetails - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "hash" => _serde::__private::Ok(__Field::__field0), - "index" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"hash" => _serde::__private::Ok(__Field::__field0), - b"index" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData< - TransactionBlockDetails, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::de::Visitor<'de> for __Visitor<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - type Value = TransactionBlockDetails; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct TransactionBlockDetails", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Hash, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct TransactionBlockDetails with 2 elements", - ), - ); - } - }; - let __field1 = match { - #[doc(hidden)] - struct __DeserializeWith<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - value: u64, - phantom: _serde::__private::PhantomData< - TransactionBlockDetails, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::Deserialize<'de> - for __DeserializeWith<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: unsigned_number_as_string::deserialize( - __deserializer, - )?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de, Hash>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct TransactionBlockDetails with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(TransactionBlockDetails { - hash: __field0, - index: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("hash"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("index"), - ); - } - __field1 = _serde::__private::Some({ - #[doc(hidden)] - struct __DeserializeWith<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - value: u64, - phantom: _serde::__private::PhantomData< - TransactionBlockDetails, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de, Hash> _serde::Deserialize<'de> - for __DeserializeWith<'de, Hash> - where - Hash: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: unsigned_number_as_string::deserialize( - __deserializer, - )?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - match _serde::de::MapAccess::next_value::< - __DeserializeWith<'de, Hash>, - >(&mut __map) { - _serde::__private::Ok(__wrapper) => __wrapper.value, - _serde::__private::Err(__err) => { - return _serde::__private::Err(__err); - } - } - }); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("hash")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::missing_field("index"), - ); - } - }; - _serde::__private::Ok(TransactionBlockDetails { - hash: __field0, - index: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["hash", "index"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "TransactionBlockDetails", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - TransactionBlockDetails, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - /// Hex-serialized shim for `Vec`. - pub struct Bytes(#[serde(with = "impl_serde::serialize")] pub Vec); - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Bytes {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Bytes { - #[inline] - fn eq(&self, other: &Bytes) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Bytes { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Bytes { - #[inline] - fn clone(&self) -> Bytes { - Bytes(::core::clone::Clone::clone(&self.0)) - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Bytes { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - _serde::Serializer::serialize_newtype_struct( - __serializer, - "Bytes", - { - #[doc(hidden)] - struct __SerializeWith<'__a> { - values: (&'__a Vec,), - phantom: _serde::__private::PhantomData, - } - impl<'__a> _serde::Serialize for __SerializeWith<'__a> { - fn serialize<__S>( - &self, - __s: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - impl_serde::serialize::serialize(self.values.0, __s) - } - } - &__SerializeWith { - values: (&self.0,), - phantom: _serde::__private::PhantomData::, - } - }, - ) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Bytes { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Bytes; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "tuple struct Bytes", - ) - } - #[inline] - fn visit_newtype_struct<__E>( - self, - __e: __E, - ) -> _serde::__private::Result - where - __E: _serde::Deserializer<'de>, - { - let __field0: Vec = impl_serde::serialize::deserialize( - __e, - )?; - _serde::__private::Ok(Bytes(__field0)) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match { - #[doc(hidden)] - struct __DeserializeWith<'de> { - value: Vec, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::Deserialize<'de> - for __DeserializeWith<'de> { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: impl_serde::serialize::deserialize(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"tuple struct Bytes with 1 element", - ), - ); - } - }; - _serde::__private::Ok(Bytes(__field0)) - } - } - _serde::Deserializer::deserialize_newtype_struct( - __deserializer, - "Bytes", - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::hash::Hash for Bytes { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Bytes { - #[inline] - fn partial_cmp( - &self, - other: &Bytes, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Bytes { - #[inline] - fn cmp(&self, other: &Bytes) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Bytes { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Bytes", - &&self.0, - ) - } - } - impl std::ops::Deref for Bytes { - type Target = [u8]; - fn deref(&self) -> &[u8] { - &self.0[..] - } - } - impl From> for Bytes { - fn from(s: Vec) -> Self { - Bytes(s) - } - } - fn to_hex(bytes: impl AsRef<[u8]>) -> String { - { - let res = ::alloc::fmt::format( - format_args!("0x{0}", hex::encode(bytes.as_ref())), - ); - res - } - } - /// Attempt to deserialize either a string or integer into an integer. - /// See - pub(crate) mod unsigned_number_as_string { - use serde::de::{Deserializer, Visitor}; - use std::fmt; - /// Deserialize a number from a string or number. - pub fn deserialize<'de, N: From, D>( - deserializer: D, - ) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_any(NumberVisitor(std::marker::PhantomData)) - } - struct NumberVisitor(std::marker::PhantomData); - impl<'de, N: From> Visitor<'de> for NumberVisitor { - type Value = N; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter - .write_str("an unsigned integer or a string containing one") - } - fn visit_str( - self, - v: &str, - ) -> Result { - let n: u64 = v.parse().map_err(serde::de::Error::custom)?; - Ok(n.into()) - } - fn visit_u64( - self, - v: u64, - ) -> Result { - Ok(v.into()) - } - } - } - /// A temporary shim to decode "spec.apis" if it comes back as an array like: - /// - /// ```text - /// [["0xABC", 1], ["0xCDE", 2]] - /// ``` - /// - /// The expected format (which this also supports deserializing from) is: - /// - /// ```text - /// { "0xABC": 1, "0xCDE": 2 } - /// ``` - /// - /// We can delete this when the correct format is being returned. - /// - /// Adapted from - pub(crate) mod hashmap_as_tuple_list { - use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; - use std::collections::HashMap; - use std::fmt; - use std::hash::{BuildHasher, Hash}; - use std::marker::PhantomData; - /// Deserialize a [`HashMap`] from a list of tuples or object - pub fn deserialize<'de, K, V, BH, D>( - deserializer: D, - ) -> Result, D::Error> - where - D: Deserializer<'de>, - K: Eq + Hash + Deserialize<'de>, - V: Deserialize<'de>, - BH: BuildHasher + Default, - { - deserializer.deserialize_any(HashMapVisitor(PhantomData)) - } - #[allow(clippy::type_complexity)] - struct HashMapVisitor(PhantomData HashMap>); - impl<'de, K, V, BH> Visitor<'de> for HashMapVisitor - where - K: Deserialize<'de> + Eq + Hash, - V: Deserialize<'de>, - BH: BuildHasher + Default, - { - type Value = HashMap; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a list of key-value pairs") - } - fn visit_map(self, mut m: A) -> Result - where - A: serde::de::MapAccess<'de>, - { - let mut map = HashMap::with_capacity_and_hasher( - m.size_hint().unwrap_or(0), - BH::default(), - ); - while let Some((key, value)) = m.next_entry()? { - map.insert(key, value); - } - Ok(map) - } - fn visit_seq(self, mut seq: A) -> Result - where - A: SeqAccess<'de>, - { - let mut map = HashMap::with_capacity_and_hasher( - seq.size_hint().unwrap_or(0), - BH::default(), - ); - while let Some((key, value)) = seq.next_element()? { - map.insert(key, value); - } - Ok(map) - } - } - } - } - use self::rpc_methods::{ - FollowEvent, MethodResponse, RuntimeEvent, StorageQuery, StorageQueryType, - StorageResultType, - }; - use crate::backend::{ - rpc::RpcClient, Backend, BlockRef, BlockRefT, RuntimeVersion, - StorageResponse, StreamOf, StreamOfResults, TransactionStatus, - }; - use crate::config::BlockHash; - use crate::error::{Error, RpcError}; - use crate::Config; - use async_trait::async_trait; - use follow_stream_driver::{FollowStreamDriver, FollowStreamDriverHandle}; - use futures::{Stream, StreamExt}; - use std::collections::HashMap; - use std::sync::Arc; - use std::task::Poll; - use storage_items::StorageItems; - pub use rpc_methods::UnstableRpcMethods; - /// Configure and build an [`UnstableBackend`]. - pub struct UnstableBackendBuilder { - max_block_life: usize, - _marker: std::marker::PhantomData, - } - impl Default for UnstableBackendBuilder { - fn default() -> Self { - Self::new() - } - } - impl UnstableBackendBuilder { - /// Create a new [`UnstableBackendBuilder`]. - pub fn new() -> Self { - Self { - max_block_life: usize::MAX, - _marker: std::marker::PhantomData, - } - } - /// The age of a block is defined here as the difference between the current finalized block number - /// and the block number of a given block. Once the difference equals or exceeds the number given - /// here, the block is unpinned. - /// - /// By default, we will never automatically unpin blocks, but if the number of pinned blocks that we - /// keep hold of exceeds the number that the server can tolerate, then a `stop` event is generated and - /// we are forced to resubscribe, losing any pinned blocks. - pub fn max_block_life(mut self, max_block_life: usize) -> Self { - self.max_block_life = max_block_life; - self - } - /// Given an [`RpcClient`] to use to make requests, this returns a tuple of an [`UnstableBackend`], - /// which implements the [`Backend`] trait, and an [`UnstableBackendDriver`] which must be polled in - /// order for the backend to make progress. - pub fn build( - self, - client: RpcClient, - ) -> (UnstableBackend, UnstableBackendDriver) { - let rpc_methods = UnstableRpcMethods::new(client); - let follow_stream = follow_stream::FollowStream::< - T::Hash, - >::from_methods(rpc_methods.clone()); - let follow_stream_unpin = follow_stream_unpin::FollowStreamUnpin::< - T::Hash, - >::from_methods(follow_stream, rpc_methods.clone(), self.max_block_life); - let follow_stream_driver = FollowStreamDriver::new(follow_stream_unpin); - let backend = UnstableBackend { - methods: rpc_methods, - follow_handle: follow_stream_driver.handle(), - }; - let driver = UnstableBackendDriver { - driver: follow_stream_driver, - }; - (backend, driver) - } - } - /// Driver for the [`UnstableBackend`]. This must be polled in order for the - /// backend to make progress. - pub struct UnstableBackendDriver { - driver: FollowStreamDriver, - } - #[automatically_derived] - impl ::core::fmt::Debug - for UnstableBackendDriver - where - T::Hash: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "UnstableBackendDriver", - "driver", - &&self.driver, - ) - } - } - impl Stream for UnstableBackendDriver { - type Item = as Stream>::Item; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - self.driver.poll_next_unpin(cx) - } - } - /// The unstable backend. - pub struct UnstableBackend { - methods: UnstableRpcMethods, - follow_handle: FollowStreamDriverHandle, - } - #[automatically_derived] - impl ::core::fmt::Debug for UnstableBackend - where - T::Hash: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "UnstableBackend", - "methods", - &self.methods, - "follow_handle", - &&self.follow_handle, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone - for UnstableBackend - where - T::Hash: ::core::clone::Clone, - { - #[inline] - fn clone(&self) -> UnstableBackend { - UnstableBackend { - methods: ::core::clone::Clone::clone(&self.methods), - follow_handle: ::core::clone::Clone::clone(&self.follow_handle), - } - } - } - impl UnstableBackend { - /// Configure and construct an [`UnstableBackend`] and the associated [`UnstableBackendDriver`]. - pub fn builder() -> UnstableBackendBuilder { - UnstableBackendBuilder::new() - } - /// Stream block headers based on the provided filter fn - async fn stream_headers( - &self, - f: F, - ) -> Result)>, Error> - where - F: Fn(FollowEvent>) -> I + Copy - + Send + 'static, - I: IntoIterator> + Send - + 'static, - ::IntoIter: Send, - { - let sub_id = get_subscription_id(&self.follow_handle).await?; - let sub_id = Arc::new(sub_id); - let methods = self.methods.clone(); - let headers = self - .follow_handle - .subscribe() - .events() - .flat_map(move |ev| { - let sub_id = sub_id.clone(); - let methods = methods.clone(); - let block_refs = f(ev).into_iter(); - futures::stream::iter(block_refs) - .filter_map(move |block_ref| { - let sub_id = sub_id.clone(); - let methods = methods.clone(); - async move { - let res = methods - .chainhead_unstable_header(&sub_id, block_ref.hash()) - .await - .transpose()?; - let header = match res { - Ok(header) => header, - Err(e) => return Some(Err(e)), - }; - Some(Ok((header, block_ref.into()))) - } - }) - }); - Ok(StreamOf(Box::pin(headers))) - } - } - impl BlockRefT - for follow_stream_unpin::BlockRef {} - impl From> - for BlockRef { - fn from(b: follow_stream_unpin::BlockRef) -> Self { - BlockRef::new(b.hash(), b) - } - } - impl super::sealed::Sealed for UnstableBackend {} - impl Backend for UnstableBackend { - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_values<'life0, 'async_trait>( - &'life0 self, - keys: Vec>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let keys = keys; - let at = at; - let __ret: Result, Error> = { - let queries = keys - .iter() - .map(|key| StorageQuery { - key: &**key, - query_type: StorageQueryType::Value, - }); - let storage_items = StorageItems::from_methods( - queries, - at, - &__self.follow_handle, - __self.methods.clone(), - ) - .await?; - let storage_result_stream = storage_items - .filter_map(|val| async move { - let val = match val { - Ok(val) => val, - Err(e) => return Some(Err(e)), - }; - let StorageResultType::Value(result) = val.result else { - return None; - }; - Some( - Ok(StorageResponse { - key: val.key.0, - value: result.0, - }), - ) - }); - Ok(StreamOf(Box::pin(storage_result_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_descendant_keys<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>, Error>, - > { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result>, Error> = { - let query = StorageQuery { - key: &*key, - query_type: StorageQueryType::DescendantsHashes, - }; - let storage_items = StorageItems::from_methods( - std::iter::once(query), - at, - &__self.follow_handle, - __self.methods.clone(), - ) - .await?; - let storage_result_stream = storage_items - .map(|val| val.map(|v| v.key.0)); - Ok(StreamOf(Box::pin(storage_result_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_descendant_values<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result, Error> = { - let query = StorageQuery { - key: &*key, - query_type: StorageQueryType::DescendantsValues, - }; - let storage_items = StorageItems::from_methods( - std::iter::once(query), - at, - &__self.follow_handle, - __self.methods.clone(), - ) - .await?; - let storage_result_stream = storage_items - .filter_map(|val| async move { - let val = match val { - Ok(val) => val, - Err(e) => return Some(Err(e)), - }; - let StorageResultType::Value(result) = val.result else { - return None; - }; - Some( - Ok(StorageResponse { - key: val.key.0, - value: result.0, - }), - ) - }); - Ok(StreamOf(Box::pin(storage_result_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn genesis_hash<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let __ret: Result = { - __self.methods.chainspec_v1_genesis_hash().await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn block_header<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result, Error> = { - let sub_id = get_subscription_id(&__self.follow_handle).await?; - __self.methods.chainhead_unstable_header(&sub_id, at).await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn block_body<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>>, Error>, - > { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result>>, Error> = { - let sub_id = get_subscription_id(&__self.follow_handle).await?; - let follow_events = __self.follow_handle.subscribe().events(); - let status = __self - .methods - .chainhead_unstable_body(&sub_id, at) - .await?; - let operation_id = match status { - MethodResponse::LimitReached => { - return Err( - RpcError::request_rejected("limit reached").into(), - ); - } - MethodResponse::Started(s) => s.operation_id, - }; - let mut exts_stream = follow_events - .filter_map(|ev| { - let FollowEvent::OperationBodyDone(body) = ev else { - return std::future::ready(None); - }; - if body.operation_id != operation_id { - return std::future::ready(None); - } - let exts: Vec<_> = body - .value - .into_iter() - .map(|ext| ext.0) - .collect(); - std::future::ready(Some(exts)) - }); - Ok(exts_stream.next().await) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn latest_finalized_block_ref<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result, Error> = { - let next_ref: Option> = __self - .follow_handle - .subscribe() - .events() - .filter_map(|ev| { - let out = match ev { - FollowEvent::Initialized(init) => { - Some(init.finalized_block_hash.into()) - } - _ => None, - }; - std::future::ready(out) - }) - .next() - .await; - next_ref.ok_or_else(|| RpcError::SubscriptionDropped.into()) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn current_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let __ret: Result = { - let runtime_version = __self - .stream_runtime_version() - .await? - .next() - .await; - match runtime_version { - None => Err(Error::Rpc(RpcError::SubscriptionDropped)), - Some(Err(e)) => Err(e), - Some(Ok(version)) => Ok(version), - } - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result, Error> = { - let mut runtimes = HashMap::new(); - let runtime_stream = __self - .follow_handle - .subscribe() - .events() - .filter_map(move |ev| { - let output = match ev { - FollowEvent::Initialized(ev) => { - runtimes.remove(&ev.finalized_block_hash.hash()); - ev.finalized_block_runtime - } - FollowEvent::NewBlock(ev) => { - if let Some(runtime) = ev.new_runtime { - runtimes.insert(ev.block_hash.hash(), runtime); - } - None - } - FollowEvent::Finalized(ev) => { - let next_runtime = { - let mut it = ev - .finalized_block_hashes - .iter() - .rev() - .filter_map(|h| runtimes.get(&h.hash()).cloned()) - .peekable(); - let next = it.next(); - if it.peek().is_some() { - { - use ::tracing::__macro_support::Callsite as _; - static __CALLSITE: ::tracing::callsite::DefaultCallsite = { - static META: ::tracing::Metadata<'static> = { - ::tracing_core::metadata::Metadata::new( - "event subxt/src/backend/unstable/mod.rs:377", - "subxt", - ::tracing::Level::WARN, - ::core::option::Option::Some( - "subxt/src/backend/unstable/mod.rs", - ), - ::core::option::Option::Some(377u32), - ::core::option::Option::Some("subxt::backend::unstable"), - ::tracing_core::field::FieldSet::new( - &["message"], - ::tracing_core::callsite::Identifier(&__CALLSITE), - ), - ::tracing::metadata::Kind::EVENT, - ) - }; - ::tracing::callsite::DefaultCallsite::new(&META) - }; - let enabled = ::tracing::Level::WARN - <= ::tracing::level_filters::STATIC_MAX_LEVEL - && ::tracing::Level::WARN - <= ::tracing::level_filters::LevelFilter::current() - && { - let interest = __CALLSITE.interest(); - !interest.is_never() - && ::tracing::__macro_support::__is_enabled( - __CALLSITE.metadata(), - interest, - ) - }; - if enabled { - (|value_set: ::tracing::field::ValueSet| { - let meta = __CALLSITE.metadata(); - ::tracing::Event::dispatch(meta, &value_set); - })({ - #[allow(unused_imports)] - use ::tracing::field::{debug, display, Value}; - let mut iter = __CALLSITE.metadata().fields().iter(); - __CALLSITE - .metadata() - .fields() - .value_set( - &[ - ( - &::core::iter::Iterator::next(&mut iter) - .expect("FieldSet corrupted (this is a bug)"), - ::core::option::Option::Some( - &format_args!( - "Several runtime upgrades in the finalized blocks but only the latest runtime upgrade is returned" - ) as &dyn Value, - ), - ), - ], - ) - }); - } else { - } - }; - } - next - }; - for block in ev - .finalized_block_hashes - .iter() - .chain(ev.pruned_block_hashes.iter()) - { - runtimes.remove(&block.hash()); - } - next_runtime - } - _ => None, - }; - let runtime_event = match output { - None => return std::future::ready(None), - Some(ev) => ev, - }; - let runtime_details = match runtime_event { - RuntimeEvent::Invalid(err) => { - return std::future::ready( - Some(Err(Error::Other(err.error))), - ); - } - RuntimeEvent::Valid(ev) => ev, - }; - std::future::ready( - Some( - Ok(RuntimeVersion { - spec_version: runtime_details.spec.spec_version, - transaction_version: runtime_details - .spec - .transaction_version, - }), - ), - ) - }); - Ok(StreamOf(Box::pin(runtime_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_all_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - __self - .stream_headers(|ev| match ev { - FollowEvent::Initialized(ev) => { - Some(ev.finalized_block_hash) - } - FollowEvent::NewBlock(ev) => Some(ev.block_hash), - _ => None, - }) - .await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_best_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - __self - .stream_headers(|ev| match ev { - FollowEvent::Initialized(ev) => { - Some(ev.finalized_block_hash) - } - FollowEvent::BestBlockChanged(ev) => { - Some(ev.best_block_hash) - } - _ => None, - }) - .await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn stream_finalized_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - > = { - __self - .stream_headers(|ev| match ev { - FollowEvent::Initialized(ev) => { - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ev.finalized_block_hash]), - ) - } - FollowEvent::Finalized(ev) => ev.finalized_block_hashes, - _ => ::alloc::vec::Vec::new(), - }) - .await - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn submit_transaction<'life0, 'life1, 'async_trait>( - &'life0 self, - extrinsic: &'life1 [u8], - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::< - Result>, Error>, - > { - return __ret; - } - let __self = self; - let __ret: Result< - StreamOfResults>, - Error, - > = { - enum SeenBlockMarker { - New, - Finalized, - } - let mut seen_blocks_sub = __self - .follow_handle - .subscribe() - .events(); - let mut tx_progress = __self - .methods - .transaction_unstable_submit_and_watch(extrinsic) - .await?; - let mut seen_blocks = HashMap::new(); - let mut done = false; - let mut finalized_hash: Option = None; - let start_instant = instant::Instant::now(); - let err_other = |s: &str| Some(Err(Error::Other(s.into()))); - let tx_stream = futures::stream::poll_fn(move |cx| { - loop { - if done { - return Poll::Ready(None); - } - if start_instant.elapsed().as_secs() > 240 { - return Poll::Ready( - err_other( - "Timeout waiting for the transaction to be finalized", - ), - ); - } - let follow_ev_poll = match seen_blocks_sub - .poll_next_unpin(cx) - { - Poll::Ready(None) => { - return Poll::Ready( - err_other("chainHead_follow stream ended unexpectedly"), - ); - } - Poll::Ready(Some(follow_ev)) => Poll::Ready(follow_ev), - Poll::Pending => Poll::Pending, - }; - let follow_ev_is_pending = follow_ev_poll.is_pending(); - if let Poll::Ready(follow_ev) = follow_ev_poll { - match follow_ev { - FollowEvent::NewBlock(ev) => { - if finalized_hash.is_none() { - seen_blocks - .insert( - ev.block_hash.hash(), - (SeenBlockMarker::New, ev.block_hash), - ); - } - } - FollowEvent::Finalized(ev) => { - for block_ref in ev.finalized_block_hashes { - seen_blocks - .insert( - block_ref.hash(), - (SeenBlockMarker::Finalized, block_ref), - ); - } - } - FollowEvent::Stop => { - return Poll::Ready( - err_other( - "chainHead_follow emitted 'stop' event during transaction submission", - ), - ); - } - _ => {} - } - continue; - } - if let Some(hash) = &finalized_hash { - if let Some((SeenBlockMarker::Finalized, block_ref)) - = seen_blocks.remove(hash) - { - done = true; - let ev = TransactionStatus::InFinalizedBlock { - hash: block_ref.into(), - }; - return Poll::Ready(Some(Ok(ev))); - } else { - seen_blocks.clear(); - if follow_ev_is_pending { - return Poll::Pending; - } else { - continue; - } - } - } - let tx_progress_ev = match tx_progress.poll_next_unpin(cx) { - Poll::Pending => return Poll::Pending, - Poll::Ready(None) => { - return Poll::Ready( - err_other( - "No more transaction progress events, but we haven't seen a Finalized one yet", - ), - ); - } - Poll::Ready(Some(Err(e))) => { - return Poll::Ready(Some(Err(e))); - } - Poll::Ready(Some(Ok(ev))) => ev, - }; - let tx_progress_ev = match tx_progress_ev { - rpc_methods::TransactionStatus::Finalized { block } => { - finalized_hash = Some(block.hash); - continue; - } - rpc_methods::TransactionStatus::BestChainBlockIncluded { - block: Some(block), - } => { - let block_ref = match seen_blocks.get(&block.hash) { - Some((_, block_ref)) => block_ref.clone().into(), - None => BlockRef::from_hash(block.hash), - }; - TransactionStatus::InBestBlock { - hash: block_ref, - } - } - rpc_methods::TransactionStatus::BestChainBlockIncluded { - block: None, - } => TransactionStatus::NoLongerInBestBlock, - rpc_methods::TransactionStatus::Broadcasted { - num_peers, - } => { - TransactionStatus::Broadcasted { - num_peers, - } - } - rpc_methods::TransactionStatus::Dropped { error, .. } => { - TransactionStatus::Dropped { - message: error, - } - } - rpc_methods::TransactionStatus::Error { error } => { - TransactionStatus::Dropped { - message: error, - } - } - rpc_methods::TransactionStatus::Invalid { error } => { - TransactionStatus::Invalid { - message: error, - } - } - rpc_methods::TransactionStatus::Validated => { - TransactionStatus::Validated - } - }; - return Poll::Ready(Some(Ok(tx_progress_ev))); - } - }); - Ok(StreamOf(Box::pin(tx_stream))) - }; - #[allow(unreachable_code)] __ret - }) - } - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn call<'life0, 'life1, 'life2, 'async_trait>( - &'life0 self, - method: &'life1 str, - call_parameters: Option<&'life2 [u8]>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - 'life2: 'async_trait, - Self: 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::, Error>> { - return __ret; - } - let __self = self; - let call_parameters = call_parameters; - let at = at; - let __ret: Result, Error> = { - let sub_id = get_subscription_id(&__self.follow_handle).await?; - let follow_events = __self.follow_handle.subscribe().events(); - let call_parameters = call_parameters.unwrap_or(&[]); - let status = __self - .methods - .chainhead_unstable_call( - &sub_id, - at, - method, - call_parameters, - ) - .await?; - let operation_id = match status { - MethodResponse::LimitReached => { - return Err( - RpcError::request_rejected("limit reached").into(), - ); - } - MethodResponse::Started(s) => s.operation_id, - }; - let mut call_data_stream = follow_events - .filter_map(|ev| { - let FollowEvent::OperationCallDone(body) = ev else { - return std::future::ready(None); - }; - if body.operation_id != operation_id { - return std::future::ready(None); - } - std::future::ready(Some(body.output.0)) - }); - call_data_stream - .next() - .await - .ok_or_else(|| RpcError::SubscriptionDropped.into()) - }; - #[allow(unreachable_code)] __ret - }) - } - } - /// A helper to obtain a subscription ID. - async fn get_subscription_id( - follow_handle: &FollowStreamDriverHandle, - ) -> Result { - let Some(sub_id) = follow_handle.subscribe().subscription_id().await else { - return Err(RpcError::SubscriptionDropped.into()); - }; - Ok(sub_id) - } - } - use crate::error::Error; - use crate::metadata::Metadata; - use crate::Config; - use async_trait::async_trait; - use codec::{Decode, Encode}; - use futures::{Stream, StreamExt}; - use std::pin::Pin; - use std::sync::Arc; - /// Prevent the backend trait being implemented externally. - #[doc(hidden)] - pub(crate) mod sealed { - pub trait Sealed {} - } - /// This trait exposes the interface that Subxt will use to communicate with - /// a backend. Its goal is to be as minimal as possible. - pub trait Backend: sealed::Sealed + Send + Sync + 'static { - /// Fetch values from storage. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn storage_fetch_values<'life0, 'async_trait>( - &'life0 self, - keys: Vec>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Fetch keys underneath the given key from storage. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn storage_fetch_descendant_keys<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Fetch values underneath the given key from storage. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn storage_fetch_descendant_values<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Fetch the genesis hash - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn genesis_hash<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Get a block header - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn block_header<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Return the extrinsics found in the block. Each extrinsic is represented - /// by a vector of bytes which has _not_ been SCALE decoded (in other words, the - /// first bytes in the vector will decode to the compact encoded length of the extrinsic) - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn block_body<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Get the most recent finalized block hash. - /// Note: needed only in blocks client for finalized block stream; can prolly be removed. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn latest_finalized_block_ref<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Get information about the current runtime. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn current_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// A stream of all new runtime versions as they occur. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn stream_runtime_version<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// A stream of all new block headers as they arrive. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn stream_all_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// A stream of best block headers. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn stream_best_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// A stream of finalized block headers. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn stream_finalized_block_headers<'life0, 'async_trait>( - &'life0 self, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result< - StreamOfResults<(T::Header, BlockRef)>, - Error, - >, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: 'async_trait; - /// Submit a transaction. This will return a stream of events about it. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn submit_transaction<'life0, 'life1, 'async_trait>( - &'life0 self, - bytes: &'life1 [u8], - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - Self: 'async_trait; - /// Make a call to some runtime API. - #[must_use] - #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)] - fn call<'life0, 'life1, 'life2, 'async_trait>( - &'life0 self, - method: &'life1 str, - call_parameters: Option<&'life2 [u8]>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - 'life1: 'async_trait, - 'life2: 'async_trait, - Self: 'async_trait; - } - /// helpeful utility methods derived from those provided on [`Backend`] - pub trait BackendExt: Backend { - /// Fetch a single value from storage. - #[must_use] - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn storage_fetch_value<'life0, 'async_trait>( - &'life0 self, - key: Vec, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result>, Error>, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: ::core::marker::Sync + 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::>, Error>> { - return __ret; - } - let __self = self; - let key = key; - let at = at; - let __ret: Result>, Error> = { - __self - .storage_fetch_values( - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([key]), - ), - at, - ) - .await? - .next() - .await - .transpose() - .map(|o| o.map(|s| s.value)) - }; - #[allow(unreachable_code)] __ret - }) - } - /// The same as a [`Backend::call()`], but it will also attempt to decode the - /// result into the given type, which is a fairly common operation. - #[must_use] - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn call_decoding<'life0, 'life1, 'life2, 'async_trait, D>( - &'life0 self, - method: &'life1 str, - call_parameters: Option<&'life2 [u8]>, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - D: 'async_trait + codec::Decode, - 'life0: 'async_trait, - 'life1: 'async_trait, - 'life2: 'async_trait, - Self: ::core::marker::Sync + 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let call_parameters = call_parameters; - let at = at; - let __ret: Result = { - let bytes = __self.call(method, call_parameters, at).await?; - let res = D::decode(&mut &*bytes)?; - Ok(res) - }; - #[allow(unreachable_code)] __ret - }) - } - /// Return the metadata at some version. - #[must_use] - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn metadata_at_version<'life0, 'async_trait>( - &'life0 self, - version: u32, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: ::core::marker::Sync + 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let version = version; - let at = at; - let __ret: Result = { - let param = version.encode(); - let opaque: Option = __self - .call_decoding("Metadata_metadata_at_version", Some(¶m), at) - .await?; - let Some(opaque) = opaque else { - return Err(Error::Other("Metadata version not found".into())); - }; - let metadata: Metadata = Decode::decode(&mut &opaque.0[..])?; - Ok(metadata) - }; - #[allow(unreachable_code)] __ret - }) - } - /// Return V14 metadata from the legacy `Metadata_metadata` call. - #[must_use] - #[allow( - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - fn legacy_metadata<'life0, 'async_trait>( - &'life0 self, - at: T::Hash, - ) -> ::core::pin::Pin< - Box< - dyn ::core::future::Future< - Output = Result, - > + ::core::marker::Send + 'async_trait, - >, - > - where - 'life0: 'async_trait, - Self: ::core::marker::Sync + 'async_trait, - { - Box::pin(async move { - if let ::core::option::Option::Some(__ret) - = ::core::option::Option::None::> { - return __ret; - } - let __self = self; - let at = at; - let __ret: Result = { - let opaque: frame_metadata::OpaqueMetadata = __self - .call_decoding("Metadata_metadata", None, at) - .await?; - let metadata: Metadata = Decode::decode(&mut &opaque.0[..])?; - Ok(metadata) - }; - #[allow(unreachable_code)] __ret - }) - } - } - impl + ?Sized, T: Config> BackendExt for B {} - /// An opaque struct which, while alive, indicates that some references to a block - /// still exist. This gives the backend the opportunity to keep the corresponding block - /// details around for a while if it likes and is able to. No guarantees can be made about - /// how long the corresponding details might be available for, but if no references to a block - /// exist, then the backend is free to discard any details for it. - pub struct BlockRef { - hash: H, - _pointer: Option>, - } - #[automatically_derived] - impl ::core::clone::Clone for BlockRef { - #[inline] - fn clone(&self) -> BlockRef { - BlockRef { - hash: ::core::clone::Clone::clone(&self.hash), - _pointer: ::core::clone::Clone::clone(&self._pointer), - } - } - } - impl From for BlockRef { - fn from(value: H) -> Self { - BlockRef::from_hash(value) - } - } - impl PartialEq for BlockRef { - fn eq(&self, other: &Self) -> bool { - self.hash == other.hash - } - } - impl Eq for BlockRef {} - impl PartialOrd for BlockRef { - fn partial_cmp(&self, other: &Self) -> Option { - self.hash.partial_cmp(&other.hash) - } - } - impl Ord for BlockRef { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.hash.cmp(&other.hash) - } - } - impl std::fmt::Debug for BlockRef { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("BlockRef").field(&self.hash).finish() - } - } - impl std::hash::Hash for BlockRef { - fn hash(&self, state: &mut Hasher) { - self.hash.hash(state); - } - } - impl BlockRef { - /// A [`BlockRef`] that doesn't reference a given block, but does have an associated hash. - /// This is used in the legacy backend, which has no notion of pinning blocks. - pub fn from_hash(hash: H) -> Self { - Self { hash, _pointer: None } - } - /// Construct a [`BlockRef`] from an instance of the underlying trait. It's expected - /// that the [`Backend`] implementation will call this if it wants to track which blocks - /// are potentially in use. - pub fn new(hash: H, inner: P) -> Self { - Self { - hash, - _pointer: Some(Arc::new(inner)), - } - } - /// Return the hash of the referenced block. - pub fn hash(&self) -> H - where - H: Copy, - { - self.hash - } - } - /// A trait that a [`Backend`] can implement to know when some block - /// can be unpinned: when this is dropped, there are no remaining references - /// to the block that it's associated with. - pub trait BlockRefT: Send + Sync + 'static {} - /// A stream of some item. - pub struct StreamOf(Pin + Send + 'static>>); - impl Stream for StreamOf { - type Item = T; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - self.0.poll_next_unpin(cx) - } - } - impl std::fmt::Debug for StreamOf { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("StreamOf").field(&"").finish() - } - } - impl StreamOf { - /// Construct a new stream. - pub fn new(inner: Pin + Send + 'static>>) -> Self { - StreamOf(inner) - } - /// Returns the next item in the stream. This is just a wrapper around - /// [`StreamExt::next()`] so that you can avoid the extra import. - pub async fn next(&mut self) -> Option { - StreamExt::next(self).await - } - } - /// A stream of [`Result`]. - pub type StreamOfResults = StreamOf>; - /// Runtime version information needed to submit transactions. - pub struct RuntimeVersion { - /// Version of the runtime specification. A full-node will not attempt to use its native - /// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, - /// `spec_version` and `authoring_version` are the same between Wasm and native. - pub spec_version: u32, - /// All existing dispatches are fully compatible when this number doesn't change. If this - /// number changes, then `spec_version` must change, also. - /// - /// This number must change when an existing dispatchable (module ID, dispatch ID) is changed, - /// either through an alteration in its user-level semantics, a parameter - /// added/removed/changed, a dispatchable being removed, a module being removed, or a - /// dispatchable/module changing its index. - /// - /// It need *not* change when a new module is added or when a dispatchable is added. - pub transaction_version: u32, - } - #[automatically_derived] - impl ::core::fmt::Debug for RuntimeVersion { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "RuntimeVersion", - "spec_version", - &self.spec_version, - "transaction_version", - &&self.transaction_version, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for RuntimeVersion { - #[inline] - fn clone(&self) -> RuntimeVersion { - RuntimeVersion { - spec_version: ::core::clone::Clone::clone(&self.spec_version), - transaction_version: ::core::clone::Clone::clone( - &self.transaction_version, - ), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for RuntimeVersion {} - #[automatically_derived] - impl ::core::cmp::PartialEq for RuntimeVersion { - #[inline] - fn eq(&self, other: &RuntimeVersion) -> bool { - self.spec_version == other.spec_version - && self.transaction_version == other.transaction_version - } - } - #[automatically_derived] - impl ::core::cmp::Eq for RuntimeVersion { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - /// The status of the transaction. - /// - /// If the status is [`TransactionStatus::InFinalizedBlock`], [`TransactionStatus::Error`], - /// [`TransactionStatus::Invalid`] or [`TransactionStatus::Dropped`], then no future - /// events will be emitted. - pub enum TransactionStatus { - /// Transaction is part of the future queue. - Validated, - /// The transaction has been broadcast to other nodes. - Broadcasted { - /// Number of peers it's been broadcast to. - num_peers: u32, - }, - /// Transaction is no longer in a best block. - NoLongerInBestBlock, - /// Transaction has been included in block with given hash. - InBestBlock { - /// Block hash the transaction is in. - hash: BlockRef, - }, - /// Transaction has been finalized by a finality-gadget, e.g GRANDPA - InFinalizedBlock { - /// Block hash the transaction is in. - hash: BlockRef, - }, - /// Something went wrong in the node. - Error { - /// Human readable message; what went wrong. - message: String, - }, - /// Transaction is invalid (bad nonce, signature etc). - Invalid { - /// Human readable message; why was it invalid. - message: String, - }, - /// The transaction was dropped. - Dropped { - /// Human readable message; why was it dropped. - message: String, - }, - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionStatus { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionStatus::Validated => { - ::core::fmt::Formatter::write_str(f, "Validated") - } - TransactionStatus::Broadcasted { num_peers: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Broadcasted", - "num_peers", - &__self_0, - ) - } - TransactionStatus::NoLongerInBestBlock => { - ::core::fmt::Formatter::write_str(f, "NoLongerInBestBlock") - } - TransactionStatus::InBestBlock { hash: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "InBestBlock", - "hash", - &__self_0, - ) - } - TransactionStatus::InFinalizedBlock { hash: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "InFinalizedBlock", - "hash", - &__self_0, - ) - } - TransactionStatus::Error { message: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Error", - "message", - &__self_0, - ) - } - TransactionStatus::Invalid { message: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Invalid", - "message", - &__self_0, - ) - } - TransactionStatus::Dropped { message: __self_0 } => { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Dropped", - "message", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::clone::Clone for TransactionStatus { - #[inline] - fn clone(&self) -> TransactionStatus { - match self { - TransactionStatus::Validated => TransactionStatus::Validated, - TransactionStatus::Broadcasted { num_peers: __self_0 } => { - TransactionStatus::Broadcasted { - num_peers: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::NoLongerInBestBlock => { - TransactionStatus::NoLongerInBestBlock - } - TransactionStatus::InBestBlock { hash: __self_0 } => { - TransactionStatus::InBestBlock { - hash: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::InFinalizedBlock { hash: __self_0 } => { - TransactionStatus::InFinalizedBlock { - hash: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Error { message: __self_0 } => { - TransactionStatus::Error { - message: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Invalid { message: __self_0 } => { - TransactionStatus::Invalid { - message: ::core::clone::Clone::clone(__self_0), - } - } - TransactionStatus::Dropped { message: __self_0 } => { - TransactionStatus::Dropped { - message: ::core::clone::Clone::clone(__self_0), - } - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionStatus {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for TransactionStatus { - #[inline] - fn eq(&self, other: &TransactionStatus) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionStatus::Broadcasted { num_peers: __self_0 }, - TransactionStatus::Broadcasted { num_peers: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::InBestBlock { hash: __self_0 }, - TransactionStatus::InBestBlock { hash: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::InFinalizedBlock { hash: __self_0 }, - TransactionStatus::InFinalizedBlock { hash: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Error { message: __self_0 }, - TransactionStatus::Error { message: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Invalid { message: __self_0 }, - TransactionStatus::Invalid { message: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - ( - TransactionStatus::Dropped { message: __self_0 }, - TransactionStatus::Dropped { message: __arg1_0 }, - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TransactionStatus { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - } - } - /// A response from calls like [`Backend::storage_fetch_values`] or - /// [`Backend::storage_fetch_descendant_values`]. - pub struct StorageResponse { - /// The key. - pub key: Vec, - /// The associated value. - pub value: Vec, - } -} -pub mod blocks { - //! This module exposes the necessary functionality for working with events. - mod block_types { - use crate::{ - backend::BlockRef, - blocks::{extrinsic_types::ExtrinsicPartTypeIds, Extrinsics}, - client::{OfflineClientT, OnlineClientT}, - config::{Config, Header}, - error::{BlockError, DecodeError, Error}, - events, runtime_api::RuntimeApi, storage::Storage, - }; - use codec::{Decode, Encode}; - use futures::lock::Mutex as AsyncMutex; - use std::sync::Arc; - /// A representation of a block. - pub struct Block { - header: T::Header, - block_ref: BlockRef, - client: C, - cached_events: CachedEvents, - } - pub(crate) type CachedEvents = Arc>>>; - impl Block - where - T: Config, - C: OfflineClientT, - { - pub(crate) fn new( - header: T::Header, - block_ref: BlockRef, - client: C, - ) -> Self { - Block { - header, - block_ref, - client, - cached_events: Default::default(), - } - } - /// Return a reference to the given block. While this reference is kept alive, - /// the backend will (if possible) endeavour to keep hold of the block. - pub fn reference(&self) -> BlockRef { - self.block_ref.clone() - } - /// Return the block hash. - pub fn hash(&self) -> T::Hash { - self.block_ref.hash() - } - /// Return the block number. - pub fn number(&self) -> ::Number { - self.header().number() - } - /// Return the entire block header. - pub fn header(&self) -> &T::Header { - &self.header - } - } - impl Block - where - T: Config, - C: OnlineClientT, - { - /// Return the events associated with the block, fetching them from the node if necessary. - pub async fn events(&self) -> Result, Error> { - get_events(&self.client, self.header.hash(), &self.cached_events).await - } - /// Fetch and return the extrinsics in the block body. - pub async fn extrinsics(&self) -> Result, Error> { - let ids = ExtrinsicPartTypeIds::new(&self.client.metadata())?; - let block_hash = self.header.hash(); - let Some(extrinsics) = self - .client - .backend() - .block_body(block_hash) - .await? else { return Err(BlockError::not_found(block_hash).into()); - }; - Ok( - Extrinsics::new( - self.client.clone(), - extrinsics, - self.cached_events.clone(), - ids, - block_hash, - ), - ) - } - /// Work with storage. - pub fn storage(&self) -> Storage { - Storage::new(self.client.clone(), self.block_ref.clone()) - } - /// Execute a runtime API call at this block. - pub async fn runtime_api(&self) -> Result, Error> { - Ok(RuntimeApi::new(self.client.clone(), self.block_ref.clone())) - } - /// Get the account nonce for a given account ID at this block. - pub async fn account_nonce( - &self, - account_id: &T::AccountId, - ) -> Result { - get_account_nonce(&self.client, account_id, self.hash()).await - } - } - pub(crate) async fn get_events( - client: &C, - block_hash: T::Hash, - cached_events: &AsyncMutex>>, - ) -> Result, Error> - where - T: Config, - C: OnlineClientT, - { - let mut lock = cached_events.lock().await; - let events = match &*lock { - Some(events) => events.clone(), - None => { - let events = events::EventsClient::new(client.clone()) - .at(block_hash) - .await?; - lock.replace(events.clone()); - events - } - }; - Ok(events) - } - pub(crate) async fn get_account_nonce( - client: &C, - account_id: &T::AccountId, - block_hash: T::Hash, - ) -> Result - where - C: OnlineClientT, - T: Config, - { - let account_nonce_bytes = client - .backend() - .call( - "AccountNonceApi_account_nonce", - Some(&account_id.encode()), - block_hash, - ) - .await?; - let cursor = &mut &account_nonce_bytes[..]; - let account_nonce: u64 = match account_nonce_bytes.len() { - 2 => u16::decode(cursor)?.into(), - 4 => u32::decode(cursor)?.into(), - 8 => u64::decode(cursor)?, - _ => { - return Err( - Error::Decode( - DecodeError::custom_string({ - let res = ::alloc::fmt::format( - format_args!( - "state call AccountNonceApi_account_nonce returned an unexpected number of bytes: {0} (expected 2, 4 or 8)", - account_nonce_bytes.len() - ), - ); - res - }), - ), - ); - } - }; - Ok(account_nonce) - } - } - mod blocks_client { - use super::Block; - use crate::{ - backend::{BlockRef, StreamOfResults}, - client::OnlineClientT, config::Config, error::{BlockError, Error}, - utils::PhantomDataSendSync, - }; - use derivative::Derivative; - use futures::StreamExt; - use std::future::Future; - type BlockStream = StreamOfResults; - type BlockStreamRes = Result, Error>; - /// A client for working with blocks. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct BlocksClient { - client: Client, - _marker: PhantomDataSendSync, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for BlocksClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - BlocksClient { client: ref __arg_0, _marker: ref __arg_1 } => { - BlocksClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl BlocksClient { - /// Create a new [`BlocksClient`]. - pub fn new(client: Client) -> Self { - Self { - client, - _marker: PhantomDataSendSync::new(), - } - } - } - impl BlocksClient - where - T: Config, - Client: OnlineClientT, - { - /// Obtain block details given the provided block hash. - /// - /// # Warning - /// - /// This call only supports blocks produced since the most recent - /// runtime upgrade. You can attempt to retrieve older blocks, - /// but may run into errors attempting to work with them. - pub fn at( - &self, - block_ref: impl Into>, - ) -> impl Future, Error>> + Send + 'static { - self.at_or_latest(Some(block_ref.into())) - } - /// Obtain block details of the latest block hash. - pub fn at_latest( - &self, - ) -> impl Future, Error>> + Send + 'static { - self.at_or_latest(None) - } - /// Obtain block details given the provided block hash, or the latest block if `None` is - /// provided. - fn at_or_latest( - &self, - block_ref: Option>, - ) -> impl Future, Error>> + Send + 'static { - let client = self.client.clone(); - async move { - let block_ref = match block_ref { - Some(r) => r, - None => client.backend().latest_finalized_block_ref().await?, - }; - let block_header = match client - .backend() - .block_header(block_ref.hash()) - .await? - { - Some(header) => header, - None => { - return Err(BlockError::not_found(block_ref.hash()).into()); - } - }; - Ok(Block::new(block_header, block_ref, client)) - } - } - /// Subscribe to all new blocks imported by the node. - /// - /// **Note:** You probably want to use [`Self::subscribe_finalized()`] most of - /// the time. - pub fn subscribe_all( - &self, - ) -> impl Future< - Output = Result>, Error>, - > + Send + 'static - where - Client: Send + Sync + 'static, - { - let client = self.client.clone(); - header_sub_fut_to_block_sub( - self.clone(), - async move { - let sub = client.backend().stream_all_block_headers().await?; - BlockStreamRes::Ok(sub) - }, - ) - } - /// Subscribe to all new blocks imported by the node onto the current best fork. - /// - /// **Note:** You probably want to use [`Self::subscribe_finalized()`] most of - /// the time. - pub fn subscribe_best( - &self, - ) -> impl Future< - Output = Result>, Error>, - > + Send + 'static - where - Client: Send + Sync + 'static, - { - let client = self.client.clone(); - header_sub_fut_to_block_sub( - self.clone(), - async move { - let sub = client.backend().stream_best_block_headers().await?; - BlockStreamRes::Ok(sub) - }, - ) - } - /// Subscribe to finalized blocks. - pub fn subscribe_finalized( - &self, - ) -> impl Future< - Output = Result>, Error>, - > + Send + 'static - where - Client: Send + Sync + 'static, - { - let client = self.client.clone(); - header_sub_fut_to_block_sub( - self.clone(), - async move { - let sub = client - .backend() - .stream_finalized_block_headers() - .await?; - BlockStreamRes::Ok(sub) - }, - ) - } - } - /// Take a promise that will return a subscription to some block headers, - /// and return a subscription to some blocks based on this. - async fn header_sub_fut_to_block_sub( - blocks_client: BlocksClient, - sub: S, - ) -> Result>, Error> - where - T: Config, - S: Future< - Output = Result)>, Error>, - > + Send + 'static, - Client: OnlineClientT + Send + Sync + 'static, - { - let sub = sub - .await? - .then(move |header_and_ref| { - let client = blocks_client.client.clone(); - async move { - let (header, block_ref) = match header_and_ref { - Ok(header_and_ref) => header_and_ref, - Err(e) => return Err(e), - }; - Ok(Block::new(header, block_ref, client)) - } - }); - BlockStreamRes::Ok(StreamOfResults::new(Box::pin(sub))) - } - } - mod extrinsic_types { - use crate::{ - blocks::block_types::{get_events, CachedEvents}, - client::{OfflineClientT, OnlineClientT}, - config::{Config, Hasher}, - error::{BlockError, Error, MetadataError}, - events, metadata::types::PalletMetadata, Metadata, - }; - use crate::config::signed_extensions::{ - ChargeAssetTxPayment, ChargeTransactionPayment, CheckNonce, - }; - use crate::config::SignedExtension; - use crate::dynamic::DecodedValue; - use crate::utils::strip_compact_prefix; - use codec::Decode; - use derivative::Derivative; - use scale_decode::{DecodeAsFields, DecodeAsType}; - use std::sync::Arc; - /// Trait to uniquely identify the extrinsic's identity from the runtime metadata. - /// - /// Generated API structures that represent an extrinsic implement this trait. - /// - /// The trait is utilized to decode emitted extrinsics from a block, via obtaining the - /// form of the `Extrinsic` from the metadata. - pub trait StaticExtrinsic: DecodeAsFields { - /// Pallet name. - const PALLET: &'static str; - /// Call name. - const CALL: &'static str; - /// Returns true if the given pallet and call names match this extrinsic. - fn is_extrinsic(pallet: &str, call: &str) -> bool { - Self::PALLET == pallet && Self::CALL == call - } - } - /// The body of a block. - pub struct Extrinsics { - client: C, - extrinsics: Vec>, - cached_events: CachedEvents, - ids: ExtrinsicPartTypeIds, - hash: T::Hash, - } - impl Extrinsics - where - T: Config, - C: OfflineClientT, - { - pub(crate) fn new( - client: C, - extrinsics: Vec>, - cached_events: CachedEvents, - ids: ExtrinsicPartTypeIds, - hash: T::Hash, - ) -> Self { - Self { - client, - extrinsics, - cached_events, - ids, - hash, - } - } - /// The number of extrinsics. - pub fn len(&self) -> usize { - self.extrinsics.len() - } - /// Are there no extrinsics in this block? - pub fn is_empty(&self) -> bool { - self.extrinsics.is_empty() - } - /// Return the block hash that these extrinsics are from. - pub fn block_hash(&self) -> T::Hash { - self.hash - } - /// Returns an iterator over the extrinsics in the block body. - pub fn iter( - &self, - ) -> impl Iterator< - Item = Result, Error>, - > + Send + Sync + 'static { - let extrinsics = self.extrinsics.clone(); - let num_extrinsics = self.extrinsics.len(); - let client = self.client.clone(); - let hash = self.hash; - let cached_events = self.cached_events.clone(); - let ids = self.ids; - let mut index = 0; - std::iter::from_fn(move || { - if index == num_extrinsics { - None - } else { - match ExtrinsicDetails::decode_from( - index as u32, - &extrinsics[index], - client.clone(), - hash, - cached_events.clone(), - ids, - ) { - Ok(extrinsic_details) => { - index += 1; - Some(Ok(extrinsic_details)) - } - Err(e) => { - index = num_extrinsics; - Some(Err(e)) - } - } - } - }) - } - /// Iterate through the extrinsics using metadata to dynamically decode and skip - /// them, and return only those which should decode to the provided `E` type. - /// If an error occurs, all subsequent iterations return `None`. - pub fn find( - &self, - ) -> impl Iterator, Error>> + '_ { - self.iter() - .filter_map(|res| match res { - Err(err) => Some(Err(err)), - Ok(details) => { - match details.as_extrinsic::() { - Err(err) => Some(Err(err)), - Ok(None) => None, - Ok(Some(value)) => { - Some(Ok(FoundExtrinsic { details, value })) - } - } - } - }) - } - /// Iterate through the extrinsics using metadata to dynamically decode and skip - /// them, and return the first extrinsic found which decodes to the provided `E` type. - pub fn find_first( - &self, - ) -> Result>, Error> { - self.find::().next().transpose() - } - /// Iterate through the extrinsics using metadata to dynamically decode and skip - /// them, and return the last extrinsic found which decodes to the provided `Ev` type. - pub fn find_last( - &self, - ) -> Result>, Error> { - self.find::().last().transpose() - } - /// Find an extrinsics that decodes to the type provided. Returns true if it was found. - pub fn has(&self) -> Result { - Ok(self.find::().next().transpose()?.is_some()) - } - } - /// A single extrinsic in a block. - pub struct ExtrinsicDetails { - /// The index of the extrinsic in the block. - index: u32, - /// Extrinsic bytes. - bytes: Arc<[u8]>, - /// Some if the extrinsic payload is signed. - signed_details: Option, - /// The start index in the `bytes` from which the call is encoded. - call_start_idx: usize, - /// The pallet index. - pallet_index: u8, - /// The variant index. - variant_index: u8, - /// The block hash of this extrinsic (needed to fetch events). - block_hash: T::Hash, - /// Subxt client. - client: C, - /// Cached events. - cached_events: CachedEvents, - /// Subxt metadata to fetch the extrinsic metadata. - metadata: Metadata, - _marker: std::marker::PhantomData, - } - /// Details only available in signed extrinsics. - pub struct SignedExtrinsicDetails { - /// start index of the range in `bytes` of `ExtrinsicDetails` that encodes the address. - address_start_idx: usize, - /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the address. Equivalent to signature_start_idx. - address_end_idx: usize, - /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the signature. Equivalent to extra_start_idx. - signature_end_idx: usize, - /// end index of the range in `bytes` of `ExtrinsicDetails` that encodes the signature. - extra_end_idx: usize, - } - impl ExtrinsicDetails - where - T: Config, - C: OfflineClientT, - { - pub(crate) fn decode_from( - index: u32, - extrinsic_bytes: &[u8], - client: C, - block_hash: T::Hash, - cached_events: CachedEvents, - ids: ExtrinsicPartTypeIds, - ) -> Result, Error> { - const SIGNATURE_MASK: u8 = 0b1000_0000; - const VERSION_MASK: u8 = 0b0111_1111; - const LATEST_EXTRINSIC_VERSION: u8 = 4; - let metadata = client.metadata(); - let bytes: Arc<[u8]> = strip_compact_prefix(extrinsic_bytes)?.1.into(); - let first_byte: u8 = Decode::decode(&mut &bytes[..])?; - let version = first_byte & VERSION_MASK; - if version != LATEST_EXTRINSIC_VERSION { - return Err(BlockError::UnsupportedVersion(version).into()); - } - let is_signed = first_byte & SIGNATURE_MASK != 0; - let cursor = &mut &bytes[1..]; - let signed_details = is_signed - .then(|| -> Result { - let address_start_idx = bytes.len() - cursor.len(); - scale_decode::visitor::decode_with_visitor( - cursor, - ids.address, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(scale_decode::Error::from)?; - let address_end_idx = bytes.len() - cursor.len(); - scale_decode::visitor::decode_with_visitor( - cursor, - ids.signature, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(scale_decode::Error::from)?; - let signature_end_idx = bytes.len() - cursor.len(); - scale_decode::visitor::decode_with_visitor( - cursor, - ids.extra, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(scale_decode::Error::from)?; - let extra_end_idx = bytes.len() - cursor.len(); - Ok(SignedExtrinsicDetails { - address_start_idx, - address_end_idx, - signature_end_idx, - extra_end_idx, - }) - }) - .transpose()?; - let call_start_idx = bytes.len() - cursor.len(); - let cursor = &mut &bytes[call_start_idx..]; - let pallet_index: u8 = Decode::decode(cursor)?; - let variant_index: u8 = Decode::decode(cursor)?; - Ok(ExtrinsicDetails { - index, - bytes, - signed_details, - call_start_idx, - pallet_index, - variant_index, - block_hash, - client, - cached_events, - metadata, - _marker: std::marker::PhantomData, - }) - } - /// Is the extrinsic signed? - pub fn is_signed(&self) -> bool { - self.signed_details.is_some() - } - /// The index of the extrinsic in the block. - pub fn index(&self) -> u32 { - self.index - } - /// Return _all_ of the bytes representing this extrinsic, which include, in order: - /// - First byte: abbbbbbb (a = 0 for unsigned, 1 for signed, b = version) - /// - SignatureType (if the payload is signed) - /// - Address - /// - Signature - /// - Extra fields - /// - Extrinsic call bytes - pub fn bytes(&self) -> &[u8] { - &self.bytes - } - /// Return only the bytes representing this extrinsic call: - /// - First byte is the pallet index - /// - Second byte is the variant (call) index - /// - Followed by field bytes. - /// - /// # Note - /// - /// Please use [`Self::bytes`] if you want to get all extrinsic bytes. - pub fn call_bytes(&self) -> &[u8] { - &self.bytes[self.call_start_idx..] - } - /// Return the bytes representing the fields stored in this extrinsic. - /// - /// # Note - /// - /// This is a subset of [`Self::call_bytes`] that does not include the - /// first two bytes that denote the pallet index and the variant index. - pub fn field_bytes(&self) -> &[u8] { - &self.call_bytes()[2..] - } - /// Return only the bytes of the address that signed this extrinsic. - /// - /// # Note - /// - /// Returns `None` if the extrinsic is not signed. - pub fn address_bytes(&self) -> Option<&[u8]> { - self.signed_details - .as_ref() - .map(|e| &self.bytes[e.address_start_idx..e.address_end_idx]) - } - /// Returns Some(signature_bytes) if the extrinsic was signed otherwise None is returned. - pub fn signature_bytes(&self) -> Option<&[u8]> { - self.signed_details - .as_ref() - .map(|e| &self.bytes[e.address_end_idx..e.signature_end_idx]) - } - /// Returns the signed extension `extra` bytes of the extrinsic. - /// Each signed extension has an `extra` type (May be zero-sized). - /// These bytes are the scale encoded `extra` fields of each signed extension in order of the signed extensions. - /// They do *not* include the `additional` signed bytes that are used as part of the payload that is signed. - /// - /// Note: Returns `None` if the extrinsic is not signed. - pub fn signed_extensions_bytes(&self) -> Option<&[u8]> { - self.signed_details - .as_ref() - .map(|e| &self.bytes[e.signature_end_idx..e.extra_end_idx]) - } - /// Returns `None` if the extrinsic is not signed. - pub fn signed_extensions(&self) -> Option> { - let signed = self.signed_details.as_ref()?; - let extra_bytes = &self - .bytes[signed.signature_end_idx..signed.extra_end_idx]; - Some(ExtrinsicSignedExtensions { - bytes: extra_bytes, - metadata: &self.metadata, - _marker: std::marker::PhantomData, - }) - } - /// The index of the pallet that the extrinsic originated from. - pub fn pallet_index(&self) -> u8 { - self.pallet_index - } - /// The index of the extrinsic variant that the extrinsic originated from. - pub fn variant_index(&self) -> u8 { - self.variant_index - } - /// The name of the pallet from whence the extrinsic originated. - pub fn pallet_name(&self) -> Result<&str, Error> { - Ok(self.extrinsic_metadata()?.pallet.name()) - } - /// The name of the call (ie the name of the variant that it corresponds to). - pub fn variant_name(&self) -> Result<&str, Error> { - Ok(&self.extrinsic_metadata()?.variant.name) - } - /// Fetch the metadata for this extrinsic. - pub fn extrinsic_metadata(&self) -> Result { - let pallet = self.metadata.pallet_by_index_err(self.pallet_index())?; - let variant = pallet - .call_variant_by_index(self.variant_index()) - .ok_or_else(|| MetadataError::VariantIndexNotFound( - self.variant_index(), - ))?; - Ok(ExtrinsicMetadataDetails { - pallet, - variant, - }) - } - /// Decode and provide the extrinsic fields back in the form of a [`scale_value::Composite`] - /// type which represents the named or unnamed fields that were present in the extrinsic. - pub fn field_values( - &self, - ) -> Result, Error> { - let bytes = &mut self.field_bytes(); - let extrinsic_metadata = self.extrinsic_metadata()?; - let mut fields = extrinsic_metadata - .variant - .fields - .iter() - .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); - let decoded = >::decode_as_fields(bytes, &mut fields, self.metadata.types())?; - Ok(decoded) - } - /// Attempt to decode these [`ExtrinsicDetails`] into a type representing the extrinsic fields. - /// Such types are exposed in the codegen as `pallet_name::calls::types::CallName` types. - pub fn as_extrinsic(&self) -> Result, Error> { - let extrinsic_metadata = self.extrinsic_metadata()?; - if extrinsic_metadata.pallet.name() == E::PALLET - && extrinsic_metadata.variant.name == E::CALL - { - let mut fields = extrinsic_metadata - .variant - .fields - .iter() - .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); - let decoded = E::decode_as_fields( - &mut self.field_bytes(), - &mut fields, - self.metadata.types(), - )?; - Ok(Some(decoded)) - } else { - Ok(None) - } - } - /// Attempt to decode these [`ExtrinsicDetails`] into an outer call enum type (which includes - /// the pallet and extrinsic enum variants as well as the extrinsic fields). A compatible - /// type for this is exposed via static codegen as a root level `Call` type. - pub fn as_root_extrinsic(&self) -> Result { - let decoded = E::decode_as_type( - &mut &self.call_bytes()[..], - self.metadata.outer_enums().call_enum_ty(), - self.metadata.types(), - )?; - Ok(decoded) - } - } - impl ExtrinsicDetails - where - T: Config, - C: OnlineClientT, - { - /// The events associated with the extrinsic. - pub async fn events(&self) -> Result, Error> { - let events = get_events( - &self.client, - self.block_hash, - &self.cached_events, - ) - .await?; - let ext_hash = T::Hasher::hash_of(&self.bytes); - Ok(ExtrinsicEvents::new(ext_hash, self.index, events)) - } - } - /// A Static Extrinsic found in a block coupled with it's details. - pub struct FoundExtrinsic { - pub details: ExtrinsicDetails, - pub value: E, - } - /// Details for the given extrinsic plucked from the metadata. - pub struct ExtrinsicMetadataDetails<'a> { - pub pallet: PalletMetadata<'a>, - pub variant: &'a scale_info::Variant, - } - /// The type IDs extracted from the metadata that represent the - /// generic type parameters passed to the `UncheckedExtrinsic` from - /// the substrate-based chain. - pub(crate) struct ExtrinsicPartTypeIds { - /// The address (source) of the extrinsic. - address: u32, - /// The extrinsic call type. - _call: u32, - /// The signature of the extrinsic. - signature: u32, - /// The extra parameters of the extrinsic. - extra: u32, - } - #[automatically_derived] - impl ::core::fmt::Debug for ExtrinsicPartTypeIds { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field4_finish( - f, - "ExtrinsicPartTypeIds", - "address", - &self.address, - "_call", - &self._call, - "signature", - &self.signature, - "extra", - &&self.extra, - ) - } - } - #[automatically_derived] - impl ::core::marker::Copy for ExtrinsicPartTypeIds {} - #[automatically_derived] - impl ::core::clone::Clone for ExtrinsicPartTypeIds { - #[inline] - fn clone(&self) -> ExtrinsicPartTypeIds { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - impl ExtrinsicPartTypeIds { - /// Extract the generic type parameters IDs from the extrinsic type. - pub(crate) fn new(metadata: &Metadata) -> Result { - Ok(ExtrinsicPartTypeIds { - address: metadata.extrinsic().address_ty(), - _call: metadata.extrinsic().call_ty(), - signature: metadata.extrinsic().signature_ty(), - extra: metadata.extrinsic().extra_ty(), - }) - } - } - /// The events associated with a given extrinsic. - #[derivative(Debug(bound = ""))] - pub struct ExtrinsicEvents { - ext_hash: T::Hash, - idx: u32, - events: events::Events, - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for ExtrinsicEvents { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - ExtrinsicEvents { - ext_hash: ref __arg_0, - idx: ref __arg_1, - events: ref __arg_2, - } => { - let mut __debug_trait_builder = __f - .debug_struct("ExtrinsicEvents"); - let _ = __debug_trait_builder.field("ext_hash", &&(*__arg_0)); - let _ = __debug_trait_builder.field("idx", &&(*__arg_1)); - let _ = __debug_trait_builder.field("events", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - impl ExtrinsicEvents { - pub(crate) fn new( - ext_hash: T::Hash, - idx: u32, - events: events::Events, - ) -> Self { - Self { ext_hash, idx, events } - } - /// Return the hash of the block that the extrinsic is in. - pub fn block_hash(&self) -> T::Hash { - self.events.block_hash() - } - /// The index of the extrinsic that these events are produced from. - pub fn extrinsic_index(&self) -> u32 { - self.idx - } - /// Return the hash of the extrinsic. - pub fn extrinsic_hash(&self) -> T::Hash { - self.ext_hash - } - /// Return all of the events in the block that the extrinsic is in. - pub fn all_events_in_block(&self) -> &events::Events { - &self.events - } - /// Iterate over all of the raw events associated with this transaction. - /// - /// This works in the same way that [`events::Events::iter()`] does, with the - /// exception that it filters out events not related to the submitted extrinsic. - pub fn iter( - &self, - ) -> impl Iterator, Error>> + '_ { - self.events - .iter() - .filter(|ev| { - ev.as_ref() - .map(|ev| { - ev.phase() == events::Phase::ApplyExtrinsic(self.idx) - }) - .unwrap_or(true) - }) - } - /// Find all of the transaction events matching the event type provided as a generic parameter. - /// - /// This works in the same way that [`events::Events::find()`] does, with the - /// exception that it filters out events not related to the submitted extrinsic. - pub fn find( - &self, - ) -> impl Iterator> + '_ { - self.iter() - .filter_map(|ev| { - ev.and_then(|ev| ev.as_event::().map_err(Into::into)) - .transpose() - }) - } - /// Iterate through the transaction events using metadata to dynamically decode and skip - /// them, and return the first event found which decodes to the provided `Ev` type. - /// - /// This works in the same way that [`events::Events::find_first()`] does, with the - /// exception that it ignores events not related to the submitted extrinsic. - pub fn find_first( - &self, - ) -> Result, Error> { - self.find::().next().transpose() - } - /// Iterate through the transaction events using metadata to dynamically decode and skip - /// them, and return the last event found which decodes to the provided `Ev` type. - /// - /// This works in the same way that [`events::Events::find_last()`] does, with the - /// exception that it ignores events not related to the submitted extrinsic. - pub fn find_last( - &self, - ) -> Result, Error> { - self.find::().last().transpose() - } - /// Find an event in those associated with this transaction. Returns true if it was found. - /// - /// This works in the same way that [`events::Events::has()`] does, with the - /// exception that it ignores events not related to the submitted extrinsic. - pub fn has(&self) -> Result { - Ok(self.find::().next().transpose()?.is_some()) - } - } - /// The signed extensions of an extrinsic. - pub struct ExtrinsicSignedExtensions<'a, T: Config> { - bytes: &'a [u8], - metadata: &'a Metadata, - _marker: std::marker::PhantomData, - } - #[automatically_derived] - impl<'a, T: ::core::fmt::Debug + Config> ::core::fmt::Debug - for ExtrinsicSignedExtensions<'a, T> { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "ExtrinsicSignedExtensions", - "bytes", - &self.bytes, - "metadata", - &self.metadata, - "_marker", - &&self._marker, - ) - } - } - #[automatically_derived] - impl<'a, T: ::core::clone::Clone + Config> ::core::clone::Clone - for ExtrinsicSignedExtensions<'a, T> { - #[inline] - fn clone(&self) -> ExtrinsicSignedExtensions<'a, T> { - ExtrinsicSignedExtensions { - bytes: ::core::clone::Clone::clone(&self.bytes), - metadata: ::core::clone::Clone::clone(&self.metadata), - _marker: ::core::clone::Clone::clone(&self._marker), - } - } - } - impl<'a, T: Config> ExtrinsicSignedExtensions<'a, T> { - /// Returns an iterator over each of the signed extension details of the extrinsic. - /// If the decoding of any signed extension fails, an error item is yielded and the iterator stops. - pub fn iter( - &self, - ) -> impl Iterator, Error>> { - let signed_extension_types = self - .metadata - .extrinsic() - .signed_extensions(); - let num_signed_extensions = signed_extension_types.len(); - let bytes = self.bytes; - let mut index = 0; - let mut byte_start_idx = 0; - let metadata = &self.metadata; - std::iter::from_fn(move || { - if index == num_signed_extensions { - return None; - } - let extension = &signed_extension_types[index]; - let ty_id = extension.extra_ty(); - let cursor = &mut &bytes[byte_start_idx..]; - if let Err(err) - = scale_decode::visitor::decode_with_visitor( - cursor, - ty_id, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(|e| Error::Decode(e.into())) - { - index = num_signed_extensions; - return Some(Err(err)); - } - let byte_end_idx = bytes.len() - cursor.len(); - let bytes = &bytes[byte_start_idx..byte_end_idx]; - byte_start_idx = byte_end_idx; - index += 1; - Some( - Ok(ExtrinsicSignedExtension { - bytes, - ty_id, - identifier: extension.identifier(), - metadata, - _marker: std::marker::PhantomData, - }), - ) - }) - } - /// Searches through all signed extensions to find a specific one. - /// If the Signed Extension is not found `Ok(None)` is returned. - /// If the Signed Extension is found but decoding failed `Err(_)` is returned. - pub fn find>( - &self, - ) -> Result, Error> { - for ext in self.iter() { - let ext = ext?; - match ext.as_signed_extension::() { - Ok(Some(e)) => return Ok(Some(e)), - Ok(None) => continue, - Err(e) => return Err(e), - } - } - Ok(None) - } - /// The tip of an extrinsic, extracted from the ChargeTransactionPayment or ChargeAssetTxPayment - /// signed extension, depending on which is present. - /// - /// Returns `None` if `tip` was not found or decoding failed. - pub fn tip(&self) -> Option { - self.find::() - .ok() - .flatten() - .map(|e| e.tip()) - .or_else(|| { - self.find::>() - .ok() - .flatten() - .map(|e| e.tip()) - }) - } - /// The nonce of the account that submitted the extrinsic, extracted from the CheckNonce signed extension. - /// - /// Returns `None` if `nonce` was not found or decoding failed. - pub fn nonce(&self) -> Option { - self.find::().ok()? - } - } - /// A single signed extension - pub struct ExtrinsicSignedExtension<'a, T: Config> { - bytes: &'a [u8], - ty_id: u32, - identifier: &'a str, - metadata: &'a Metadata, - _marker: std::marker::PhantomData, - } - #[automatically_derived] - impl<'a, T: ::core::fmt::Debug + Config> ::core::fmt::Debug - for ExtrinsicSignedExtension<'a, T> { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "ExtrinsicSignedExtension", - "bytes", - &self.bytes, - "ty_id", - &self.ty_id, - "identifier", - &self.identifier, - "metadata", - &self.metadata, - "_marker", - &&self._marker, - ) - } - } - #[automatically_derived] - impl<'a, T: ::core::clone::Clone + Config> ::core::clone::Clone - for ExtrinsicSignedExtension<'a, T> { - #[inline] - fn clone(&self) -> ExtrinsicSignedExtension<'a, T> { - ExtrinsicSignedExtension { - bytes: ::core::clone::Clone::clone(&self.bytes), - ty_id: ::core::clone::Clone::clone(&self.ty_id), - identifier: ::core::clone::Clone::clone(&self.identifier), - metadata: ::core::clone::Clone::clone(&self.metadata), - _marker: ::core::clone::Clone::clone(&self._marker), - } - } - } - impl<'a, T: Config> ExtrinsicSignedExtension<'a, T> { - /// The bytes representing this signed extension. - pub fn bytes(&self) -> &'a [u8] { - self.bytes - } - /// The name of the signed extension. - pub fn name(&self) -> &'a str { - self.identifier - } - /// The type id of the signed extension. - pub fn type_id(&self) -> u32 { - self.ty_id - } - /// Signed Extension as a [`scale_value::Value`] - pub fn value(&self) -> Result { - self.as_type() - } - /// Decodes the bytes of this Signed Extension into its associated `Decoded` type. - /// Returns `Ok(None)` if the data we have doesn't match the Signed Extension we're asking to - /// decode with. - pub fn as_signed_extension>( - &self, - ) -> Result, Error> { - if !S::matches(self.identifier, self.ty_id, self.metadata.types()) { - return Ok(None); - } - self.as_type::().map(Some) - } - fn as_type(&self) -> Result { - let value = E::decode_as_type( - &mut &self.bytes[..], - self.ty_id, - self.metadata.types(), - )?; - Ok(value) - } - } - } - /// A reference to a block. - pub use crate::backend::BlockRef; - pub use block_types::Block; - pub use blocks_client::BlocksClient; - pub use extrinsic_types::{ - ExtrinsicDetails, ExtrinsicEvents, ExtrinsicSignedExtension, - ExtrinsicSignedExtensions, Extrinsics, StaticExtrinsic, - }; - pub(crate) use block_types::get_account_nonce; -} -pub mod client { - //! This module provides two clients that can be used to work with - //! transactions, storage and events. The [`OfflineClient`] works - //! entirely offline and can be passed to any function that doesn't - //! require network access. The [`OnlineClient`] requires network - //! access. - mod offline_client { - use crate::custom_values::CustomValuesClient; - use crate::{ - backend::RuntimeVersion, blocks::BlocksClient, constants::ConstantsClient, - events::EventsClient, runtime_api::RuntimeApiClient, storage::StorageClient, - tx::TxClient, Config, Metadata, - }; - use derivative::Derivative; - use std::sync::Arc; - /// A trait representing a client that can perform - /// offline-only actions. - pub trait OfflineClientT: Clone + Send + Sync + 'static { - /// Return the provided [`Metadata`]. - fn metadata(&self) -> Metadata; - /// Return the provided genesis hash. - fn genesis_hash(&self) -> T::Hash; - /// Return the provided [`RuntimeVersion`]. - fn runtime_version(&self) -> RuntimeVersion; - /// Work with transactions. - fn tx(&self) -> TxClient { - TxClient::new(self.clone()) - } - /// Work with events. - fn events(&self) -> EventsClient { - EventsClient::new(self.clone()) - } - /// Work with storage. - fn storage(&self) -> StorageClient { - StorageClient::new(self.clone()) - } - /// Access constants. - fn constants(&self) -> ConstantsClient { - ConstantsClient::new(self.clone()) - } - /// Work with blocks. - fn blocks(&self) -> BlocksClient { - BlocksClient::new(self.clone()) - } - /// Work with runtime API. - fn runtime_api(&self) -> RuntimeApiClient { - RuntimeApiClient::new(self.clone()) - } - /// Work this custom types. - fn custom_values(&self) -> CustomValuesClient { - CustomValuesClient::new(self.clone()) - } - } - /// A client that is capable of performing offline-only operations. - /// Can be constructed as long as you can populate the required fields. - #[derivative(Debug(bound = ""), Clone(bound = ""))] - pub struct OfflineClient { - inner: Arc>, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for OfflineClient { - fn clone(&self) -> Self { - match *self { - OfflineClient { inner: ref __arg_0 } => { - OfflineClient { - inner: (*__arg_0).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for OfflineClient { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - OfflineClient { inner: ref __arg_0 } => { - let mut __debug_trait_builder = __f - .debug_struct("OfflineClient"); - let _ = __debug_trait_builder.field("inner", &&(*__arg_0)); - __debug_trait_builder.finish() - } - } - } - } - #[derivative(Debug(bound = ""), Clone(bound = ""))] - struct Inner { - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: Metadata, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Inner { - fn clone(&self) -> Self { - match *self { - Inner { - genesis_hash: ref __arg_0, - runtime_version: ref __arg_1, - metadata: ref __arg_2, - } => { - Inner { - genesis_hash: (*__arg_0).clone(), - runtime_version: (*__arg_1).clone(), - metadata: (*__arg_2).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Inner { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Inner { - genesis_hash: ref __arg_0, - runtime_version: ref __arg_1, - metadata: ref __arg_2, - } => { - let mut __debug_trait_builder = __f.debug_struct("Inner"); - let _ = __debug_trait_builder - .field("genesis_hash", &&(*__arg_0)); - let _ = __debug_trait_builder - .field("runtime_version", &&(*__arg_1)); - let _ = __debug_trait_builder.field("metadata", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - impl OfflineClient { - /// Construct a new [`OfflineClient`], providing - /// the necessary runtime and compile-time arguments. - pub fn new( - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: impl Into, - ) -> OfflineClient { - OfflineClient { - inner: Arc::new(Inner { - genesis_hash, - runtime_version, - metadata: metadata.into(), - }), - } - } - /// Return the genesis hash. - pub fn genesis_hash(&self) -> T::Hash { - self.inner.genesis_hash - } - /// Return the runtime version. - pub fn runtime_version(&self) -> RuntimeVersion { - self.inner.runtime_version.clone() - } - /// Return the [`Metadata`] used in this client. - pub fn metadata(&self) -> Metadata { - self.inner.metadata.clone() - } - /// Work with transactions. - pub fn tx(&self) -> TxClient { - >::tx(self) - } - /// Work with events. - pub fn events(&self) -> EventsClient { - >::events(self) - } - /// Work with storage. - pub fn storage(&self) -> StorageClient { - >::storage(self) - } - /// Access constants. - pub fn constants(&self) -> ConstantsClient { - >::constants(self) - } - /// Access custom types - pub fn custom_values(&self) -> CustomValuesClient { - >::custom_values(self) - } - } - impl OfflineClientT for OfflineClient { - fn genesis_hash(&self) -> T::Hash { - self.genesis_hash() - } - fn runtime_version(&self) -> RuntimeVersion { - self.runtime_version() - } - fn metadata(&self) -> Metadata { - self.metadata() - } - } - impl<'a, T: Config> From<&'a OfflineClient> for OfflineClient { - fn from(c: &'a OfflineClient) -> Self { - c.clone() - } - } - } - mod online_client { - use super::{OfflineClient, OfflineClientT}; - use crate::custom_values::CustomValuesClient; - use crate::{ - backend::{ - legacy::LegacyBackend, rpc::RpcClient, Backend, BackendExt, - RuntimeVersion, StreamOfResults, - }, - blocks::{BlockRef, BlocksClient}, - constants::ConstantsClient, error::Error, events::EventsClient, - runtime_api::RuntimeApiClient, storage::StorageClient, tx::TxClient, Config, - Metadata, - }; - use derivative::Derivative; - use futures::future; - use std::sync::{Arc, RwLock}; - /// A trait representing a client that can perform - /// online actions. - pub trait OnlineClientT: OfflineClientT { - /// Return a backend that can be used to communicate with a node. - fn backend(&self) -> &dyn Backend; - } - /// A client that can be used to perform API calls (that is, either those - /// requiring an [`OfflineClientT`] or those requiring an [`OnlineClientT`]). - #[derivative(Clone(bound = ""))] - pub struct OnlineClient { - inner: Arc>>, - backend: Arc>, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for OnlineClient { - fn clone(&self) -> Self { - match *self { - OnlineClient { inner: ref __arg_0, backend: ref __arg_1 } => { - OnlineClient { - inner: (*__arg_0).clone(), - backend: (*__arg_1).clone(), - } - } - } - } - } - #[derivative(Debug(bound = ""))] - struct Inner { - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: Metadata, - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Inner { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Inner { - genesis_hash: ref __arg_0, - runtime_version: ref __arg_1, - metadata: ref __arg_2, - } => { - let mut __debug_trait_builder = __f.debug_struct("Inner"); - let _ = __debug_trait_builder - .field("genesis_hash", &&(*__arg_0)); - let _ = __debug_trait_builder - .field("runtime_version", &&(*__arg_1)); - let _ = __debug_trait_builder.field("metadata", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - impl std::fmt::Debug for OnlineClient { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Client") - .field("rpc", &"RpcClient") - .field("inner", &self.inner) - .finish() - } - } - #[cfg(feature = "jsonrpsee")] - impl OnlineClient { - /// Construct a new [`OnlineClient`] using default settings which - /// point to a locally running node on `ws://127.0.0.1:9944`. - pub async fn new() -> Result, Error> { - let url = "ws://127.0.0.1:9944"; - OnlineClient::from_url(url).await - } - /// Construct a new [`OnlineClient`], providing a URL to connect to. - pub async fn from_url( - url: impl AsRef, - ) -> Result, Error> { - crate::utils::validate_url_is_secure(url.as_ref())?; - OnlineClient::from_insecure_url(url).await - } - /// Construct a new [`OnlineClient`], providing a URL to connect to. - /// - /// Allows insecure URLs without SSL encryption, e.g. (http:// and ws:// URLs). - pub async fn from_insecure_url( - url: impl AsRef, - ) -> Result, Error> { - let client = RpcClient::from_insecure_url(url).await?; - let backend = LegacyBackend::new(client); - OnlineClient::from_backend(Arc::new(backend)).await - } - } - impl OnlineClient { - /// Construct a new [`OnlineClient`] by providing an [`RpcClient`] to drive the connection. - /// This will use the current default [`Backend`], which may change in future releases. - pub async fn from_rpc_client( - rpc_client: RpcClient, - ) -> Result, Error> { - let backend = Arc::new(LegacyBackend::new(rpc_client)); - OnlineClient::from_backend(backend).await - } - /// Construct a new [`OnlineClient`] by providing an RPC client along with the other - /// necessary details. This will use the current default [`Backend`], which may change - /// in future releases. - /// - /// # Warning - /// - /// This is considered the most primitive and also error prone way to - /// instantiate a client; the genesis hash, metadata and runtime version provided will - /// entirely determine which node and blocks this client will be able to interact with, - /// and whether it will be able to successfully do things like submit transactions. - /// - /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate - /// a client. - pub fn from_rpc_client_with( - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: impl Into, - rpc_client: RpcClient, - ) -> Result, Error> { - let backend = Arc::new(LegacyBackend::new(rpc_client)); - OnlineClient::from_backend_with( - genesis_hash, - runtime_version, - metadata, - backend, - ) - } - /// Construct a new [`OnlineClient`] by providing an underlying [`Backend`] - /// implementation to power it. Other details will be obtained from the chain. - pub async fn from_backend>( - backend: Arc, - ) -> Result, Error> { - let latest_block = backend.latest_finalized_block_ref().await?; - let (genesis_hash, runtime_version, metadata) = future::join3( - backend.genesis_hash(), - backend.current_runtime_version(), - OnlineClient::fetch_metadata(&*backend, latest_block.hash()), - ) - .await; - OnlineClient::from_backend_with( - genesis_hash?, - runtime_version?, - metadata?, - backend, - ) - } - /// Construct a new [`OnlineClient`] by providing all of the underlying details needed - /// to make it work. - /// - /// # Warning - /// - /// This is considered the most primitive and also error prone way to - /// instantiate a client; the genesis hash, metadata and runtime version provided will - /// entirely determine which node and blocks this client will be able to interact with, - /// and whether it will be able to successfully do things like submit transactions. - /// - /// If you're unsure what you're doing, prefer one of the alternate methods to instantiate - /// a client. - pub fn from_backend_with>( - genesis_hash: T::Hash, - runtime_version: RuntimeVersion, - metadata: impl Into, - backend: Arc, - ) -> Result, Error> { - Ok(OnlineClient { - inner: Arc::new( - RwLock::new(Inner { - genesis_hash, - runtime_version, - metadata: metadata.into(), - }), - ), - backend, - }) - } - /// Fetch the metadata from substrate using the runtime API. - async fn fetch_metadata( - backend: &dyn Backend, - block_hash: T::Hash, - ) -> Result { - #[cfg(not(feature = "unstable-metadata"))] - OnlineClient::fetch_latest_stable_metadata(backend, block_hash).await - } - /// Fetch the latest stable metadata from the node. - async fn fetch_latest_stable_metadata( - backend: &dyn Backend, - block_hash: T::Hash, - ) -> Result { - const V15_METADATA_VERSION: u32 = 15; - if let Ok(bytes) - = backend.metadata_at_version(V15_METADATA_VERSION, block_hash).await - { - return Ok(bytes); - } - backend.legacy_metadata(block_hash).await - } - /// Create an object which can be used to keep the runtime up to date - /// in a separate thread. - /// - /// # Example - /// - /// ```no_run - /// # #[tokio::main] - /// # async fn main() { - /// use subxt::{ OnlineClient, PolkadotConfig }; - /// - /// let client = OnlineClient::::new().await.unwrap(); - /// - /// // high level API. - /// - /// let update_task = client.updater(); - /// tokio::spawn(async move { - /// update_task.perform_runtime_updates().await; - /// }); - /// - /// - /// // low level API. - /// - /// let updater = client.updater(); - /// tokio::spawn(async move { - /// let mut update_stream = updater.runtime_updates().await.unwrap(); - /// - /// while let Some(Ok(update)) = update_stream.next().await { - /// let version = update.runtime_version().spec_version; - /// - /// match updater.apply_update(update) { - /// Ok(()) => { - /// println!("Upgrade to version: {} successful", version) - /// } - /// Err(e) => { - /// println!("Upgrade to version {} failed {:?}", version, e); - /// } - /// }; - /// } - /// }); - /// # } - /// ``` - pub fn updater(&self) -> ClientRuntimeUpdater { - ClientRuntimeUpdater(self.clone()) - } - /// Return the [`Metadata`] used in this client. - pub fn metadata(&self) -> Metadata { - let inner = self.inner.read().expect("shouldn't be poisoned"); - inner.metadata.clone() - } - /// Change the [`Metadata`] used in this client. - /// - /// # Warning - /// - /// Setting custom metadata may leave Subxt unable to work with certain blocks, - /// subscribe to latest blocks or submit valid transactions. - pub fn set_metadata(&self, metadata: impl Into) { - let mut inner = self.inner.write().expect("shouldn't be poisoned"); - inner.metadata = metadata.into(); - } - /// Return the genesis hash. - pub fn genesis_hash(&self) -> T::Hash { - let inner = self.inner.read().expect("shouldn't be poisoned"); - inner.genesis_hash - } - /// Change the genesis hash used in this client. - /// - /// # Warning - /// - /// Setting a custom genesis hash may leave Subxt unable to - /// submit valid transactions. - pub fn set_genesis_hash(&self, genesis_hash: T::Hash) { - let mut inner = self.inner.write().expect("shouldn't be poisoned"); - inner.genesis_hash = genesis_hash; - } - /// Return the runtime version. - pub fn runtime_version(&self) -> RuntimeVersion { - let inner = self.inner.read().expect("shouldn't be poisoned"); - inner.runtime_version.clone() - } - /// Change the [`RuntimeVersion`] used in this client. - /// - /// # Warning - /// - /// Setting a custom runtime version may leave Subxt unable to - /// submit valid transactions. - pub fn set_runtime_version(&self, runtime_version: RuntimeVersion) { - let mut inner = self.inner.write().expect("shouldn't be poisoned"); - inner.runtime_version = runtime_version; - } - /// Return an RPC client to make raw requests with. - pub fn backend(&self) -> &dyn Backend { - &*self.backend - } - /// Return an offline client with the same configuration as this. - pub fn offline(&self) -> OfflineClient { - let inner = self.inner.read().expect("shouldn't be poisoned"); - OfflineClient::new( - inner.genesis_hash, - inner.runtime_version.clone(), - inner.metadata.clone(), - ) - } - /// Work with transactions. - pub fn tx(&self) -> TxClient { - >::tx(self) - } - /// Work with events. - pub fn events(&self) -> EventsClient { - >::events(self) - } - /// Work with storage. - pub fn storage(&self) -> StorageClient { - >::storage(self) - } - /// Access constants. - pub fn constants(&self) -> ConstantsClient { - >::constants(self) - } - /// Access custom types. - pub fn custom_values(&self) -> CustomValuesClient { - >::custom_values(self) - } - /// Work with blocks. - pub fn blocks(&self) -> BlocksClient { - >::blocks(self) - } - /// Work with runtime API. - pub fn runtime_api(&self) -> RuntimeApiClient { - >::runtime_api(self) - } - } - impl OfflineClientT for OnlineClient { - fn metadata(&self) -> Metadata { - self.metadata() - } - fn genesis_hash(&self) -> T::Hash { - self.genesis_hash() - } - fn runtime_version(&self) -> RuntimeVersion { - self.runtime_version() - } - } - impl OnlineClientT for OnlineClient { - fn backend(&self) -> &dyn Backend { - &*self.backend - } - } - /// Client wrapper for performing runtime updates. See [`OnlineClient::updater()`] - /// for example usage. - pub struct ClientRuntimeUpdater(OnlineClient); - impl ClientRuntimeUpdater { - fn is_runtime_version_different(&self, new: &RuntimeVersion) -> bool { - let curr = self.0.inner.read().expect("shouldn't be poisoned"); - &curr.runtime_version != new - } - fn do_update(&self, update: Update) { - let mut writable = self.0.inner.write().expect("shouldn't be poisoned"); - writable.metadata = update.metadata; - writable.runtime_version = update.runtime_version; - } - /// Tries to apply a new update. - pub fn apply_update(&self, update: Update) -> Result<(), UpgradeError> { - if !self.is_runtime_version_different(&update.runtime_version) { - return Err(UpgradeError::SameVersion); - } - self.do_update(update); - Ok(()) - } - /// Performs runtime updates indefinitely unless encountering an error. - /// - /// *Note:* This will run indefinitely until it errors, so the typical usage - /// would be to run it in a separate background task. - pub async fn perform_runtime_updates(&self) -> Result<(), Error> { - let mut runtime_version_stream = self.runtime_updates().await?; - while let Some(update) = runtime_version_stream.next().await { - let update = update?; - let _ = self.apply_update(update); - } - Ok(()) - } - /// Low-level API to get runtime updates as a stream but it's doesn't check if the - /// runtime version is newer or updates the runtime. - /// - /// Instead that's up to the user of this API to decide when to update and - /// to perform the actual updating. - pub async fn runtime_updates( - &self, - ) -> Result, Error> { - let stream = self.0.backend().stream_runtime_version().await?; - Ok(RuntimeUpdaterStream { - stream, - client: self.0.clone(), - }) - } - } - /// Stream to perform runtime upgrades. - pub struct RuntimeUpdaterStream { - stream: StreamOfResults, - client: OnlineClient, - } - impl RuntimeUpdaterStream { - /// Wait for the next runtime update. - pub async fn next(&mut self) -> Option> { - let runtime_version = match self.stream.next().await? { - Ok(runtime_version) => runtime_version, - Err(err) => return Some(Err(err)), - }; - let at = match wait_runtime_upgrade_in_finalized_block( - &self.client, - &runtime_version, - ) - .await? - { - Ok(at) => at, - Err(err) => return Some(Err(err)), - }; - let metadata = match OnlineClient::fetch_metadata( - self.client.backend(), - at.hash(), - ) - .await - { - Ok(metadata) => metadata, - Err(err) => return Some(Err(err)), - }; - Some( - Ok(Update { - metadata, - runtime_version, - }), - ) - } - } - /// Error that can occur during upgrade. - #[non_exhaustive] - pub enum UpgradeError { - /// The version is the same as the current version. - SameVersion, - } - #[automatically_derived] - impl ::core::fmt::Debug for UpgradeError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "SameVersion") - } - } - #[automatically_derived] - impl ::core::clone::Clone for UpgradeError { - #[inline] - fn clone(&self) -> UpgradeError { - UpgradeError::SameVersion - } - } - /// Represents the state when a runtime upgrade occurred. - pub struct Update { - runtime_version: RuntimeVersion, - metadata: Metadata, - } - impl Update { - /// Get the runtime version. - pub fn runtime_version(&self) -> &RuntimeVersion { - &self.runtime_version - } - /// Get the metadata. - pub fn metadata(&self) -> &Metadata { - &self.metadata - } - } - /// Helper to wait until the runtime upgrade is applied on at finalized block. - async fn wait_runtime_upgrade_in_finalized_block( - client: &OnlineClient, - runtime_version: &RuntimeVersion, - ) -> Option, Error>> { - use scale_value::At; - let mut block_sub = match client - .backend() - .stream_finalized_block_headers() - .await - { - Ok(s) => s, - Err(err) => return Some(Err(err)), - }; - let block_ref = loop { - let (_, block_ref) = match block_sub.next().await? { - Ok(n) => n, - Err(err) => return Some(Err(err)), - }; - let key: Vec = ::alloc::vec::Vec::new(); - let addr = crate::dynamic::storage("System", "LastRuntimeUpgrade", key); - let chunk = match client - .storage() - .at(block_ref.hash()) - .fetch(&addr) - .await - { - Ok(Some(v)) => v, - Ok(None) => { - ::core::panicking::panic_fmt( - format_args!( - "internal error: entered unreachable code: {0}", - format_args!("The storage item `system::lastRuntimeUpgrade` should always exist") - ), - ); - } - Err(e) => return Some(Err(e)), - }; - let scale_val = match chunk.to_value() { - Ok(v) => v, - Err(e) => return Some(Err(e)), - }; - let Some(Ok(spec_version)) = scale_val - .at("spec_version") - .and_then(|v| v.as_u128()) - .map(u32::try_from) else { - return Some( - Err( - Error::Other( - "Decoding `RuntimeVersion::spec_version` as u32 failed" - .to_string(), - ), - ), - ); - }; - if spec_version == runtime_version.spec_version { - break block_ref; - } - }; - Some(Ok(block_ref)) - } - } - pub use offline_client::{OfflineClient, OfflineClientT}; - pub use online_client::{ - ClientRuntimeUpdater, OnlineClient, OnlineClientT, RuntimeUpdaterStream, Update, - UpgradeError, - }; -} -pub mod config { - //! This module provides a [`Config`] type, which is used to define various - //! types that are important in order to speak to a particular chain. - //! [`SubstrateConfig`] provides a default set of these types suitable for the - //! default Substrate node implementation, and [`PolkadotConfig`] for a - //! Polkadot node. - mod default_extrinsic_params { - use super::{signed_extensions, ExtrinsicParams}; - use super::{Config, Header}; - /// The default [`super::ExtrinsicParams`] implementation understands common signed extensions - /// and how to apply them to a given chain. - pub type DefaultExtrinsicParams = signed_extensions::AnyOf< - T, - ( - signed_extensions::CheckSpecVersion, - signed_extensions::CheckTxVersion, - signed_extensions::CheckNonce, - signed_extensions::CheckGenesis, - signed_extensions::CheckMortality, - signed_extensions::ChargeAssetTxPayment, - signed_extensions::ChargeTransactionPayment, - ), - >; - /// A builder that outputs the set of [`super::ExtrinsicParams::OtherParams`] required for - /// [`DefaultExtrinsicParams`]. This may expose methods that aren't applicable to the current - /// chain; such values will simply be ignored if so. - pub struct DefaultExtrinsicParamsBuilder { - /// `None` means the tx will be immortal. - mortality: Option>, - /// `None` means we'll use the native token. - tip_of_asset_id: Option, - tip: u128, - tip_of: u128, - } - struct Mortality { - /// Block hash that mortality starts from - checkpoint_hash: Hash, - /// Block number that mortality starts from (must - checkpoint_number: u64, - /// How many blocks the tx is mortal for - period: u64, - } - impl Default for DefaultExtrinsicParamsBuilder { - fn default() -> Self { - Self { - mortality: None, - tip: 0, - tip_of: 0, - tip_of_asset_id: None, - } - } - } - impl DefaultExtrinsicParamsBuilder { - /// Configure new extrinsic params. We default to providing no tip - /// and using an immortal transaction unless otherwise configured - pub fn new() -> Self { - Default::default() - } - /// Make the transaction mortal, given a block header that it should be mortal from, - /// and the number of blocks (roughly; it'll be rounded to a power of two) that it will - /// be mortal for. - pub fn mortal(mut self, from_block: &T::Header, for_n_blocks: u64) -> Self { - self - .mortality = Some(Mortality { - checkpoint_hash: from_block.hash(), - checkpoint_number: from_block.number().into(), - period: for_n_blocks, - }); - self - } - /// Make the transaction mortal, given a block number and block hash (which must both point to - /// the same block) that it should be mortal from, and the number of blocks (roughly; it'll be - /// rounded to a power of two) that it will be mortal for. - /// - /// Prefer to use [`DefaultExtrinsicParamsBuilder::mortal()`], which ensures that the block hash - /// and number align. - pub fn mortal_unchecked( - mut self, - from_block_number: u64, - from_block_hash: T::Hash, - for_n_blocks: u64, - ) -> Self { - self - .mortality = Some(Mortality { - checkpoint_hash: from_block_hash, - checkpoint_number: from_block_number, - period: for_n_blocks, - }); - self - } - /// Provide a tip to the block author in the chain's native token. - pub fn tip(mut self, tip: u128) -> Self { - self.tip = tip; - self.tip_of = tip; - self.tip_of_asset_id = None; - self - } - /// Provide a tip to the block author using the token denominated by the `asset_id` provided. This - /// is not applicable on chains which don't use the `ChargeAssetTxPayment` signed extension; in this - /// case, no tip will be given. - pub fn tip_of(mut self, tip: u128, asset_id: T::AssetId) -> Self { - self.tip = 0; - self.tip_of = tip; - self.tip_of_asset_id = Some(asset_id); - self - } - /// Build the extrinsic parameters. - pub fn build( - self, - ) -> as ExtrinsicParams>::OtherParams { - let check_mortality_params = if let Some(mortality) = self.mortality { - signed_extensions::CheckMortalityParams::mortal( - mortality.period, - mortality.checkpoint_number, - mortality.checkpoint_hash, - ) - } else { - signed_extensions::CheckMortalityParams::immortal() - }; - let charge_asset_tx_params = if let Some(asset_id) = self.tip_of_asset_id - { - signed_extensions::ChargeAssetTxPaymentParams::tip_of( - self.tip, - asset_id, - ) - } else { - signed_extensions::ChargeAssetTxPaymentParams::tip(self.tip) - }; - let charge_transaction_params = signed_extensions::ChargeTransactionPaymentParams::tip( - self.tip, - ); - ( - (), - (), - (), - (), - check_mortality_params, - charge_asset_tx_params, - charge_transaction_params, - ) - } - } - } - mod extrinsic_params { - //! This module contains a trait which controls the parameters that must - //! be provided in order to successfully construct an extrinsic. - //! [`crate::config::DefaultExtrinsicParams`] provides a general-purpose - //! implementation of this that will work in many cases. - use crate::{client::OfflineClientT, Config}; - use core::fmt::Debug; - /// An error that can be emitted when trying to construct an instance of [`ExtrinsicParams`], - /// encode data from the instance, or match on signed extensions. - #[non_exhaustive] - pub enum ExtrinsicParamsError { - /// Cannot find a type id in the metadata. The context provides some additional - /// information about the source of the error (eg the signed extension name). - #[error( - "Cannot find type id '{type_id} in the metadata (context: {context})" - )] - MissingTypeId { - /// Type ID. - type_id: u32, - /// Some arbitrary context to help narrow the source of the error. - context: &'static str, - }, - /// A signed extension in use on some chain was not provided. - #[error( - "The chain expects a signed extension with the name {0}, but we did not provide one" - )] - UnknownSignedExtension(String), - /// Some custom error. - #[error("Error constructing extrinsic parameters: {0}")] - Custom(CustomExtrinsicParamsError), - } - #[allow(unused_qualifications)] - impl std::error::Error for ExtrinsicParamsError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for ExtrinsicParamsError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - ExtrinsicParamsError::MissingTypeId { type_id, context } => { - __formatter - .write_fmt( - format_args!( - "Cannot find type id \'{0} in the metadata (context: {1})", - type_id.as_display(), context.as_display() - ), - ) - } - ExtrinsicParamsError::UnknownSignedExtension(_0) => { - __formatter - .write_fmt( - format_args!( - "The chain expects a signed extension with the name {0}, but we did not provide one", - _0.as_display() - ), - ) - } - ExtrinsicParamsError::Custom(_0) => { - __formatter - .write_fmt( - format_args!( - "Error constructing extrinsic parameters: {0}", _0 - .as_display() - ), - ) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ExtrinsicParamsError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - ExtrinsicParamsError::MissingTypeId { - type_id: __self_0, - context: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "MissingTypeId", - "type_id", - __self_0, - "context", - &__self_1, - ) - } - ExtrinsicParamsError::UnknownSignedExtension(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "UnknownSignedExtension", - &__self_0, - ) - } - ExtrinsicParamsError::Custom(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Custom", - &__self_0, - ) - } - } - } - } - /// A custom error. - pub type CustomExtrinsicParamsError = Box< - dyn std::error::Error + Send + Sync + 'static, - >; - impl From for ExtrinsicParamsError { - fn from(value: std::convert::Infallible) -> Self { - match value {} - } - } - impl From for ExtrinsicParamsError { - fn from(value: CustomExtrinsicParamsError) -> Self { - ExtrinsicParamsError::Custom(value) - } - } - /// This trait allows you to configure the "signed extra" and - /// "additional" parameters that are a part of the transaction payload - /// or the signer payload respectively. - pub trait ExtrinsicParams: ExtrinsicParamsEncoder + Sized + 'static { - /// These parameters can be provided to the constructor along with - /// some default parameters that `subxt` understands, in order to - /// help construct your [`ExtrinsicParams`] object. - type OtherParams; - /// Construct a new instance of our [`ExtrinsicParams`]. - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result; - } - /// This trait is expected to be implemented for any [`ExtrinsicParams`], and - /// defines how to encode the "additional" and "extra" params. Both functions - /// are optional and will encode nothing by default. - pub trait ExtrinsicParamsEncoder: 'static { - /// This is expected to SCALE encode the "signed extra" parameters - /// to some buffer that has been provided. These are the parameters - /// which are sent along with the transaction, as well as taken into - /// account when signing the transaction. - fn encode_extra_to(&self, _v: &mut Vec) {} - /// This is expected to SCALE encode the "additional" parameters - /// to some buffer that has been provided. These parameters are _not_ - /// sent along with the transaction, but are taken into account when - /// signing it, meaning the client and node must agree on their values. - fn encode_additional_to(&self, _v: &mut Vec) {} - } - } - pub mod polkadot { - //! Polkadot specific configuration - use super::{Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder}; - pub use crate::utils::{AccountId32, MultiAddress, MultiSignature}; - use crate::SubstrateConfig; - pub use primitive_types::{H256, U256}; - /// Default set of commonly used types by Polkadot nodes. - pub enum PolkadotConfig {} - impl Config for PolkadotConfig { - type Hash = ::Hash; - type AccountId = ::AccountId; - type Address = MultiAddress; - type Signature = ::Signature; - type Hasher = ::Hasher; - type Header = ::Header; - type ExtrinsicParams = PolkadotExtrinsicParams; - type AssetId = u32; - } - /// A struct representing the signed extra and additional parameters required - /// to construct a transaction for a polkadot node. - pub type PolkadotExtrinsicParams = DefaultExtrinsicParams; - /// A builder which leads to [`PolkadotExtrinsicParams`] being constructed. - /// This is what you provide to methods like `sign_and_submit()`. - pub type PolkadotExtrinsicParamsBuilder = DefaultExtrinsicParamsBuilder; - } - pub mod signed_extensions { - //! This module contains implementations for common signed extensions, each - //! of which implements [`SignedExtension`], and can be used in conjunction with - //! [`AnyOf`] to configure the set of signed extensions which are known about - //! when interacting with a chain. - use super::extrinsic_params::{ - ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, - }; - use crate::utils::Era; - use crate::{client::OfflineClientT, Config}; - use codec::{Compact, Encode}; - use core::fmt::Debug; - use derivative::Derivative; - use scale_decode::DecodeAsType; - use scale_info::PortableRegistry; - use std::collections::HashMap; - /// A single [`SignedExtension`] has a unique name, but is otherwise the - /// same as [`ExtrinsicParams`] in describing how to encode the extra and - /// additional data. - pub trait SignedExtension: ExtrinsicParams { - /// The type representing the `extra` bytes of a signed extension. - /// Decoding from this type should be symmetrical to the respective - /// `ExtrinsicParamsEncoder::encode_extra_to()` implementation of this signed extension. - type Decoded: DecodeAsType; - /// This should return true if the signed extension matches the details given. - /// Often, this will involve just checking that the identifier given matches that of the - /// extension in question. - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool; - } - /// The [`CheckSpecVersion`] signed extension. - pub struct CheckSpecVersion(u32); - impl ExtrinsicParams for CheckSpecVersion { - type OtherParams = (); - fn new>( - _nonce: u64, - client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CheckSpecVersion(client.runtime_version().spec_version)) - } - } - impl ExtrinsicParamsEncoder for CheckSpecVersion { - fn encode_additional_to(&self, v: &mut Vec) { - self.0.encode_to(v); - } - } - impl SignedExtension for CheckSpecVersion { - type Decoded = (); - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckSpecVersion" - } - } - /// The [`CheckNonce`] signed extension. - pub struct CheckNonce(Compact); - impl ExtrinsicParams for CheckNonce { - type OtherParams = (); - fn new>( - nonce: u64, - _client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CheckNonce(Compact(nonce))) - } - } - impl ExtrinsicParamsEncoder for CheckNonce { - fn encode_extra_to(&self, v: &mut Vec) { - self.0.encode_to(v); - } - } - impl SignedExtension for CheckNonce { - type Decoded = u64; - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckNonce" - } - } - /// The [`CheckTxVersion`] signed extension. - pub struct CheckTxVersion(u32); - impl ExtrinsicParams for CheckTxVersion { - type OtherParams = (); - fn new>( - _nonce: u64, - client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CheckTxVersion(client.runtime_version().transaction_version)) - } - } - impl ExtrinsicParamsEncoder for CheckTxVersion { - fn encode_additional_to(&self, v: &mut Vec) { - self.0.encode_to(v); - } - } - impl SignedExtension for CheckTxVersion { - type Decoded = (); - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckTxVersion" - } - } - /// The [`CheckGenesis`] signed extension. - pub struct CheckGenesis(T::Hash); - impl ExtrinsicParams for CheckGenesis { - type OtherParams = (); - fn new>( - _nonce: u64, - client: Client, - _other_params: Self::OtherParams, - ) -> Result { - Ok(CheckGenesis(client.genesis_hash())) - } - } - impl ExtrinsicParamsEncoder for CheckGenesis { - fn encode_additional_to(&self, v: &mut Vec) { - self.0.encode_to(v); - } - } - impl SignedExtension for CheckGenesis { - type Decoded = (); - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckGenesis" - } - } - /// The [`CheckMortality`] signed extension. - pub struct CheckMortality { - era: Era, - checkpoint: T::Hash, - } - /// Parameters to configure the [`CheckMortality`] signed extension. - pub struct CheckMortalityParams { - era: Era, - checkpoint: Option, - } - impl Default for CheckMortalityParams { - fn default() -> Self { - Self { - era: Default::default(), - checkpoint: Default::default(), - } - } - } - impl CheckMortalityParams { - /// Configure a mortal transaction. The `period` is (roughly) how many - /// blocks the transaction will be valid for. The `block_number` and - /// `block_hash` should both point to the same block, and are the block that - /// the transaction is mortal from. - pub fn mortal(period: u64, block_number: u64, block_hash: T::Hash) -> Self { - CheckMortalityParams { - era: Era::mortal(period, block_number), - checkpoint: Some(block_hash), - } - } - /// An immortal transaction. - pub fn immortal() -> Self { - CheckMortalityParams { - era: Era::Immortal, - checkpoint: None, - } - } - } - impl ExtrinsicParams for CheckMortality { - type OtherParams = CheckMortalityParams; - fn new>( - _nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - Ok(CheckMortality { - era: other_params.era, - checkpoint: other_params.checkpoint.unwrap_or(client.genesis_hash()), - }) - } - } - impl ExtrinsicParamsEncoder for CheckMortality { - fn encode_extra_to(&self, v: &mut Vec) { - self.era.encode_to(v); - } - fn encode_additional_to(&self, v: &mut Vec) { - self.checkpoint.encode_to(v); - } - } - impl SignedExtension for CheckMortality { - type Decoded = Era; - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "CheckMortality" - } - } - /// The [`ChargeAssetTxPayment`] signed extension. - #[derivative( - Clone(bound = "T::AssetId: Clone"), - Debug(bound = "T::AssetId: Debug") - )] - #[decode_as_type(trait_bounds = "T::AssetId: DecodeAsType")] - pub struct ChargeAssetTxPayment { - tip: Compact, - asset_id: Option, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for ChargeAssetTxPayment - where - T::AssetId: Clone, - { - fn clone(&self) -> Self { - match *self { - ChargeAssetTxPayment { tip: ref __arg_0, asset_id: ref __arg_1 } => { - ChargeAssetTxPayment { - tip: (*__arg_0).clone(), - asset_id: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for ChargeAssetTxPayment - where - T::AssetId: Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - ChargeAssetTxPayment { tip: ref __arg_0, asset_id: ref __arg_1 } => { - let mut __debug_trait_builder = __f - .debug_struct("ChargeAssetTxPayment"); - let _ = __debug_trait_builder.field("tip", &&(*__arg_0)); - let _ = __debug_trait_builder.field("asset_id", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<(T,)>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for ChargeAssetTxPayment - where - T::AssetId: DecodeAsType, - { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor - where - T::AssetId: DecodeAsType, - { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = ChargeAssetTxPayment; - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.has_unnamed_fields() { - return self.visit_tuple(&mut value.as_tuple(), type_id); - } - let vals: ::scale_decode::BTreeMap, _> = value - .map(|res| res.map(|item| (item.name(), item))) - .collect::>()?; - Ok(ChargeAssetTxPayment { - tip: { - let val = *vals - .get(&Some("tip")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "tip".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("tip"))? - }, - asset_id: { - let val = *vals - .get(&Some("asset_id")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "asset_id".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("asset_id"))? - }, - }) - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 2usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: value.remaining(), - expected_len: 2usize, - }), - ); - } - let vals = value; - Ok(ChargeAssetTxPayment { - tip: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("tip"))? - }, - asset_id: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("asset_id"))? - }, - }) - } - } - impl ::scale_decode::DecodeAsFields for ChargeAssetTxPayment - where - T::AssetId: DecodeAsType, - { - fn decode_as_fields<'info>( - input: &mut &[u8], - fields: &mut dyn ::scale_decode::FieldIter<'info>, - types: &'info ::scale_decode::PortableRegistry, - ) -> Result { - let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; - let mut composite = ::scale_decode::visitor::types::Composite::new( - input, - path, - fields, - types, - false, - ); - use ::scale_decode::{Visitor, IntoVisitor}; - let val = >::into_visitor() - .visit_composite( - &mut composite, - ::scale_decode::visitor::TypeId(0), - ); - composite.skip_decoding()?; - *input = composite.bytes_from_undecoded(); - val.map_err(From::from) - } - } - }; - impl ChargeAssetTxPayment { - /// Tip to the extrinsic author in the native chain token. - pub fn tip(&self) -> u128 { - self.tip.0 - } - /// Tip to the extrinsic author using the asset ID given. - pub fn asset_id(&self) -> Option<&T::AssetId> { - self.asset_id.as_ref() - } - } - /// Parameters to configure the [`ChargeAssetTxPayment`] signed extension. - pub struct ChargeAssetTxPaymentParams { - tip: u128, - asset_id: Option, - } - impl Default for ChargeAssetTxPaymentParams { - fn default() -> Self { - ChargeAssetTxPaymentParams { - tip: Default::default(), - asset_id: Default::default(), - } - } - } - impl ChargeAssetTxPaymentParams { - /// Don't provide a tip to the extrinsic author. - pub fn no_tip() -> Self { - ChargeAssetTxPaymentParams { - tip: 0, - asset_id: None, - } - } - /// Tip the extrinsic author in the native chain token. - pub fn tip(tip: u128) -> Self { - ChargeAssetTxPaymentParams { - tip, - asset_id: None, - } - } - /// Tip the extrinsic author using the asset ID given. - pub fn tip_of(tip: u128, asset_id: T::AssetId) -> Self { - ChargeAssetTxPaymentParams { - tip, - asset_id: Some(asset_id), - } - } - } - impl ExtrinsicParams for ChargeAssetTxPayment { - type OtherParams = ChargeAssetTxPaymentParams; - fn new>( - _nonce: u64, - _client: Client, - other_params: Self::OtherParams, - ) -> Result { - Ok(ChargeAssetTxPayment { - tip: Compact(other_params.tip), - asset_id: other_params.asset_id, - }) - } - } - impl ExtrinsicParamsEncoder for ChargeAssetTxPayment { - fn encode_extra_to(&self, v: &mut Vec) { - (self.tip, &self.asset_id).encode_to(v); - } - } - impl SignedExtension for ChargeAssetTxPayment { - type Decoded = Self; - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "ChargeAssetTxPayment" - } - } - /// The [`ChargeTransactionPayment`] signed extension. - pub struct ChargeTransactionPayment { - tip: Compact, - } - #[automatically_derived] - impl ::core::clone::Clone for ChargeTransactionPayment { - #[inline] - fn clone(&self) -> ChargeTransactionPayment { - ChargeTransactionPayment { - tip: ::core::clone::Clone::clone(&self.tip), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ChargeTransactionPayment { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "ChargeTransactionPayment", - "tip", - &&self.tip, - ) - } - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for ChargeTransactionPayment { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = ChargeTransactionPayment; - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.has_unnamed_fields() { - return self.visit_tuple(&mut value.as_tuple(), type_id); - } - let vals: ::scale_decode::BTreeMap, _> = value - .map(|res| res.map(|item| (item.name(), item))) - .collect::>()?; - Ok(ChargeTransactionPayment { - tip: { - let val = *vals - .get(&Some("tip")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "tip".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("tip"))? - }, - }) - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: value.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = value; - Ok(ChargeTransactionPayment { - tip: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("tip"))? - }, - }) - } - } - impl ::scale_decode::DecodeAsFields for ChargeTransactionPayment { - fn decode_as_fields<'info>( - input: &mut &[u8], - fields: &mut dyn ::scale_decode::FieldIter<'info>, - types: &'info ::scale_decode::PortableRegistry, - ) -> Result { - let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; - let mut composite = ::scale_decode::visitor::types::Composite::new( - input, - path, - fields, - types, - false, - ); - use ::scale_decode::{Visitor, IntoVisitor}; - let val = ::into_visitor() - .visit_composite( - &mut composite, - ::scale_decode::visitor::TypeId(0), - ); - composite.skip_decoding()?; - *input = composite.bytes_from_undecoded(); - val.map_err(From::from) - } - } - }; - impl ChargeTransactionPayment { - /// Tip to the extrinsic author in the native chain token. - pub fn tip(&self) -> u128 { - self.tip.0 - } - } - /// Parameters to configure the [`ChargeTransactionPayment`] signed extension. - pub struct ChargeTransactionPaymentParams { - tip: u128, - } - #[automatically_derived] - impl ::core::default::Default for ChargeTransactionPaymentParams { - #[inline] - fn default() -> ChargeTransactionPaymentParams { - ChargeTransactionPaymentParams { - tip: ::core::default::Default::default(), - } - } - } - impl ChargeTransactionPaymentParams { - /// Don't provide a tip to the extrinsic author. - pub fn no_tip() -> Self { - ChargeTransactionPaymentParams { - tip: 0, - } - } - /// Tip the extrinsic author in the native chain token. - pub fn tip(tip: u128) -> Self { - ChargeTransactionPaymentParams { - tip, - } - } - } - impl ExtrinsicParams for ChargeTransactionPayment { - type OtherParams = ChargeTransactionPaymentParams; - fn new>( - _nonce: u64, - _client: Client, - other_params: Self::OtherParams, - ) -> Result { - Ok(ChargeTransactionPayment { - tip: Compact(other_params.tip), - }) - } - } - impl ExtrinsicParamsEncoder for ChargeTransactionPayment { - fn encode_extra_to(&self, v: &mut Vec) { - self.tip.encode_to(v); - } - } - impl SignedExtension for ChargeTransactionPayment { - type Decoded = Self; - fn matches( - identifier: &str, - _type_id: u32, - _types: &PortableRegistry, - ) -> bool { - identifier == "ChargeTransactionPayment" - } - } - /// This accepts a tuple of [`SignedExtension`]s, and will dynamically make use of whichever - /// ones are actually required for the chain in the correct order, ignoring the rest. This - /// is a sensible default, and allows for a single configuration to work across multiple chains. - pub struct AnyOf { - params: Vec>, - _marker: std::marker::PhantomData<(T, Params)>, - } - #[rustfmt::skip] - const _: () = { - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - { - type OtherParams = (A::OtherParams,); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - { - type OtherParams = (A::OtherParams, B::OtherParams); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - { - type OtherParams = (A::OtherParams, B::OtherParams, C::OtherParams); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - > ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - R::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if R::matches(e.identifier(), e.extra_ty(), types) { - let ext = R::new(nonce, client.clone(), other_params.17)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - > ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - R::OtherParams, - S::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if R::matches(e.identifier(), e.extra_ty(), types) { - let ext = R::new(nonce, client.clone(), other_params.17)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if S::matches(e.identifier(), e.extra_ty(), types) { - let ext = S::new(nonce, client.clone(), other_params.18)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - U, - > ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - U: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - R::OtherParams, - S::OtherParams, - U::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if R::matches(e.identifier(), e.extra_ty(), types) { - let ext = R::new(nonce, client.clone(), other_params.17)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if S::matches(e.identifier(), e.extra_ty(), types) { - let ext = S::new(nonce, client.clone(), other_params.18)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if U::matches(e.identifier(), e.extra_ty(), types) { - let ext = U::new(nonce, client.clone(), other_params.19)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - U, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - U: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - U, - V, - > ExtrinsicParams - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - U: SignedExtension, - V: SignedExtension, - { - type OtherParams = ( - A::OtherParams, - B::OtherParams, - C::OtherParams, - D::OtherParams, - E::OtherParams, - F::OtherParams, - G::OtherParams, - H::OtherParams, - I::OtherParams, - J::OtherParams, - K::OtherParams, - L::OtherParams, - M::OtherParams, - N::OtherParams, - O::OtherParams, - P::OtherParams, - Q::OtherParams, - R::OtherParams, - S::OtherParams, - U::OtherParams, - V::OtherParams, - ); - fn new>( - nonce: u64, - client: Client, - other_params: Self::OtherParams, - ) -> Result { - let metadata = client.metadata(); - let types = metadata.types(); - let mut exts_by_index = HashMap::new(); - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if A::matches(e.identifier(), e.extra_ty(), types) { - let ext = A::new(nonce, client.clone(), other_params.0)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if B::matches(e.identifier(), e.extra_ty(), types) { - let ext = B::new(nonce, client.clone(), other_params.1)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if C::matches(e.identifier(), e.extra_ty(), types) { - let ext = C::new(nonce, client.clone(), other_params.2)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if D::matches(e.identifier(), e.extra_ty(), types) { - let ext = D::new(nonce, client.clone(), other_params.3)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if E::matches(e.identifier(), e.extra_ty(), types) { - let ext = E::new(nonce, client.clone(), other_params.4)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if F::matches(e.identifier(), e.extra_ty(), types) { - let ext = F::new(nonce, client.clone(), other_params.5)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if G::matches(e.identifier(), e.extra_ty(), types) { - let ext = G::new(nonce, client.clone(), other_params.6)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if H::matches(e.identifier(), e.extra_ty(), types) { - let ext = H::new(nonce, client.clone(), other_params.7)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if I::matches(e.identifier(), e.extra_ty(), types) { - let ext = I::new(nonce, client.clone(), other_params.8)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if J::matches(e.identifier(), e.extra_ty(), types) { - let ext = J::new(nonce, client.clone(), other_params.9)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if K::matches(e.identifier(), e.extra_ty(), types) { - let ext = K::new(nonce, client.clone(), other_params.10)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if L::matches(e.identifier(), e.extra_ty(), types) { - let ext = L::new(nonce, client.clone(), other_params.11)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if M::matches(e.identifier(), e.extra_ty(), types) { - let ext = M::new(nonce, client.clone(), other_params.12)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if N::matches(e.identifier(), e.extra_ty(), types) { - let ext = N::new(nonce, client.clone(), other_params.13)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if O::matches(e.identifier(), e.extra_ty(), types) { - let ext = O::new(nonce, client.clone(), other_params.14)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if P::matches(e.identifier(), e.extra_ty(), types) { - let ext = P::new(nonce, client.clone(), other_params.15)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if Q::matches(e.identifier(), e.extra_ty(), types) { - let ext = Q::new(nonce, client.clone(), other_params.16)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if R::matches(e.identifier(), e.extra_ty(), types) { - let ext = R::new(nonce, client.clone(), other_params.17)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if S::matches(e.identifier(), e.extra_ty(), types) { - let ext = S::new(nonce, client.clone(), other_params.18)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if U::matches(e.identifier(), e.extra_ty(), types) { - let ext = U::new(nonce, client.clone(), other_params.19)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - { - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - if exts_by_index.contains_key(&idx) { - continue; - } - if V::matches(e.identifier(), e.extra_ty(), types) { - let ext = V::new(nonce, client.clone(), other_params.20)?; - let boxed_ext: Box = Box::new( - ext, - ); - exts_by_index.insert(idx, boxed_ext); - break; - } - } - } - let mut params = Vec::new(); - for (idx, e) in metadata - .extrinsic() - .signed_extensions() - .iter() - .enumerate() - { - let Some(ext) = exts_by_index.remove(&idx) else { - if is_type_empty(e.extra_ty(), types) { - continue - } else { - return Err( - ExtrinsicParamsError::UnknownSignedExtension( - e.identifier().to_owned(), - ), - ); - } }; - params.push(ext); - } - Ok(AnyOf { - params, - _marker: std::marker::PhantomData, - }) - } - } - impl< - T, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - U, - V, - > ExtrinsicParamsEncoder - for AnyOf - where - T: Config, - A: SignedExtension, - B: SignedExtension, - C: SignedExtension, - D: SignedExtension, - E: SignedExtension, - F: SignedExtension, - G: SignedExtension, - H: SignedExtension, - I: SignedExtension, - J: SignedExtension, - K: SignedExtension, - L: SignedExtension, - M: SignedExtension, - N: SignedExtension, - O: SignedExtension, - P: SignedExtension, - Q: SignedExtension, - R: SignedExtension, - S: SignedExtension, - U: SignedExtension, - V: SignedExtension, - { - fn encode_extra_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_extra_to(v); - } - } - fn encode_additional_to(&self, v: &mut Vec) { - for ext in &self.params { - ext.encode_additional_to(v); - } - } - } - }; - /// Checks to see whether the type being given is empty, ie would require - /// 0 bytes to encode. - fn is_type_empty(type_id: u32, types: &scale_info::PortableRegistry) -> bool { - let Some(ty) = types.resolve(type_id) else { return false; - }; - use scale_info::TypeDef; - match &ty.type_def { - TypeDef::Composite(c) => { - c.fields.iter().all(|f| is_type_empty(f.ty.id, types)) - } - TypeDef::Array(a) => a.len == 0 || is_type_empty(a.type_param.id, types), - TypeDef::Tuple(t) => t.fields.iter().all(|f| is_type_empty(f.id, types)), - TypeDef::BitSequence(_) - | TypeDef::Variant(_) - | TypeDef::Sequence(_) - | TypeDef::Compact(_) - | TypeDef::Primitive(_) => false, - } - } - } - pub mod substrate { - //! Substrate specific configuration - use super::{ - Config, DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, Hasher, Header, - }; - use codec::{Decode, Encode}; - use serde::{Deserialize, Serialize}; - pub use crate::utils::{AccountId32, MultiAddress, MultiSignature}; - pub use primitive_types::{H256, U256}; - /// Default set of commonly used types by Substrate runtimes. - pub enum SubstrateConfig {} - impl Config for SubstrateConfig { - type Hash = H256; - type AccountId = AccountId32; - type Address = MultiAddress; - type Signature = MultiSignature; - type Hasher = BlakeTwo256; - type Header = SubstrateHeader; - type ExtrinsicParams = SubstrateExtrinsicParams; - type AssetId = u32; - } - /// A struct representing the signed extra and additional parameters required - /// to construct a transaction for the default substrate node. - pub type SubstrateExtrinsicParams = DefaultExtrinsicParams; - /// A builder which leads to [`SubstrateExtrinsicParams`] being constructed. - /// This is what you provide to methods like `sign_and_submit()`. - pub type SubstrateExtrinsicParamsBuilder = DefaultExtrinsicParamsBuilder; - /// A type that can hash values using the blaks2_256 algorithm. - pub struct BlakeTwo256; - #[automatically_derived] - impl ::core::fmt::Debug for BlakeTwo256 { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str(f, "BlakeTwo256") - } - } - #[automatically_derived] - impl ::core::clone::Clone for BlakeTwo256 { - #[inline] - fn clone(&self) -> BlakeTwo256 { - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for BlakeTwo256 {} - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BlakeTwo256 {} - #[automatically_derived] - impl ::core::cmp::PartialEq for BlakeTwo256 { - #[inline] - fn eq(&self, other: &BlakeTwo256) -> bool { - true - } - } - #[automatically_derived] - impl ::core::cmp::Eq for BlakeTwo256 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for BlakeTwo256 { - fn size_hint(&self) -> usize { - 0_usize - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) {} - } - #[automatically_derived] - impl ::codec::EncodeLike for BlakeTwo256 {} - }; - impl Hasher for BlakeTwo256 { - type Output = H256; - fn hash(s: &[u8]) -> Self::Output { - sp_core_hashing::blake2_256(s).into() - } - } - /// A generic Substrate header type, adapted from `sp_runtime::generic::Header`. - /// The block number and hasher can be configured to adapt this for other nodes. - #[serde(rename_all = "camelCase")] - pub struct SubstrateHeader + TryFrom, H: Hasher> { - /// The parent hash. - pub parent_hash: H::Output, - /// The block number. - #[serde( - serialize_with = "serialize_number", - deserialize_with = "deserialize_number" - )] - #[codec(compact)] - pub number: N, - /// The state trie merkle root - pub state_root: H::Output, - /// The merkle root of the extrinsics. - pub extrinsics_root: H::Output, - /// A chain-specific digest of data useful for light clients or referencing auxiliary data. - pub digest: Digest, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl + TryFrom, H: Hasher> ::codec::Encode - for SubstrateHeader - where - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - N: ::codec::HasCompact, - { - fn size_hint(&self) -> usize { - 0_usize - .saturating_add(::codec::Encode::size_hint(&self.parent_hash)) - .saturating_add( - ::codec::Encode::size_hint( - &<::Type as ::codec::EncodeAsRef< - '_, - N, - >>::RefType::from(&self.number), - ), - ) - .saturating_add(::codec::Encode::size_hint(&self.state_root)) - .saturating_add( - ::codec::Encode::size_hint(&self.extrinsics_root), - ) - .saturating_add(::codec::Encode::size_hint(&self.digest)) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&self.parent_hash, __codec_dest_edqy); - { - ::codec::Encode::encode_to( - &<::Type as ::codec::EncodeAsRef< - '_, - N, - >>::RefType::from(&self.number), - __codec_dest_edqy, - ); - } - ::codec::Encode::encode_to(&self.state_root, __codec_dest_edqy); - ::codec::Encode::encode_to(&self.extrinsics_root, __codec_dest_edqy); - ::codec::Encode::encode_to(&self.digest, __codec_dest_edqy); - } - } - #[automatically_derived] - impl + TryFrom, H: Hasher> ::codec::EncodeLike - for SubstrateHeader - where - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - H::Output: ::codec::Encode, - N: ::codec::HasCompact, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl + TryFrom, H: Hasher> ::codec::Decode - for SubstrateHeader - where - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - H::Output: ::codec::Decode, - N: ::codec::HasCompact, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(SubstrateHeader:: { - parent_hash: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `SubstrateHeader::parent_hash`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - number: { - let __codec_res_edqy = <::Type as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `SubstrateHeader::number`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy.into() - } - } - }, - state_root: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `SubstrateHeader::state_root`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - extrinsics_root: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e - .chain( - "Could not decode `SubstrateHeader::extrinsics_root`", - ), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - digest: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `SubstrateHeader::digest`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - #[automatically_derived] - impl< - N: ::core::fmt::Debug + Copy + Into + TryFrom, - H: ::core::fmt::Debug + Hasher, - > ::core::fmt::Debug for SubstrateHeader - where - H::Output: ::core::fmt::Debug, - H::Output: ::core::fmt::Debug, - H::Output: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "SubstrateHeader", - "parent_hash", - &self.parent_hash, - "number", - &self.number, - "state_root", - &self.state_root, - "extrinsics_root", - &self.extrinsics_root, - "digest", - &&self.digest, - ) - } - } - #[automatically_derived] - impl< - N: Copy + Into + TryFrom, - H: Hasher, - > ::core::marker::StructuralPartialEq for SubstrateHeader {} - #[automatically_derived] - impl< - N: ::core::cmp::PartialEq + Copy + Into + TryFrom, - H: ::core::cmp::PartialEq + Hasher, - > ::core::cmp::PartialEq for SubstrateHeader - where - H::Output: ::core::cmp::PartialEq, - H::Output: ::core::cmp::PartialEq, - H::Output: ::core::cmp::PartialEq, - { - #[inline] - fn eq(&self, other: &SubstrateHeader) -> bool { - self.parent_hash == other.parent_hash && self.number == other.number - && self.state_root == other.state_root - && self.extrinsics_root == other.extrinsics_root - && self.digest == other.digest - } - } - #[automatically_derived] - impl< - N: ::core::cmp::Eq + Copy + Into + TryFrom, - H: ::core::cmp::Eq + Hasher, - > ::core::cmp::Eq for SubstrateHeader - where - H::Output: ::core::cmp::Eq, - H::Output: ::core::cmp::Eq, - H::Output: ::core::cmp::Eq, - { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl< - N: ::core::clone::Clone + Copy + Into + TryFrom, - H: ::core::clone::Clone + Hasher, - > ::core::clone::Clone for SubstrateHeader - where - H::Output: ::core::clone::Clone, - H::Output: ::core::clone::Clone, - H::Output: ::core::clone::Clone, - { - #[inline] - fn clone(&self) -> SubstrateHeader { - SubstrateHeader { - parent_hash: ::core::clone::Clone::clone(&self.parent_hash), - number: ::core::clone::Clone::clone(&self.number), - state_root: ::core::clone::Clone::clone(&self.state_root), - extrinsics_root: ::core::clone::Clone::clone(&self.extrinsics_root), - digest: ::core::clone::Clone::clone(&self.digest), - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl + TryFrom, H: Hasher> _serde::Serialize - for SubstrateHeader - where - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "SubstrateHeader", - false as usize + 1 + 1 + 1 + 1 + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "parentHash", - &self.parent_hash, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "number", - { - #[doc(hidden)] - struct __SerializeWith< - '__a, - N: Copy + Into + TryFrom + '__a, - H: Hasher + '__a, - > - where - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - { - values: (&'__a N,), - phantom: _serde::__private::PhantomData< - SubstrateHeader, - >, - } - impl< - '__a, - N: Copy + Into + TryFrom + '__a, - H: Hasher + '__a, - > _serde::Serialize for __SerializeWith<'__a, N, H> - where - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - H::Output: _serde::Serialize, - { - fn serialize<__S>( - &self, - __s: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - serialize_number(self.values.0, __s) - } - } - &__SerializeWith { - values: (&self.number,), - phantom: _serde::__private::PhantomData::< - SubstrateHeader, - >, - } - }, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "stateRoot", - &self.state_root, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "extrinsicsRoot", - &self.extrinsics_root, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "digest", - &self.digest, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > _serde::Deserialize<'de> for SubstrateHeader - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __field2, - __field3, - __field4, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - 2u64 => _serde::__private::Ok(__Field::__field2), - 3u64 => _serde::__private::Ok(__Field::__field3), - 4u64 => _serde::__private::Ok(__Field::__field4), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "parentHash" => _serde::__private::Ok(__Field::__field0), - "number" => _serde::__private::Ok(__Field::__field1), - "stateRoot" => _serde::__private::Ok(__Field::__field2), - "extrinsicsRoot" => _serde::__private::Ok(__Field::__field3), - "digest" => _serde::__private::Ok(__Field::__field4), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"parentHash" => _serde::__private::Ok(__Field::__field0), - b"number" => _serde::__private::Ok(__Field::__field1), - b"stateRoot" => _serde::__private::Ok(__Field::__field2), - b"extrinsicsRoot" => { - _serde::__private::Ok(__Field::__field3) - } - b"digest" => _serde::__private::Ok(__Field::__field4), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - marker: _serde::__private::PhantomData>, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > _serde::de::Visitor<'de> for __Visitor<'de, N, H> - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - type Value = SubstrateHeader; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct SubstrateHeader", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - H::Output, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - let __field1 = match { - #[doc(hidden)] - struct __DeserializeWith< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - value: N, - phantom: _serde::__private::PhantomData< - SubstrateHeader, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > _serde::Deserialize<'de> for __DeserializeWith<'de, N, H> - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: deserialize_number(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - _serde::__private::Option::map( - _serde::de::SeqAccess::next_element::< - __DeserializeWith<'de, N, H>, - >(&mut __seq)?, - |__wrap| __wrap.value, - ) - } { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - let __field2 = match _serde::de::SeqAccess::next_element::< - H::Output, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 2usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - let __field3 = match _serde::de::SeqAccess::next_element::< - H::Output, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 3usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - let __field4 = match _serde::de::SeqAccess::next_element::< - Digest, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 4usize, - &"struct SubstrateHeader with 5 elements", - ), - ); - } - }; - _serde::__private::Ok(SubstrateHeader { - parent_hash: __field0, - number: __field1, - state_root: __field2, - extrinsics_root: __field3, - digest: __field4, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - let mut __field2: _serde::__private::Option = _serde::__private::None; - let mut __field3: _serde::__private::Option = _serde::__private::None; - let mut __field4: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "parentHash", - ), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("number"), - ); - } - __field1 = _serde::__private::Some({ - #[doc(hidden)] - struct __DeserializeWith< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - value: N, - phantom: _serde::__private::PhantomData< - SubstrateHeader, - >, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl< - 'de, - N: Copy + Into + TryFrom, - H: Hasher, - > _serde::Deserialize<'de> for __DeserializeWith<'de, N, H> - where - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - H::Output: _serde::Deserialize<'de>, - { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::__private::Ok(__DeserializeWith { - value: deserialize_number(__deserializer)?, - phantom: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData, - }) - } - } - match _serde::de::MapAccess::next_value::< - __DeserializeWith<'de, N, H>, - >(&mut __map) { - _serde::__private::Ok(__wrapper) => __wrapper.value, - _serde::__private::Err(__err) => { - return _serde::__private::Err(__err); - } - } - }); - } - __Field::__field2 => { - if _serde::__private::Option::is_some(&__field2) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "stateRoot", - ), - ); - } - __field2 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field3 => { - if _serde::__private::Option::is_some(&__field3) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field( - "extrinsicsRoot", - ), - ); - } - __field3 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field4 => { - if _serde::__private::Option::is_some(&__field4) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("digest"), - ); - } - __field4 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("parentHash")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::missing_field("number"), - ); - } - }; - let __field2 = match __field2 { - _serde::__private::Some(__field2) => __field2, - _serde::__private::None => { - _serde::__private::de::missing_field("stateRoot")? - } - }; - let __field3 = match __field3 { - _serde::__private::Some(__field3) => __field3, - _serde::__private::None => { - _serde::__private::de::missing_field("extrinsicsRoot")? - } - }; - let __field4 = match __field4 { - _serde::__private::Some(__field4) => __field4, - _serde::__private::None => { - _serde::__private::de::missing_field("digest")? - } - }; - _serde::__private::Ok(SubstrateHeader { - parent_hash: __field0, - number: __field1, - state_root: __field2, - extrinsics_root: __field3, - digest: __field4, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "parentHash", - "number", - "stateRoot", - "extrinsicsRoot", - "digest", - ]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "SubstrateHeader", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::< - SubstrateHeader, - >, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - impl Header for SubstrateHeader - where - N: Copy + Into + Into + TryFrom + Encode, - H: Hasher + Encode, - SubstrateHeader: Encode + Decode, - { - type Number = N; - type Hasher = H; - fn number(&self) -> Self::Number { - self.number - } - } - /// Generic header digest. From `sp_runtime::generic::digest`. - pub struct Digest { - /// A list of digest items. - pub logs: Vec, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for Digest { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.logs) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&&self.logs, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.logs) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.logs, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike for Digest {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for Digest { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(Digest { - logs: { - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `Digest::logs`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for Digest { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Digest", - "logs", - &&self.logs, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Digest {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Digest { - #[inline] - fn eq(&self, other: &Digest) -> bool { - self.logs == other.logs - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Digest { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Digest { - #[inline] - fn clone(&self) -> Digest { - Digest { - logs: ::core::clone::Clone::clone(&self.logs), - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Digest { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - let mut __serde_state = _serde::Serializer::serialize_struct( - __serializer, - "Digest", - false as usize + 1, - )?; - _serde::ser::SerializeStruct::serialize_field( - &mut __serde_state, - "logs", - &self.logs, - )?; - _serde::ser::SerializeStruct::end(__serde_state) - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Digest { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "logs" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"logs" => _serde::__private::Ok(__Field::__field0), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Digest; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct Digest", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - Vec, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct Digest with 1 element", - ), - ); - } - }; - _serde::__private::Ok(Digest { logs: __field0 }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option< - Vec, - > = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("logs"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::< - Vec, - >(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("logs")? - } - }; - _serde::__private::Ok(Digest { logs: __field0 }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &["logs"]; - _serde::Deserializer::deserialize_struct( - __deserializer, - "Digest", - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - #[automatically_derived] - impl ::core::default::Default for Digest { - #[inline] - fn default() -> Digest { - Digest { - logs: ::core::default::Default::default(), - } - } - } - /// Digest item that is able to encode/decode 'system' digest items and - /// provide opaque access to other items. From `sp_runtime::generic::digest`. - pub enum DigestItem { - /// A pre-runtime digest. - /// - /// These are messages from the consensus engine to the runtime, although - /// the consensus engine can (and should) read them itself to avoid - /// code and state duplication. It is erroneous for a runtime to produce - /// these, but this is not (yet) checked. - /// - /// NOTE: the runtime is not allowed to panic or fail in an `on_initialize` - /// call if an expected `PreRuntime` digest is not present. It is the - /// responsibility of a external block verifier to check this. Runtime API calls - /// will initialize the block without pre-runtime digests, so initialization - /// cannot fail when they are missing. - PreRuntime(ConsensusEngineId, Vec), - /// A message from the runtime to the consensus engine. This should *never* - /// be generated by the native code of any consensus engine, but this is not - /// checked (yet). - Consensus(ConsensusEngineId, Vec), - /// Put a Seal on it. This is only used by native code, and is never seen - /// by runtimes. - Seal(ConsensusEngineId, Vec), - /// Some other thing. Unsupported and experimental. - Other(Vec), - /// An indication for the light clients that the runtime execution - /// environment is updated. - /// - /// Currently this is triggered when: - /// 1. Runtime code blob is changed or - /// 2. `heap_pages` value is changed. - RuntimeEnvironmentUpdated, - } - #[automatically_derived] - impl ::core::fmt::Debug for DigestItem { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - DigestItem::PreRuntime(__self_0, __self_1) => { - ::core::fmt::Formatter::debug_tuple_field2_finish( - f, - "PreRuntime", - __self_0, - &__self_1, - ) - } - DigestItem::Consensus(__self_0, __self_1) => { - ::core::fmt::Formatter::debug_tuple_field2_finish( - f, - "Consensus", - __self_0, - &__self_1, - ) - } - DigestItem::Seal(__self_0, __self_1) => { - ::core::fmt::Formatter::debug_tuple_field2_finish( - f, - "Seal", - __self_0, - &__self_1, - ) - } - DigestItem::Other(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Other", - &__self_0, - ) - } - DigestItem::RuntimeEnvironmentUpdated => { - ::core::fmt::Formatter::write_str(f, "RuntimeEnvironmentUpdated") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DigestItem {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DigestItem { - #[inline] - fn eq(&self, other: &DigestItem) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - DigestItem::PreRuntime(__self_0, __self_1), - DigestItem::PreRuntime(__arg1_0, __arg1_1), - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - ( - DigestItem::Consensus(__self_0, __self_1), - DigestItem::Consensus(__arg1_0, __arg1_1), - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - ( - DigestItem::Seal(__self_0, __self_1), - DigestItem::Seal(__arg1_0, __arg1_1), - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - (DigestItem::Other(__self_0), DigestItem::Other(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DigestItem { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::clone::Clone for DigestItem { - #[inline] - fn clone(&self) -> DigestItem { - match self { - DigestItem::PreRuntime(__self_0, __self_1) => { - DigestItem::PreRuntime( - ::core::clone::Clone::clone(__self_0), - ::core::clone::Clone::clone(__self_1), - ) - } - DigestItem::Consensus(__self_0, __self_1) => { - DigestItem::Consensus( - ::core::clone::Clone::clone(__self_0), - ::core::clone::Clone::clone(__self_1), - ) - } - DigestItem::Seal(__self_0, __self_1) => { - DigestItem::Seal( - ::core::clone::Clone::clone(__self_0), - ::core::clone::Clone::clone(__self_1), - ) - } - DigestItem::Other(__self_0) => { - DigestItem::Other(::core::clone::Clone::clone(__self_0)) - } - DigestItem::RuntimeEnvironmentUpdated => { - DigestItem::RuntimeEnvironmentUpdated - } - } - } - } - #[repr(u32)] - enum DigestItemType { - Other = 0u32, - Consensus = 4u32, - Seal = 5u32, - PreRuntime = 6u32, - RuntimeEnvironmentUpdated = 8u32, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for DigestItemType { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - DigestItemType::Other => 0_usize, - DigestItemType::Consensus => 0_usize, - DigestItemType::Seal => 0_usize, - DigestItemType::PreRuntime => 0_usize, - DigestItemType::RuntimeEnvironmentUpdated => 0_usize, - _ => 0_usize, - } - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - match *self { - DigestItemType::Other => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(0u32 as ::core::primitive::u8); - } - DigestItemType::Consensus => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(4u32 as ::core::primitive::u8); - } - DigestItemType::Seal => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(5u32 as ::core::primitive::u8); - } - DigestItemType::PreRuntime => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(6u32 as ::core::primitive::u8); - } - DigestItemType::RuntimeEnvironmentUpdated => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(8u32 as ::core::primitive::u8); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::codec::EncodeLike for DigestItemType {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for DigestItemType { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `DigestItemType`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(DigestItemType::Other) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 4u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(DigestItemType::Consensus) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 5u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(DigestItemType::Seal) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 6u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(DigestItemType::PreRuntime) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 8u32 as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - DigestItemType::RuntimeEnvironmentUpdated, - ) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `DigestItemType`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - impl Encode for DigestItem { - fn encode(&self) -> Vec { - let mut v = Vec::new(); - match self { - Self::Consensus(val, data) => { - DigestItemType::Consensus.encode_to(&mut v); - (val, data).encode_to(&mut v); - } - Self::Seal(val, sig) => { - DigestItemType::Seal.encode_to(&mut v); - (val, sig).encode_to(&mut v); - } - Self::PreRuntime(val, data) => { - DigestItemType::PreRuntime.encode_to(&mut v); - (val, data).encode_to(&mut v); - } - Self::Other(val) => { - DigestItemType::Other.encode_to(&mut v); - val.encode_to(&mut v); - } - Self::RuntimeEnvironmentUpdated => { - DigestItemType::RuntimeEnvironmentUpdated.encode_to(&mut v); - } - } - v - } - } - impl Decode for DigestItem { - fn decode(input: &mut I) -> Result { - let item_type: DigestItemType = Decode::decode(input)?; - match item_type { - DigestItemType::PreRuntime => { - let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; - Ok(Self::PreRuntime(vals.0, vals.1)) - } - DigestItemType::Consensus => { - let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; - Ok(Self::Consensus(vals.0, vals.1)) - } - DigestItemType::Seal => { - let vals: (ConsensusEngineId, Vec) = Decode::decode(input)?; - Ok(Self::Seal(vals.0, vals.1)) - } - DigestItemType::Other => Ok(Self::Other(Decode::decode(input)?)), - DigestItemType::RuntimeEnvironmentUpdated => { - Ok(Self::RuntimeEnvironmentUpdated) - } - } - } - } - /// Consensus engine unique ID. From `sp_runtime::ConsensusEngineId`. - pub type ConsensusEngineId = [u8; 4]; - impl serde::Serialize for DigestItem { - fn serialize(&self, seq: S) -> Result - where - S: serde::Serializer, - { - self.using_encoded(|bytes| impl_serde::serialize::serialize(bytes, seq)) - } - } - impl<'a> serde::Deserialize<'a> for DigestItem { - fn deserialize(de: D) -> Result - where - D: serde::Deserializer<'a>, - { - let r = impl_serde::serialize::deserialize(de)?; - Decode::decode(&mut &r[..]) - .map_err(|e| serde::de::Error::custom({ - let res = ::alloc::fmt::format( - format_args!("Decode error: {0}", e), - ); - res - })) - } - } - fn serialize_number>( - val: &T, - s: S, - ) -> Result - where - S: serde::Serializer, - { - let u256: U256 = (*val).into(); - serde::Serialize::serialize(&u256, s) - } - fn deserialize_number<'a, D, T: TryFrom>(d: D) -> Result - where - D: serde::Deserializer<'a>, - { - use crate::backend::legacy::rpc_methods::NumberOrHex; - let number_or_hex = NumberOrHex::deserialize(d)?; - let u256 = number_or_hex.into_u256(); - TryFrom::try_from(u256) - .map_err(|_| serde::de::Error::custom("Try from failed")) - } - } - use crate::macros::cfg_substrate_compat; - use codec::{Decode, Encode}; - use core::fmt::Debug; - use scale_decode::DecodeAsType; - use scale_encode::EncodeAsType; - use serde::{de::DeserializeOwned, Serialize}; - pub use default_extrinsic_params::{ - DefaultExtrinsicParams, DefaultExtrinsicParamsBuilder, - }; - pub use extrinsic_params::{ - ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, - }; - pub use polkadot::{ - PolkadotConfig, PolkadotExtrinsicParams, PolkadotExtrinsicParamsBuilder, - }; - pub use signed_extensions::SignedExtension; - pub use substrate::{ - SubstrateConfig, SubstrateExtrinsicParams, SubstrateExtrinsicParamsBuilder, - }; - /// Runtime types. - pub trait Config: Sized + Send + Sync + 'static { - /// The output of the `Hasher` function. - type Hash: BlockHash; - /// The account ID type. - type AccountId: Debug + Clone + Encode; - /// The address type. - type Address: Debug + Encode + From; - /// The signature type. - type Signature: Debug + Encode; - /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). - type Hasher: Debug + Hasher; - /// The block header. - type Header: Debug - + Header - + Sync - + Send - + DeserializeOwned; - /// This type defines the extrinsic extra and additional parameters. - type ExtrinsicParams: ExtrinsicParams; - /// This is used to identify an asset in the `ChargeAssetTxPayment` signed extension. - type AssetId: Debug + Clone + Encode + DecodeAsType + EncodeAsType; - } - /// given some [`Config`], this return the other params needed for its `ExtrinsicParams`. - pub type OtherParamsFor = <::ExtrinsicParams as ExtrinsicParams< - T, - >>::OtherParams; - /// Block hashes must conform to a bunch of things to be used in Subxt. - pub trait BlockHash: Debug + Copy + Send + Sync + Decode + AsRef< - [u8], - > + Serialize + DeserializeOwned + Encode + PartialEq + Eq + std::hash::Hash {} - impl BlockHash for T - where - T: Debug + Copy + Send + Sync + Decode + AsRef<[u8]> + Serialize - + DeserializeOwned + Encode + PartialEq + Eq + std::hash::Hash, - {} - /// This represents the hasher used by a node to hash things like block headers - /// and extrinsics. - pub trait Hasher { - /// The type given back from the hash operation - type Output; - /// Hash some bytes to the given output type. - fn hash(s: &[u8]) -> Self::Output; - /// Hash some SCALE encodable type to the given output type. - fn hash_of(s: &S) -> Self::Output { - let out = s.encode(); - Self::hash(&out) - } - } - /// This represents the block header type used by a node. - pub trait Header: Sized + Encode + Decode { - /// The block number type for this header. - type Number: Into; - /// The hasher used to hash this header. - type Hasher: Hasher; - /// Return the block number of this header. - fn number(&self) -> Self::Number; - /// Hash this header. - fn hash(&self) -> ::Output { - Self::Hasher::hash_of(self) - } - } -} -pub mod constants { - //! Types associated with accessing constants. - mod constant_address { - use crate::{dynamic::DecodedValueThunk, metadata::DecodeWithMetadata}; - use derivative::Derivative; - use std::borrow::Cow; - /// This represents a constant address. Anything implementing this trait - /// can be used to fetch constants. - pub trait ConstantAddress { - /// The target type of the value that lives at this address. - type Target: DecodeWithMetadata; - /// The name of the pallet that the constant lives under. - fn pallet_name(&self) -> &str; - /// The name of the constant in a given pallet. - fn constant_name(&self) -> &str; - /// An optional hash which, if present, will be checked against - /// the node metadata to confirm that the return type matches what - /// we are expecting. - fn validation_hash(&self) -> Option<[u8; 32]> { - None - } - } - /// This represents the address of a constant. - #[derivative( - Clone(bound = ""), - Debug(bound = ""), - Eq(bound = ""), - Ord(bound = ""), - PartialEq(bound = "") - )] - pub struct Address { - pallet_name: Cow<'static, str>, - constant_name: Cow<'static, str>, - constant_hash: Option<[u8; 32]>, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Address { - fn clone(&self) -> Self { - match *self { - Address { - pallet_name: ref __arg_0, - constant_name: ref __arg_1, - constant_hash: ref __arg_2, - _marker: ref __arg_3, - } => { - Address { - pallet_name: (*__arg_0).clone(), - constant_name: (*__arg_1).clone(), - constant_hash: (*__arg_2).clone(), - _marker: (*__arg_3).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Address { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Address { - pallet_name: ref __arg_0, - constant_name: ref __arg_1, - constant_hash: ref __arg_2, - _marker: ref __arg_3, - } => { - let mut __debug_trait_builder = __f.debug_struct("Address"); - let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); - let _ = __debug_trait_builder - .field("constant_name", &&(*__arg_1)); - let _ = __debug_trait_builder - .field("constant_hash", &&(*__arg_2)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_3)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for Address {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for Address { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - Address { - pallet_name: ref __self_0, - constant_name: ref __self_1, - constant_hash: ref __self_2, - _marker: ref __self_3, - } => { - match *other { - Address { - pallet_name: ref __other_0, - constant_name: ref __other_1, - constant_hash: ref __other_2, - _marker: ref __other_3, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - && &(*__self_3) == &(*__other_3) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::Ord for Address { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - Address { - pallet_name: ref __self_0, - constant_name: ref __self_1, - constant_hash: ref __self_2, - _marker: ref __self_3, - } => { - match *other { - Address { - pallet_name: ref __other_0, - constant_name: ref __other_1, - constant_hash: ref __other_2, - _marker: ref __other_3, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - impl PartialOrd for Address { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - /// The type of address typically used to return dynamic constant values. - pub type DynamicAddress = Address; - impl Address { - /// Create a new [`Address`] to use to look up a constant. - pub fn new( - pallet_name: impl Into, - constant_name: impl Into, - ) -> Self { - Self { - pallet_name: Cow::Owned(pallet_name.into()), - constant_name: Cow::Owned(constant_name.into()), - constant_hash: None, - _marker: std::marker::PhantomData, - } - } - /// Create a new [`Address`] that will be validated - /// against node metadata using the hash given. - #[doc(hidden)] - pub fn new_static( - pallet_name: &'static str, - constant_name: &'static str, - hash: [u8; 32], - ) -> Self { - Self { - pallet_name: Cow::Borrowed(pallet_name), - constant_name: Cow::Borrowed(constant_name), - constant_hash: Some(hash), - _marker: std::marker::PhantomData, - } - } - /// Do not validate this constant prior to accessing it. - pub fn unvalidated(self) -> Self { - Self { - pallet_name: self.pallet_name, - constant_name: self.constant_name, - constant_hash: None, - _marker: self._marker, - } - } - } - impl ConstantAddress for Address { - type Target = ReturnTy; - fn pallet_name(&self) -> &str { - &self.pallet_name - } - fn constant_name(&self) -> &str { - &self.constant_name - } - fn validation_hash(&self) -> Option<[u8; 32]> { - self.constant_hash - } - } - /// Construct a new dynamic constant lookup. - pub fn dynamic( - pallet_name: impl Into, - constant_name: impl Into, - ) -> DynamicAddress { - DynamicAddress::new(pallet_name, constant_name) - } - } - mod constants_client { - use super::ConstantAddress; - use crate::{ - client::OfflineClientT, error::{Error, MetadataError}, - metadata::DecodeWithMetadata, Config, - }; - use derivative::Derivative; - /// A client for accessing constants. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct ConstantsClient { - client: Client, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for ConstantsClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - ConstantsClient { client: ref __arg_0, _marker: ref __arg_1 } => { - ConstantsClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl ConstantsClient { - /// Create a new [`ConstantsClient`]. - pub fn new(client: Client) -> Self { - Self { - client, - _marker: std::marker::PhantomData, - } - } - } - impl> ConstantsClient { - /// Run the validation logic against some constant address you'd like to access. Returns `Ok(())` - /// if the address is valid (or if it's not possible to check since the address has no validation hash). - /// Return an error if the address was not valid or something went wrong trying to validate it (ie - /// the pallet or constant in question do not exist at all). - pub fn validate( - &self, - address: &Address, - ) -> Result<(), Error> { - if let Some(actual_hash) = address.validation_hash() { - let expected_hash = self - .client - .metadata() - .pallet_by_name_err(address.pallet_name())? - .constant_hash(address.constant_name()) - .ok_or_else(|| { - MetadataError::ConstantNameNotFound( - address.constant_name().to_owned(), - ) - })?; - if actual_hash != expected_hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - } - Ok(()) - } - /// Access the constant at the address given, returning the type defined by this address. - /// This is probably used with addresses given from static codegen, although you can manually - /// construct your own, too. - pub fn at( - &self, - address: &Address, - ) -> Result { - let metadata = self.client.metadata(); - self.validate(address)?; - let constant = metadata - .pallet_by_name_err(address.pallet_name())? - .constant_by_name(address.constant_name()) - .ok_or_else(|| { - MetadataError::ConstantNameNotFound( - address.constant_name().to_owned(), - ) - })?; - let value = ::decode_with_metadata( - &mut constant.value(), - constant.ty(), - &metadata, - )?; - Ok(value) - } - } - } - pub use constant_address::{dynamic, Address, ConstantAddress, DynamicAddress}; - pub use constants_client::ConstantsClient; -} -pub mod custom_values { - //! Types associated with accessing custom types - mod custom_value_address { - use derivative::Derivative; - use std::marker::PhantomData; - use crate::dynamic::DecodedValueThunk; - use crate::metadata::DecodeWithMetadata; - /// This represents the address of a custom value in in the metadata. - /// Anything, that implements the [CustomValueAddress] trait can be used, to fetch - /// custom values from the metadata. - /// The trait is implemented by [str] for dynamic loopup and [StaticAddress] for static queries. - pub trait CustomValueAddress { - /// The type of the custom value. - type Target: DecodeWithMetadata; - /// Should be set to `Yes` for Dynamic values and static values that have a valid type. - /// Should be `()` for custom values, that have an invalid type id. - type IsDecodable; - /// the name (key) by which the custom value can be accessed in the metadata. - fn name(&self) -> &str; - /// An optional hash which, if present, can be checked against node metadata. - fn validation_hash(&self) -> Option<[u8; 32]> { - None - } - } - impl CustomValueAddress for str { - type Target = DecodedValueThunk; - type IsDecodable = Yes; - fn name(&self) -> &str { - self - } - } - /// Used to signal whether a [`CustomValueAddress`] can be decoded. - pub struct Yes; - /// A static address to a custom value. - #[derivative( - Clone(bound = ""), - Debug(bound = ""), - Eq(bound = ""), - Ord(bound = ""), - PartialEq(bound = "") - )] - pub struct StaticAddress { - name: &'static str, - hash: Option<[u8; 32]>, - phantom: PhantomData<(ReturnTy, IsDecodable)>, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone - for StaticAddress { - fn clone(&self) -> Self { - match *self { - StaticAddress { - name: ref __arg_0, - hash: ref __arg_1, - phantom: ref __arg_2, - } => { - StaticAddress { - name: (*__arg_0).clone(), - hash: (*__arg_1).clone(), - phantom: (*__arg_2).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug - for StaticAddress { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - StaticAddress { - name: ref __arg_0, - hash: ref __arg_1, - phantom: ref __arg_2, - } => { - let mut __debug_trait_builder = __f - .debug_struct("StaticAddress"); - let _ = __debug_trait_builder.field("name", &&(*__arg_0)); - let _ = __debug_trait_builder.field("hash", &&(*__arg_1)); - let _ = __debug_trait_builder.field("phantom", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq - for StaticAddress {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq - for StaticAddress { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - StaticAddress { - name: ref __self_0, - hash: ref __self_1, - phantom: ref __self_2, - } => { - match *other { - StaticAddress { - name: ref __other_0, - hash: ref __other_1, - phantom: ref __other_2, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::Ord - for StaticAddress { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - StaticAddress { - name: ref __self_0, - hash: ref __self_1, - phantom: ref __self_2, - } => { - match *other { - StaticAddress { - name: ref __other_0, - hash: ref __other_1, - phantom: ref __other_2, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - impl PartialOrd for StaticAddress { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - impl StaticAddress { - #[doc(hidden)] - /// Creates a new StaticAddress. - pub fn new_static( - name: &'static str, - hash: [u8; 32], - ) -> StaticAddress { - StaticAddress:: { - name, - hash: Some(hash), - phantom: PhantomData, - } - } - /// Do not validate this custom value prior to accessing it. - pub fn unvalidated(self) -> Self { - Self { - name: self.name, - hash: None, - phantom: self.phantom, - } - } - } - impl CustomValueAddress for StaticAddress { - type Target = R; - type IsDecodable = Y; - fn name(&self) -> &str { - self.name - } - fn validation_hash(&self) -> Option<[u8; 32]> { - self.hash - } - } - } - mod custom_values_client { - use crate::client::OfflineClientT; - use crate::custom_values::custom_value_address::{CustomValueAddress, Yes}; - use crate::error::MetadataError; - use crate::metadata::DecodeWithMetadata; - use crate::{Config, Error}; - use derivative::Derivative; - /// A client for accessing custom values stored in the metadata. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct CustomValuesClient { - client: Client, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for CustomValuesClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - CustomValuesClient { client: ref __arg_0, _marker: ref __arg_1 } => { - CustomValuesClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl CustomValuesClient { - /// Create a new [`CustomValuesClient`]. - pub fn new(client: Client) -> Self { - Self { - client, - _marker: std::marker::PhantomData, - } - } - } - impl> CustomValuesClient { - /// Access a custom value by the address it is registered under. This can be just a [str] to get back a dynamic value, - /// or a static address from the generated static interface to get a value of a static type returned. - pub fn at + ?Sized>( - &self, - address: &Address, - ) -> Result { - self.validate(address)?; - let metadata = self.client.metadata(); - let custom = metadata.custom(); - let custom_value = custom - .get(address.name()) - .ok_or_else(|| MetadataError::CustomValueNameNotFound( - address.name().to_string(), - ))?; - let value = ::decode_with_metadata( - &mut custom_value.bytes(), - custom_value.type_id(), - &metadata, - )?; - Ok(value) - } - /// Access the bytes of a custom value by the address it is registered under. - pub fn bytes_at( - &self, - address: &Address, - ) -> Result, Error> { - self.validate(address)?; - let metadata = self.client.metadata(); - let custom = metadata.custom(); - let custom_value = custom - .get(address.name()) - .ok_or_else(|| MetadataError::CustomValueNameNotFound( - address.name().to_string(), - ))?; - Ok(custom_value.bytes().to_vec()) - } - /// Run the validation logic against some custom value address you'd like to access. Returns `Ok(())` - /// if the address is valid (or if it's not possible to check since the address has no validation hash). - /// Returns an error if the address was not valid (wrong name, type or raw bytes) - pub fn validate( - &self, - address: &Address, - ) -> Result<(), Error> { - let metadata = self.client.metadata(); - if let Some(actual_hash) = address.validation_hash() { - let custom = metadata.custom(); - let custom_value = custom - .get(address.name()) - .ok_or_else(|| MetadataError::CustomValueNameNotFound( - address.name().into(), - ))?; - let expected_hash = custom_value.hash(); - if actual_hash != expected_hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - } - if metadata.custom().get(address.name()).is_none() { - return Err(MetadataError::IncompatibleCodegen.into()); - } - Ok(()) - } - } - } - pub use custom_value_address::{CustomValueAddress, StaticAddress, Yes}; - pub use custom_values_client::CustomValuesClient; -} -pub mod dynamic { - //! This module provides the entry points to create dynamic - //! transactions, storage and constant lookups. - use crate::{error::Error, metadata::{DecodeWithMetadata, Metadata}}; - use scale_decode::DecodeAsType; - pub use scale_value::{At, Value}; - /// A [`scale_value::Value`] type endowed with contextual information - /// regarding what type was used to decode each part of it. This implements - /// [`crate::metadata::DecodeWithMetadata`], and is used as a return type - /// for dynamic requests. - pub type DecodedValue = scale_value::Value; - pub use crate::tx::dynamic as tx; - pub use crate::constants::dynamic as constant; - pub use crate::storage::dynamic as storage; - pub use crate::runtime_api::dynamic as runtime_api_call; - /// This is the result of making a dynamic request to a node. From this, - /// we can return the raw SCALE bytes that we were handed back, or we can - /// complete the decoding of the bytes into a [`DecodedValue`] type. - pub struct DecodedValueThunk { - type_id: u32, - metadata: Metadata, - scale_bytes: Vec, - } - impl DecodeWithMetadata for DecodedValueThunk { - fn decode_with_metadata( - bytes: &mut &[u8], - type_id: u32, - metadata: &Metadata, - ) -> Result { - let mut v = Vec::with_capacity(bytes.len()); - v.extend_from_slice(bytes); - *bytes = &[]; - Ok(DecodedValueThunk { - type_id, - metadata: metadata.clone(), - scale_bytes: v, - }) - } - } - impl DecodedValueThunk { - /// Return the SCALE encoded bytes handed back from the node. - pub fn into_encoded(self) -> Vec { - self.scale_bytes - } - /// Return the SCALE encoded bytes handed back from the node without taking ownership of them. - pub fn encoded(&self) -> &[u8] { - &self.scale_bytes - } - /// Decode the SCALE encoded storage entry into a dynamic [`DecodedValue`] type. - pub fn to_value(&self) -> Result { - let val = DecodedValue::decode_as_type( - &mut &*self.scale_bytes, - self.type_id, - self.metadata.types(), - )?; - Ok(val) - } - /// decode the `DecodedValueThunk` into a concrete type. - pub fn as_type(&self) -> Result { - T::decode_as_type( - &mut &self.scale_bytes[..], - self.type_id, - self.metadata.types(), - ) - } - } -} -pub mod error { - //! Types representing the errors that can be returned. - mod dispatch_error { - //! A representation of the dispatch error; an error returned when - //! something fails in trying to submit/execute a transaction. - use crate::metadata::{DecodeWithMetadata, Metadata}; - use core::fmt::Debug; - use scale_decode::{visitor::DecodeAsTypeResult, DecodeAsType}; - use std::borrow::Cow; - use super::{Error, MetadataError}; - /// An error dispatching a transaction. - #[non_exhaustive] - pub enum DispatchError { - /// Some error occurred. - #[error("Some unknown error occurred.")] - Other, - /// Failed to lookup some data. - #[error("Failed to lookup some data.")] - CannotLookup, - /// A bad origin. - #[error("Bad origin.")] - BadOrigin, - /// A custom error in a module. - #[error("Pallet error: {0}")] - Module(ModuleError), - /// At least one consumer is remaining so the account cannot be destroyed. - #[error( - "At least one consumer is remaining so the account cannot be destroyed." - )] - ConsumerRemaining, - /// There are no providers so the account cannot be created. - #[error("There are no providers so the account cannot be created.")] - NoProviders, - /// There are too many consumers so the account cannot be created. - #[error("There are too many consumers so the account cannot be created.")] - TooManyConsumers, - /// An error to do with tokens. - #[error("Token error: {0}")] - Token(TokenError), - /// An arithmetic error. - #[error("Arithmetic error: {0}")] - Arithmetic(ArithmeticError), - /// The number of transactional layers has been reached, or we are not in a transactional layer. - #[error("Transactional error: {0}")] - Transactional(TransactionalError), - /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. - #[error( - "Resources exhausted, e.g. attempt to read/write data which is too large to manipulate." - )] - Exhausted, - /// The state is corrupt; this is generally not going to fix itself. - #[error("The state is corrupt; this is generally not going to fix itself.")] - Corruption, - /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. - #[error( - "Some resource (e.g. a preimage) is unavailable right now. This might fix itself later." - )] - Unavailable, - } - #[automatically_derived] - impl ::core::fmt::Debug for DispatchError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - DispatchError::Other => ::core::fmt::Formatter::write_str(f, "Other"), - DispatchError::CannotLookup => { - ::core::fmt::Formatter::write_str(f, "CannotLookup") - } - DispatchError::BadOrigin => { - ::core::fmt::Formatter::write_str(f, "BadOrigin") - } - DispatchError::Module(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Module", - &__self_0, - ) - } - DispatchError::ConsumerRemaining => { - ::core::fmt::Formatter::write_str(f, "ConsumerRemaining") - } - DispatchError::NoProviders => { - ::core::fmt::Formatter::write_str(f, "NoProviders") - } - DispatchError::TooManyConsumers => { - ::core::fmt::Formatter::write_str(f, "TooManyConsumers") - } - DispatchError::Token(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Token", - &__self_0, - ) - } - DispatchError::Arithmetic(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Arithmetic", - &__self_0, - ) - } - DispatchError::Transactional(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Transactional", - &__self_0, - ) - } - DispatchError::Exhausted => { - ::core::fmt::Formatter::write_str(f, "Exhausted") - } - DispatchError::Corruption => { - ::core::fmt::Formatter::write_str(f, "Corruption") - } - DispatchError::Unavailable => { - ::core::fmt::Formatter::write_str(f, "Unavailable") - } - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for DispatchError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for DispatchError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - DispatchError::Other {} => { - __formatter.write_str("Some unknown error occurred.") - } - DispatchError::CannotLookup {} => { - __formatter.write_str("Failed to lookup some data.") - } - DispatchError::BadOrigin {} => __formatter.write_str("Bad origin."), - DispatchError::Module(_0) => { - __formatter - .write_fmt( - format_args!("Pallet error: {0}", _0.as_display()), - ) - } - DispatchError::ConsumerRemaining {} => { - __formatter - .write_str( - "At least one consumer is remaining so the account cannot be destroyed.", - ) - } - DispatchError::NoProviders {} => { - __formatter - .write_str( - "There are no providers so the account cannot be created.", - ) - } - DispatchError::TooManyConsumers {} => { - __formatter - .write_str( - "There are too many consumers so the account cannot be created.", - ) - } - DispatchError::Token(_0) => { - __formatter - .write_fmt(format_args!("Token error: {0}", _0.as_display())) - } - DispatchError::Arithmetic(_0) => { - __formatter - .write_fmt( - format_args!("Arithmetic error: {0}", _0.as_display()), - ) - } - DispatchError::Transactional(_0) => { - __formatter - .write_fmt( - format_args!("Transactional error: {0}", _0.as_display()), - ) - } - DispatchError::Exhausted {} => { - __formatter - .write_str( - "Resources exhausted, e.g. attempt to read/write data which is too large to manipulate.", - ) - } - DispatchError::Corruption {} => { - __formatter - .write_str( - "The state is corrupt; this is generally not going to fix itself.", - ) - } - DispatchError::Unavailable {} => { - __formatter - .write_str( - "Some resource (e.g. a preimage) is unavailable right now. This might fix itself later.", - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for DispatchError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for DispatchError { - #[inline] - fn eq(&self, other: &DispatchError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - DispatchError::Module(__self_0), - DispatchError::Module(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - DispatchError::Token(__self_0), - DispatchError::Token(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - DispatchError::Arithmetic(__self_0), - DispatchError::Arithmetic(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - DispatchError::Transactional(__self_0), - DispatchError::Transactional(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for DispatchError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - /// An error relating to tokens when dispatching a transaction. - #[non_exhaustive] - pub enum TokenError { - /// Funds are unavailable. - #[error("Funds are unavailable.")] - FundsUnavailable, - /// Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved. - #[error( - "Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved." - )] - OnlyProvider, - /// Account cannot exist with the funds that would be given. - #[error("Account cannot exist with the funds that would be given.")] - BelowMinimum, - /// Account cannot be created. - #[error("Account cannot be created.")] - CannotCreate, - /// The asset in question is unknown. - #[error("The asset in question is unknown.")] - UnknownAsset, - /// Funds exist but are frozen. - #[error("Funds exist but are frozen.")] - Frozen, - /// Operation is not supported by the asset. - #[error("Operation is not supported by the asset.")] - Unsupported, - /// Account cannot be created for a held balance. - #[error("Account cannot be created for a held balance.")] - CannotCreateHold, - /// Withdrawal would cause unwanted loss of account. - #[error("Withdrawal would cause unwanted loss of account.")] - NotExpendable, - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for TokenError { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = TokenError; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "FundsUnavailable" { - return Ok(TokenError::FundsUnavailable); - } - if value.name() == "OnlyProvider" { - return Ok(TokenError::OnlyProvider); - } - if value.name() == "BelowMinimum" { - return Ok(TokenError::BelowMinimum); - } - if value.name() == "CannotCreate" { - return Ok(TokenError::CannotCreate); - } - if value.name() == "UnknownAsset" { - return Ok(TokenError::UnknownAsset); - } - if value.name() == "Frozen" { - return Ok(TokenError::Frozen); - } - if value.name() == "Unsupported" { - return Ok(TokenError::Unsupported); - } - if value.name() == "CannotCreateHold" { - return Ok(TokenError::CannotCreateHold); - } - if value.name() == "NotExpendable" { - return Ok(TokenError::NotExpendable); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - "FundsUnavailable", - "OnlyProvider", - "BelowMinimum", - "CannotCreate", - "UnknownAsset", - "Frozen", - "Unsupported", - "CannotCreateHold", - "NotExpendable", - ]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for TokenError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - TokenError::FundsUnavailable => "FundsUnavailable", - TokenError::OnlyProvider => "OnlyProvider", - TokenError::BelowMinimum => "BelowMinimum", - TokenError::CannotCreate => "CannotCreate", - TokenError::UnknownAsset => "UnknownAsset", - TokenError::Frozen => "Frozen", - TokenError::Unsupported => "Unsupported", - TokenError::CannotCreateHold => "CannotCreateHold", - TokenError::NotExpendable => "NotExpendable", - }, - ) - } - } - #[allow(unused_qualifications)] - impl std::error::Error for TokenError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for TokenError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - TokenError::FundsUnavailable {} => { - __formatter.write_str("Funds are unavailable.") - } - TokenError::OnlyProvider {} => { - __formatter - .write_str( - "Some part of the balance gives the only provider reference to the account and thus cannot be (re)moved.", - ) - } - TokenError::BelowMinimum {} => { - __formatter - .write_str( - "Account cannot exist with the funds that would be given.", - ) - } - TokenError::CannotCreate {} => { - __formatter.write_str("Account cannot be created.") - } - TokenError::UnknownAsset {} => { - __formatter.write_str("The asset in question is unknown.") - } - TokenError::Frozen {} => { - __formatter.write_str("Funds exist but are frozen.") - } - TokenError::Unsupported {} => { - __formatter.write_str("Operation is not supported by the asset.") - } - TokenError::CannotCreateHold {} => { - __formatter - .write_str("Account cannot be created for a held balance.") - } - TokenError::NotExpendable {} => { - __formatter - .write_str( - "Withdrawal would cause unwanted loss of account.", - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TokenError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TokenError { - #[inline] - fn eq(&self, other: &TokenError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TokenError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - /// An error relating to arithmetic when dispatching a transaction. - #[non_exhaustive] - pub enum ArithmeticError { - /// Underflow. - #[error("Underflow.")] - Underflow, - /// Overflow. - #[error("Overflow.")] - Overflow, - /// Division by zero. - #[error("Division by zero.")] - DivisionByZero, - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for ArithmeticError { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = ArithmeticError; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "Underflow" { - return Ok(ArithmeticError::Underflow); - } - if value.name() == "Overflow" { - return Ok(ArithmeticError::Overflow); - } - if value.name() == "DivisionByZero" { - return Ok(ArithmeticError::DivisionByZero); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - "Underflow", - "Overflow", - "DivisionByZero", - ]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for ArithmeticError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - ArithmeticError::Underflow => "Underflow", - ArithmeticError::Overflow => "Overflow", - ArithmeticError::DivisionByZero => "DivisionByZero", - }, - ) - } - } - #[allow(unused_qualifications)] - impl std::error::Error for ArithmeticError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for ArithmeticError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - ArithmeticError::Underflow {} => __formatter.write_str("Underflow."), - ArithmeticError::Overflow {} => __formatter.write_str("Overflow."), - ArithmeticError::DivisionByZero {} => { - __formatter.write_str("Division by zero.") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ArithmeticError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ArithmeticError { - #[inline] - fn eq(&self, other: &ArithmeticError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - impl ::core::cmp::Eq for ArithmeticError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - /// An error relating to thr transactional layers when dispatching a transaction. - #[non_exhaustive] - pub enum TransactionalError { - /// Too many transactional layers have been spawned. - #[error("Too many transactional layers have been spawned.")] - LimitReached, - /// A transactional layer was expected, but does not exist. - #[error("A transactional layer was expected, but does not exist.")] - NoLayer, - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for TransactionalError { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = TransactionalError; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "LimitReached" { - return Ok(TransactionalError::LimitReached); - } - if value.name() == "NoLayer" { - return Ok(TransactionalError::NoLayer); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new(["LimitReached", "NoLayer"]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for TransactionalError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - TransactionalError::LimitReached => "LimitReached", - TransactionalError::NoLayer => "NoLayer", - }, - ) - } - } - #[allow(unused_qualifications)] - impl std::error::Error for TransactionalError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for TransactionalError { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - TransactionalError::LimitReached {} => { - __formatter - .write_str( - "Too many transactional layers have been spawned.", - ) - } - TransactionalError::NoLayer {} => { - __formatter - .write_str( - "A transactional layer was expected, but does not exist.", - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionalError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionalError { - #[inline] - fn eq(&self, other: &TransactionalError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TransactionalError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - /// Details about a module error that has occurred. - #[non_exhaustive] - pub struct ModuleError { - metadata: Metadata, - /// Bytes representation: - /// - `bytes[0]`: pallet index - /// - `bytes[1]`: error index - /// - `bytes[2..]`: 3 bytes specific for the module error - bytes: [u8; 5], - } - #[automatically_derived] - impl ::core::clone::Clone for ModuleError { - #[inline] - fn clone(&self) -> ModuleError { - ModuleError { - metadata: ::core::clone::Clone::clone(&self.metadata), - bytes: ::core::clone::Clone::clone(&self.bytes), - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for ModuleError {} - impl PartialEq for ModuleError { - fn eq(&self, other: &Self) -> bool { - self.bytes == other.bytes - } - } - impl Eq for ModuleError {} - /// Custom `Debug` implementation, ignores the very large `metadata` field, using it instead (as - /// intended) to resolve the actual pallet and error names. This is much more useful for debugging. - impl Debug for ModuleError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let details = self.details_string(); - f.write_fmt(format_args!("ModuleError(<{0}>)", details)) - } - } - impl std::fmt::Display for ModuleError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let details = self.details_string(); - f.write_fmt(format_args!("{0}", details)) - } - } - impl ModuleError { - /// Return more details about this error. - pub fn details(&self) -> Result { - let pallet = self.metadata.pallet_by_index_err(self.pallet_index())?; - let variant = pallet - .error_variant_by_index(self.error_index()) - .ok_or_else(|| MetadataError::VariantIndexNotFound( - self.error_index(), - ))?; - Ok(ModuleErrorDetails { - pallet, - variant, - }) - } - /// Return a formatted string of the resolved error details for debugging/display purposes. - pub fn details_string(&self) -> String { - match self.details() { - Ok(details) => { - let res = ::alloc::fmt::format( - format_args!( - "{0}::{1}", details.pallet.name(), details.variant.name - ), - ); - res - } - Err(_) => { - let res = ::alloc::fmt::format( - format_args!( - "Unknown pallet error \'{0:?}\' (pallet and error details cannot be retrieved)", - self.bytes - ), - ); - res - } - } - } - /// Return the underlying module error data that was decoded. - pub fn bytes(&self) -> [u8; 5] { - self.bytes - } - /// Obtain the pallet index from the underlying byte data. - pub fn pallet_index(&self) -> u8 { - self.bytes[0] - } - /// Obtain the error index from the underlying byte data. - pub fn error_index(&self) -> u8 { - self.bytes[1] - } - /// Attempts to decode the ModuleError into the top outer Error enum. - pub fn as_root_error(&self) -> Result { - let decoded = E::decode_as_type( - &mut &self.bytes[..], - self.metadata.outer_enums().error_enum_ty(), - self.metadata.types(), - )?; - Ok(decoded) - } - } - /// Details about the module error. - pub struct ModuleErrorDetails<'a> { - /// The pallet that the error is in - pub pallet: crate::metadata::types::PalletMetadata<'a>, - /// The variant representing the error - pub variant: &'a scale_info::Variant, - } - impl DispatchError { - /// Attempt to decode a runtime [`DispatchError`]. - #[doc(hidden)] - pub fn decode_from<'a>( - bytes: impl Into>, - metadata: Metadata, - ) -> Result { - let bytes = bytes.into(); - let dispatch_error_ty_id = metadata - .dispatch_error_ty() - .ok_or(MetadataError::DispatchErrorNotFound)?; - enum DecodedDispatchError { - Other, - CannotLookup, - BadOrigin, - Module(DecodedModuleErrorBytes), - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Token(TokenError), - Arithmetic(ArithmeticError), - Transactional(TransactionalError), - Exhausted, - Corruption, - Unavailable, - } - const _: () = { - struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for DecodedDispatchError { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = DecodedDispatchError; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant< - 'scale, - 'info, - >, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "Other" { - return Ok(DecodedDispatchError::Other); - } - if value.name() == "CannotLookup" { - return Ok(DecodedDispatchError::CannotLookup); - } - if value.name() == "BadOrigin" { - return Ok(DecodedDispatchError::BadOrigin); - } - if value.name() == "Module" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - DecodedDispatchError::Module({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "ConsumerRemaining" { - return Ok(DecodedDispatchError::ConsumerRemaining); - } - if value.name() == "NoProviders" { - return Ok(DecodedDispatchError::NoProviders); - } - if value.name() == "TooManyConsumers" { - return Ok(DecodedDispatchError::TooManyConsumers); - } - if value.name() == "Token" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - DecodedDispatchError::Token({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Arithmetic" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - DecodedDispatchError::Arithmetic({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Transactional" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - DecodedDispatchError::Transactional({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Exhausted" { - return Ok(DecodedDispatchError::Exhausted); - } - if value.name() == "Corruption" { - return Ok(DecodedDispatchError::Corruption); - } - if value.name() == "Unavailable" { - return Ok(DecodedDispatchError::Unavailable); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - "Other", - "CannotLookup", - "BadOrigin", - "Module", - "ConsumerRemaining", - "NoProviders", - "TooManyConsumers", - "Token", - "Arithmetic", - "Transactional", - "Exhausted", - "Corruption", - "Unavailable", - ]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite< - 'scale, - 'info, - >, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple< - 'scale, - 'info, - >, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - struct DecodedModuleErrorBytes(Vec); - struct DecodedModuleErrorBytesVisitor; - impl scale_decode::Visitor for DecodedModuleErrorBytesVisitor { - type Error = scale_decode::Error; - type Value<'scale, 'info> = DecodedModuleErrorBytes; - fn unchecked_decode_as_type<'scale, 'info>( - self, - input: &mut &'scale [u8], - _type_id: scale_decode::visitor::TypeId, - _types: &'info scale_info::PortableRegistry, - ) -> DecodeAsTypeResult< - Self, - Result, Self::Error>, - > { - DecodeAsTypeResult::Decoded( - Ok(DecodedModuleErrorBytes(input.to_vec())), - ) - } - } - impl scale_decode::IntoVisitor for DecodedModuleErrorBytes { - type Visitor = DecodedModuleErrorBytesVisitor; - fn into_visitor() -> Self::Visitor { - DecodedModuleErrorBytesVisitor - } - } - let decoded_dispatch_err = DecodedDispatchError::decode_with_metadata( - &mut &*bytes, - dispatch_error_ty_id, - &metadata, - )?; - let dispatch_error = match decoded_dispatch_err { - DecodedDispatchError::Other => DispatchError::Other, - DecodedDispatchError::CannotLookup => DispatchError::CannotLookup, - DecodedDispatchError::BadOrigin => DispatchError::BadOrigin, - DecodedDispatchError::ConsumerRemaining => { - DispatchError::ConsumerRemaining - } - DecodedDispatchError::NoProviders => DispatchError::NoProviders, - DecodedDispatchError::TooManyConsumers => { - DispatchError::TooManyConsumers - } - DecodedDispatchError::Token(val) => DispatchError::Token(val), - DecodedDispatchError::Arithmetic(val) => { - DispatchError::Arithmetic(val) - } - DecodedDispatchError::Transactional(val) => { - DispatchError::Transactional(val) - } - DecodedDispatchError::Exhausted => DispatchError::Exhausted, - DecodedDispatchError::Corruption => DispatchError::Corruption, - DecodedDispatchError::Unavailable => DispatchError::Unavailable, - DecodedDispatchError::Module(module_bytes) => { - let module_bytes = module_bytes.0; - let bytes = if module_bytes.len() == 2 { - [module_bytes[0], module_bytes[1], 0, 0, 0] - } else if module_bytes.len() == 5 { - [ - module_bytes[0], - module_bytes[1], - module_bytes[2], - module_bytes[3], - module_bytes[4], - ] - } else { - { - use ::tracing::__macro_support::Callsite as _; - static __CALLSITE: ::tracing::callsite::DefaultCallsite = { - static META: ::tracing::Metadata<'static> = { - ::tracing_core::metadata::Metadata::new( - "event subxt/src/error/dispatch_error.rs:318", - "subxt::error::dispatch_error", - ::tracing::Level::WARN, - ::core::option::Option::Some( - "subxt/src/error/dispatch_error.rs", - ), - ::core::option::Option::Some(318u32), - ::core::option::Option::Some( - "subxt::error::dispatch_error", - ), - ::tracing_core::field::FieldSet::new( - &["message"], - ::tracing_core::callsite::Identifier(&__CALLSITE), - ), - ::tracing::metadata::Kind::EVENT, - ) - }; - ::tracing::callsite::DefaultCallsite::new(&META) - }; - let enabled = ::tracing::Level::WARN - <= ::tracing::level_filters::STATIC_MAX_LEVEL - && ::tracing::Level::WARN - <= ::tracing::level_filters::LevelFilter::current() - && { - let interest = __CALLSITE.interest(); - !interest.is_never() - && ::tracing::__macro_support::__is_enabled( - __CALLSITE.metadata(), - interest, - ) - }; - if enabled { - (|value_set: ::tracing::field::ValueSet| { - let meta = __CALLSITE.metadata(); - ::tracing::Event::dispatch(meta, &value_set); - })({ - #[allow(unused_imports)] - use ::tracing::field::{debug, display, Value}; - let mut iter = __CALLSITE.metadata().fields().iter(); - __CALLSITE - .metadata() - .fields() - .value_set( - &[ - ( - &::core::iter::Iterator::next(&mut iter) - .expect("FieldSet corrupted (this is a bug)"), - ::core::option::Option::Some( - &format_args!( - "Can\'t decode error sp_runtime::DispatchError: bytes do not match known shapes" - ) as &dyn Value, - ), - ), - ], - ) - }); - } else { - } - }; - return Err(super::Error::Unknown(bytes.to_vec())); - }; - DispatchError::Module(ModuleError { metadata, bytes }) - } - }; - Ok(dispatch_error) - } - } - } - pub use dispatch_error::{ - ArithmeticError, DispatchError, ModuleError, TokenError, TransactionalError, - }; - use subxt_metadata::StorageHasher; - pub use crate::config::ExtrinsicParamsError; - pub use crate::metadata::Metadata; - pub use scale_decode::Error as DecodeError; - pub use scale_encode::Error as EncodeError; - pub use subxt_metadata::TryFromError as MetadataTryFromError; - /// The underlying error enum, generic over the type held by the `Runtime` - /// variant. Prefer to use the [`Error`] and [`Error`] aliases over - /// using this type directly. - #[non_exhaustive] - pub enum Error { - /// Io error. - #[error("Io error: {0}")] - Io(#[from] std::io::Error), - /// Codec error. - #[error("Scale codec error: {0}")] - Codec(#[from] codec::Error), - /// Rpc error. - #[error("Rpc error: {0}")] - Rpc(#[from] RpcError), - /// Serde serialization error - #[error("Serde json error: {0}")] - Serialization(#[from] serde_json::error::Error), - /// Error working with metadata. - #[error("Metadata error: {0}")] - Metadata(#[from] MetadataError), - /// Error decoding metadata. - #[error("Metadata Decoding error: {0}")] - MetadataDecoding(#[from] MetadataTryFromError), - /// Runtime error. - #[error("Runtime error: {0}")] - Runtime(#[from] DispatchError), - /// Error decoding to a [`crate::dynamic::Value`]. - #[error("Error decoding into dynamic value: {0}")] - Decode(#[from] DecodeError), - /// Error encoding from a [`crate::dynamic::Value`]. - #[error("Error encoding from dynamic value: {0}")] - Encode(#[from] EncodeError), - /// Transaction progress error. - #[error("Transaction error: {0}")] - Transaction(#[from] TransactionError), - /// Error constructing the appropriate extrinsic params. - #[error("Extrinsic params error: {0}")] - ExtrinsicParams(#[from] ExtrinsicParamsError), - /// Block related error. - #[error("Block error: {0}")] - Block(#[from] BlockError), - /// An error encoding a storage address. - #[error("Error encoding storage address: {0}")] - StorageAddress(#[from] StorageAddressError), - /// The bytes representing an error that we were unable to decode. - #[error("An error occurred but it could not be decoded: {0:?}")] - Unknown(Vec), - /// Other error. - #[error("Other error: {0}")] - Other(String), - } - #[automatically_derived] - impl ::core::fmt::Debug for Error { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - Error::Io(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Io", &__self_0) - } - Error::Codec(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Codec", - &__self_0, - ) - } - Error::Rpc(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Rpc", - &__self_0, - ) - } - Error::Serialization(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Serialization", - &__self_0, - ) - } - Error::Metadata(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Metadata", - &__self_0, - ) - } - Error::MetadataDecoding(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "MetadataDecoding", - &__self_0, - ) - } - Error::Runtime(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Runtime", - &__self_0, - ) - } - Error::Decode(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Decode", - &__self_0, - ) - } - Error::Encode(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Encode", - &__self_0, - ) - } - Error::Transaction(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Transaction", - &__self_0, - ) - } - Error::ExtrinsicParams(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ExtrinsicParams", - &__self_0, - ) - } - Error::Block(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Block", - &__self_0, - ) - } - Error::StorageAddress(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "StorageAddress", - &__self_0, - ) - } - Error::Unknown(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Unknown", - &__self_0, - ) - } - Error::Other(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Other", - &__self_0, - ) - } - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for Error { - fn source(&self) -> ::core::option::Option<&(dyn std::error::Error + 'static)> { - use thiserror::__private::AsDynError as _; - #[allow(deprecated)] - match self { - Error::Io { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Codec { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Rpc { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Serialization { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Metadata { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::MetadataDecoding { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Runtime { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Decode { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Encode { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Transaction { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::ExtrinsicParams { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Block { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::StorageAddress { 0: source, .. } => { - ::core::option::Option::Some(source.as_dyn_error()) - } - Error::Unknown { .. } => ::core::option::Option::None, - Error::Other { .. } => ::core::option::Option::None, - } - } - } - #[allow(unused_qualifications)] - impl ::core::fmt::Display for Error { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - Error::Io(_0) => { - __formatter.write_fmt(format_args!("Io error: {0}", _0.as_display())) - } - Error::Codec(_0) => { - __formatter - .write_fmt( - format_args!("Scale codec error: {0}", _0.as_display()), - ) - } - Error::Rpc(_0) => { - __formatter - .write_fmt(format_args!("Rpc error: {0}", _0.as_display())) - } - Error::Serialization(_0) => { - __formatter - .write_fmt( - format_args!("Serde json error: {0}", _0.as_display()), - ) - } - Error::Metadata(_0) => { - __formatter - .write_fmt(format_args!("Metadata error: {0}", _0.as_display())) - } - Error::MetadataDecoding(_0) => { - __formatter - .write_fmt( - format_args!("Metadata Decoding error: {0}", _0.as_display()), - ) - } - Error::Runtime(_0) => { - __formatter - .write_fmt(format_args!("Runtime error: {0}", _0.as_display())) - } - Error::Decode(_0) => { - __formatter - .write_fmt( - format_args!( - "Error decoding into dynamic value: {0}", _0.as_display() - ), - ) - } - Error::Encode(_0) => { - __formatter - .write_fmt( - format_args!( - "Error encoding from dynamic value: {0}", _0.as_display() - ), - ) - } - Error::Transaction(_0) => { - __formatter - .write_fmt( - format_args!("Transaction error: {0}", _0.as_display()), - ) - } - Error::ExtrinsicParams(_0) => { - __formatter - .write_fmt( - format_args!("Extrinsic params error: {0}", _0.as_display()), - ) - } - Error::Block(_0) => { - __formatter - .write_fmt(format_args!("Block error: {0}", _0.as_display())) - } - Error::StorageAddress(_0) => { - __formatter - .write_fmt( - format_args!( - "Error encoding storage address: {0}", _0.as_display() - ), - ) - } - Error::Unknown(_0) => { - __formatter - .write_fmt( - format_args!( - "An error occurred but it could not be decoded: {0:?}", _0 - ), - ) - } - Error::Other(_0) => { - __formatter - .write_fmt(format_args!("Other error: {0}", _0.as_display())) - } - } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: std::io::Error) -> Self { - Error::Io { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: codec::Error) -> Self { - Error::Codec { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: RpcError) -> Self { - Error::Rpc { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: serde_json::error::Error) -> Self { - Error::Serialization { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: MetadataError) -> Self { - Error::Metadata { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: MetadataTryFromError) -> Self { - Error::MetadataDecoding { - 0: source, - } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: DispatchError) -> Self { - Error::Runtime { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: DecodeError) -> Self { - Error::Decode { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: EncodeError) -> Self { - Error::Encode { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: TransactionError) -> Self { - Error::Transaction { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: ExtrinsicParamsError) -> Self { - Error::ExtrinsicParams { - 0: source, - } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: BlockError) -> Self { - Error::Block { 0: source } - } - } - #[allow(unused_qualifications)] - impl ::core::convert::From for Error { - #[allow(deprecated)] - fn from(source: StorageAddressError) -> Self { - Error::StorageAddress { 0: source } - } - } - impl<'a> From<&'a str> for Error { - fn from(error: &'a str) -> Self { - Error::Other(error.into()) - } - } - impl From for Error { - fn from(error: String) -> Self { - Error::Other(error) - } - } - impl From for Error { - fn from(value: std::convert::Infallible) -> Self { - match value {} - } - } - impl Error { - /// Checks whether the error was caused by a RPC re-connection. - pub fn is_disconnected_will_reconnect(&self) -> bool { - match self { - Error::Rpc(RpcError::DisconnectedWillReconnect(_)) => true, - _ => false, - } - } - } - /// An RPC error. Since we are generic over the RPC client that is used, - /// the error is boxed and could be casted. - #[non_exhaustive] - pub enum RpcError { - /// Error related to the RPC client. - #[error("RPC error: {0}")] - ClientError(Box), - /// This error signals that the request was rejected for some reason. - /// The specific reason is provided. - #[error("RPC error: request rejected: {0}")] - RequestRejected(String), - /// The RPC subscription dropped. - #[error("RPC error: subscription dropped.")] - SubscriptionDropped, - /// The requested URL is insecure. - #[error("RPC error: insecure URL: {0}")] - InsecureUrl(String), - /// The connection was lost and automatically reconnected. - #[error( - "RPC error: the connection was lost `{0}`; reconnect automatically initiated" - )] - DisconnectedWillReconnect(String), - } - #[automatically_derived] - impl ::core::fmt::Debug for RpcError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - RpcError::ClientError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ClientError", - &__self_0, - ) - } - RpcError::RequestRejected(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "RequestRejected", - &__self_0, - ) - } - RpcError::SubscriptionDropped => { - ::core::fmt::Formatter::write_str(f, "SubscriptionDropped") - } - RpcError::InsecureUrl(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "InsecureUrl", - &__self_0, - ) - } - RpcError::DisconnectedWillReconnect(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "DisconnectedWillReconnect", - &__self_0, - ) - } - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for RpcError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for RpcError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - RpcError::ClientError(_0) => { - __formatter - .write_fmt(format_args!("RPC error: {0}", _0.as_display())) - } - RpcError::RequestRejected(_0) => { - __formatter - .write_fmt( - format_args!( - "RPC error: request rejected: {0}", _0.as_display() - ), - ) - } - RpcError::SubscriptionDropped {} => { - __formatter.write_str("RPC error: subscription dropped.") - } - RpcError::InsecureUrl(_0) => { - __formatter - .write_fmt( - format_args!("RPC error: insecure URL: {0}", _0.as_display()), - ) - } - RpcError::DisconnectedWillReconnect(_0) => { - __formatter - .write_fmt( - format_args!( - "RPC error: the connection was lost `{0}`; reconnect automatically initiated", - _0.as_display() - ), - ) - } - } - } - } - impl RpcError { - /// Create a `RequestRejected` error from anything that can be turned into a string. - pub fn request_rejected>(s: S) -> RpcError { - RpcError::RequestRejected(s.into()) - } - } - /// Block error - #[non_exhaustive] - pub enum BlockError { - /// An error containing the hash of the block that was not found. - #[error( - "Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)" - )] - NotFound(String), - /// Extrinsic type ID cannot be resolved with the provided metadata. - #[error( - "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata" - )] - MissingType, - /// Unsupported signature. - #[error("Unsupported extrinsic version, only version 4 is supported currently")] - /// The extrinsic has an unsupported version. - UnsupportedVersion(u8), - /// Decoding error. - #[error("Cannot decode extrinsic: {0}")] - DecodingError(codec::Error), - } - #[automatically_derived] - impl ::core::clone::Clone for BlockError { - #[inline] - fn clone(&self) -> BlockError { - match self { - BlockError::NotFound(__self_0) => { - BlockError::NotFound(::core::clone::Clone::clone(__self_0)) - } - BlockError::MissingType => BlockError::MissingType, - BlockError::UnsupportedVersion(__self_0) => { - BlockError::UnsupportedVersion(::core::clone::Clone::clone(__self_0)) - } - BlockError::DecodingError(__self_0) => { - BlockError::DecodingError(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for BlockError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - BlockError::NotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "NotFound", - &__self_0, - ) - } - BlockError::MissingType => { - ::core::fmt::Formatter::write_str(f, "MissingType") - } - BlockError::UnsupportedVersion(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "UnsupportedVersion", - &__self_0, - ) - } - BlockError::DecodingError(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "DecodingError", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for BlockError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[allow(unused_qualifications)] - impl std::error::Error for BlockError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for BlockError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - BlockError::NotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)", - _0.as_display() - ), - ) - } - BlockError::MissingType {} => { - __formatter - .write_str( - "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata", - ) - } - BlockError::UnsupportedVersion(_0) => { - __formatter - .write_str( - "Unsupported extrinsic version, only version 4 is supported currently", - ) - } - BlockError::DecodingError(_0) => { - __formatter - .write_fmt( - format_args!("Cannot decode extrinsic: {0}", _0.as_display()), - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for BlockError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for BlockError { - #[inline] - fn eq(&self, other: &BlockError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - (BlockError::NotFound(__self_0), BlockError::NotFound(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - ( - BlockError::UnsupportedVersion(__self_0), - BlockError::UnsupportedVersion(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - BlockError::DecodingError(__self_0), - BlockError::DecodingError(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - impl BlockError { - /// Produce an error that a block with the given hash cannot be found. - pub fn not_found(hash: impl AsRef<[u8]>) -> BlockError { - let hash = { - let res = ::alloc::fmt::format(format_args!("0x{0}", hex::encode(hash))); - res - }; - BlockError::NotFound(hash) - } - } - /// Transaction error. - #[non_exhaustive] - pub enum TransactionError { - /// The block hash that the transaction was added to could not be found. - /// This is probably because the block was retracted before being finalized. - #[error( - "The block containing the transaction can no longer be found (perhaps it was on a non-finalized fork?)" - )] - BlockNotFound, - /// An error happened on the node that the transaction was submitted to. - #[error("Error handling transaction: {0}")] - Error(String), - /// The transaction was deemed invalid. - #[error("The transaction is not valid: {0}")] - Invalid(String), - /// The transaction was dropped. - #[error("The transaction was dropped: {0}")] - Dropped(String), - } - #[automatically_derived] - impl ::core::clone::Clone for TransactionError { - #[inline] - fn clone(&self) -> TransactionError { - match self { - TransactionError::BlockNotFound => TransactionError::BlockNotFound, - TransactionError::Error(__self_0) => { - TransactionError::Error(::core::clone::Clone::clone(__self_0)) - } - TransactionError::Invalid(__self_0) => { - TransactionError::Invalid(::core::clone::Clone::clone(__self_0)) - } - TransactionError::Dropped(__self_0) => { - TransactionError::Dropped(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionError::BlockNotFound => { - ::core::fmt::Formatter::write_str(f, "BlockNotFound") - } - TransactionError::Error(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Error", - &__self_0, - ) - } - TransactionError::Invalid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Invalid", - &__self_0, - ) - } - TransactionError::Dropped(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Dropped", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for TransactionError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[allow(unused_qualifications)] - impl std::error::Error for TransactionError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for TransactionError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - TransactionError::BlockNotFound {} => { - __formatter - .write_str( - "The block containing the transaction can no longer be found (perhaps it was on a non-finalized fork?)", - ) - } - TransactionError::Error(_0) => { - __formatter - .write_fmt( - format_args!( - "Error handling transaction: {0}", _0.as_display() - ), - ) - } - TransactionError::Invalid(_0) => { - __formatter - .write_fmt( - format_args!( - "The transaction is not valid: {0}", _0.as_display() - ), - ) - } - TransactionError::Dropped(_0) => { - __formatter - .write_fmt( - format_args!( - "The transaction was dropped: {0}", _0.as_display() - ), - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionError { - #[inline] - fn eq(&self, other: &TransactionError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionError::Error(__self_0), - TransactionError::Error(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - TransactionError::Invalid(__self_0), - TransactionError::Invalid(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - TransactionError::Dropped(__self_0), - TransactionError::Dropped(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - /// Something went wrong trying to encode a storage address. - #[non_exhaustive] - pub enum StorageAddressError { - /// Storage map type must be a composite type. - #[error("Storage map type must be a composite type")] - MapTypeMustBeTuple, - /// Storage lookup does not have the expected number of keys. - #[error("Storage lookup requires {expected} keys but got {actual} keys")] - WrongNumberOfKeys { - /// The actual number of keys needed, based on the metadata. - actual: usize, - /// The number of keys provided in the storage address. - expected: usize, - }, - /// This storage entry in the metadata does not have the correct number of hashers to fields. - #[error( - "Storage entry in metadata does not have the correct number of hashers to fields" - )] - WrongNumberOfHashers { - /// The number of hashers in the metadata for this storage entry. - hashers: usize, - /// The number of fields in the metadata for this storage entry. - fields: usize, - }, - /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. - #[error( - "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata." - )] - UnexpectedAddressBytes, - /// An invalid hasher was used to reconstruct a value from a chunk of bytes that is part of a storage address. Hashers where the hash does not contain the original value are invalid for this purpose. - #[error( - "An invalid hasher was used to reconstruct a value of type {ty_name} (id={ty_id}) from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher" - )] - HasherCannotReconstructKey { - /// Type id of the key's type. - ty_id: u32, - /// Type name of the key's type. - ty_name: String, - /// The invalid hasher that caused this error. - hasher: StorageHasher, - }, - } - #[automatically_derived] - impl ::core::clone::Clone for StorageAddressError { - #[inline] - fn clone(&self) -> StorageAddressError { - match self { - StorageAddressError::MapTypeMustBeTuple => { - StorageAddressError::MapTypeMustBeTuple - } - StorageAddressError::WrongNumberOfKeys { - actual: __self_0, - expected: __self_1, - } => { - StorageAddressError::WrongNumberOfKeys { - actual: ::core::clone::Clone::clone(__self_0), - expected: ::core::clone::Clone::clone(__self_1), - } - } - StorageAddressError::WrongNumberOfHashers { - hashers: __self_0, - fields: __self_1, - } => { - StorageAddressError::WrongNumberOfHashers { - hashers: ::core::clone::Clone::clone(__self_0), - fields: ::core::clone::Clone::clone(__self_1), - } - } - StorageAddressError::UnexpectedAddressBytes => { - StorageAddressError::UnexpectedAddressBytes - } - StorageAddressError::HasherCannotReconstructKey { - ty_id: __self_0, - ty_name: __self_1, - hasher: __self_2, - } => { - StorageAddressError::HasherCannotReconstructKey { - ty_id: ::core::clone::Clone::clone(__self_0), - ty_name: ::core::clone::Clone::clone(__self_1), - hasher: ::core::clone::Clone::clone(__self_2), - } - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for StorageAddressError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - StorageAddressError::MapTypeMustBeTuple => { - ::core::fmt::Formatter::write_str(f, "MapTypeMustBeTuple") - } - StorageAddressError::WrongNumberOfKeys { - actual: __self_0, - expected: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "WrongNumberOfKeys", - "actual", - __self_0, - "expected", - &__self_1, - ) - } - StorageAddressError::WrongNumberOfHashers { - hashers: __self_0, - fields: __self_1, - } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "WrongNumberOfHashers", - "hashers", - __self_0, - "fields", - &__self_1, - ) - } - StorageAddressError::UnexpectedAddressBytes => { - ::core::fmt::Formatter::write_str(f, "UnexpectedAddressBytes") - } - StorageAddressError::HasherCannotReconstructKey { - ty_id: __self_0, - ty_name: __self_1, - hasher: __self_2, - } => { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "HasherCannotReconstructKey", - "ty_id", - __self_0, - "ty_name", - __self_1, - "hasher", - &__self_2, - ) - } - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for StorageAddressError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for StorageAddressError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - StorageAddressError::MapTypeMustBeTuple {} => { - __formatter.write_str("Storage map type must be a composite type") - } - StorageAddressError::WrongNumberOfKeys { actual, expected } => { - __formatter - .write_fmt( - format_args!( - "Storage lookup requires {0} keys but got {1} keys", - expected.as_display(), actual.as_display() - ), - ) - } - StorageAddressError::WrongNumberOfHashers { hashers, fields } => { - __formatter - .write_str( - "Storage entry in metadata does not have the correct number of hashers to fields", - ) - } - StorageAddressError::UnexpectedAddressBytes {} => { - __formatter - .write_str( - "Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata.", - ) - } - StorageAddressError::HasherCannotReconstructKey { - ty_id, - ty_name, - hasher, - } => { - __formatter - .write_fmt( - format_args!( - "An invalid hasher was used to reconstruct a value of type {0} (id={1}) from a hash formed by a {2:?} hasher. This is only possible for concat-style hashers or the identity hasher", - ty_name.as_display(), ty_id.as_display(), hasher - ), - ) - } - } - } - } - /// Something went wrong trying to access details in the metadata. - #[non_exhaustive] - pub enum MetadataError { - /// The DispatchError type isn't available in the metadata - #[error("The DispatchError type isn't available")] - DispatchErrorNotFound, - /// Type not found in metadata. - #[error("Type with ID {0} not found")] - TypeNotFound(u32), - /// Pallet not found (index). - #[error("Pallet with index {0} not found")] - PalletIndexNotFound(u8), - /// Pallet not found (name). - #[error("Pallet with name {0} not found")] - PalletNameNotFound(String), - /// Variant not found. - #[error("Variant with index {0} not found")] - VariantIndexNotFound(u8), - /// Constant not found. - #[error("Constant with name {0} not found")] - ConstantNameNotFound(String), - /// Call not found. - #[error("Call with name {0} not found")] - CallNameNotFound(String), - /// Runtime trait not found. - #[error("Runtime trait with name {0} not found")] - RuntimeTraitNotFound(String), - /// Runtime method not found. - #[error("Runtime method with name {0} not found")] - RuntimeMethodNotFound(String), - /// Call type not found in metadata. - #[error("Call type not found in pallet with index {0}")] - CallTypeNotFoundInPallet(u8), - /// Event type not found in metadata. - #[error("Event type not found in pallet with index {0}")] - EventTypeNotFoundInPallet(u8), - /// Storage details not found in metadata. - #[error("Storage details not found in pallet with name {0}")] - StorageNotFoundInPallet(String), - /// Storage entry not found. - #[error("Storage entry {0} not found")] - StorageEntryNotFound(String), - /// The generated interface used is not compatible with the node. - #[error("The generated code is not compatible with the node")] - IncompatibleCodegen, - /// Custom value not found. - #[error("Custom value with name {0} not found")] - CustomValueNameNotFound(String), - } - #[automatically_derived] - impl ::core::clone::Clone for MetadataError { - #[inline] - fn clone(&self) -> MetadataError { - match self { - MetadataError::DispatchErrorNotFound => { - MetadataError::DispatchErrorNotFound - } - MetadataError::TypeNotFound(__self_0) => { - MetadataError::TypeNotFound(::core::clone::Clone::clone(__self_0)) - } - MetadataError::PalletIndexNotFound(__self_0) => { - MetadataError::PalletIndexNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::PalletNameNotFound(__self_0) => { - MetadataError::PalletNameNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::VariantIndexNotFound(__self_0) => { - MetadataError::VariantIndexNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::ConstantNameNotFound(__self_0) => { - MetadataError::ConstantNameNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::CallNameNotFound(__self_0) => { - MetadataError::CallNameNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::RuntimeTraitNotFound(__self_0) => { - MetadataError::RuntimeTraitNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::RuntimeMethodNotFound(__self_0) => { - MetadataError::RuntimeMethodNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::CallTypeNotFoundInPallet(__self_0) => { - MetadataError::CallTypeNotFoundInPallet( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::EventTypeNotFoundInPallet(__self_0) => { - MetadataError::EventTypeNotFoundInPallet( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::StorageNotFoundInPallet(__self_0) => { - MetadataError::StorageNotFoundInPallet( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::StorageEntryNotFound(__self_0) => { - MetadataError::StorageEntryNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - MetadataError::IncompatibleCodegen => MetadataError::IncompatibleCodegen, - MetadataError::CustomValueNameNotFound(__self_0) => { - MetadataError::CustomValueNameNotFound( - ::core::clone::Clone::clone(__self_0), - ) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for MetadataError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - MetadataError::DispatchErrorNotFound => { - ::core::fmt::Formatter::write_str(f, "DispatchErrorNotFound") - } - MetadataError::TypeNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "TypeNotFound", - &__self_0, - ) - } - MetadataError::PalletIndexNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "PalletIndexNotFound", - &__self_0, - ) - } - MetadataError::PalletNameNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "PalletNameNotFound", - &__self_0, - ) - } - MetadataError::VariantIndexNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "VariantIndexNotFound", - &__self_0, - ) - } - MetadataError::ConstantNameNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ConstantNameNotFound", - &__self_0, - ) - } - MetadataError::CallNameNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "CallNameNotFound", - &__self_0, - ) - } - MetadataError::RuntimeTraitNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "RuntimeTraitNotFound", - &__self_0, - ) - } - MetadataError::RuntimeMethodNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "RuntimeMethodNotFound", - &__self_0, - ) - } - MetadataError::CallTypeNotFoundInPallet(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "CallTypeNotFoundInPallet", - &__self_0, - ) - } - MetadataError::EventTypeNotFoundInPallet(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "EventTypeNotFoundInPallet", - &__self_0, - ) - } - MetadataError::StorageNotFoundInPallet(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "StorageNotFoundInPallet", - &__self_0, - ) - } - MetadataError::StorageEntryNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "StorageEntryNotFound", - &__self_0, - ) - } - MetadataError::IncompatibleCodegen => { - ::core::fmt::Formatter::write_str(f, "IncompatibleCodegen") - } - MetadataError::CustomValueNameNotFound(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "CustomValueNameNotFound", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for MetadataError {} - #[automatically_derived] - impl ::core::cmp::PartialEq for MetadataError { - #[inline] - fn eq(&self, other: &MetadataError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - MetadataError::TypeNotFound(__self_0), - MetadataError::TypeNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::PalletIndexNotFound(__self_0), - MetadataError::PalletIndexNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::PalletNameNotFound(__self_0), - MetadataError::PalletNameNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::VariantIndexNotFound(__self_0), - MetadataError::VariantIndexNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::ConstantNameNotFound(__self_0), - MetadataError::ConstantNameNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::CallNameNotFound(__self_0), - MetadataError::CallNameNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::RuntimeTraitNotFound(__self_0), - MetadataError::RuntimeTraitNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::RuntimeMethodNotFound(__self_0), - MetadataError::RuntimeMethodNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::CallTypeNotFoundInPallet(__self_0), - MetadataError::CallTypeNotFoundInPallet(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::EventTypeNotFoundInPallet(__self_0), - MetadataError::EventTypeNotFoundInPallet(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::StorageNotFoundInPallet(__self_0), - MetadataError::StorageNotFoundInPallet(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::StorageEntryNotFound(__self_0), - MetadataError::StorageEntryNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MetadataError::CustomValueNameNotFound(__self_0), - MetadataError::CustomValueNameNotFound(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[allow(unused_qualifications)] - impl std::error::Error for MetadataError {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for MetadataError { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use thiserror::__private::AsDisplay as _; - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - MetadataError::DispatchErrorNotFound {} => { - __formatter.write_str("The DispatchError type isn't available") - } - MetadataError::TypeNotFound(_0) => { - __formatter - .write_fmt( - format_args!("Type with ID {0} not found", _0.as_display()), - ) - } - MetadataError::PalletIndexNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Pallet with index {0} not found", _0.as_display() - ), - ) - } - MetadataError::PalletNameNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Pallet with name {0} not found", _0.as_display() - ), - ) - } - MetadataError::VariantIndexNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Variant with index {0} not found", _0.as_display() - ), - ) - } - MetadataError::ConstantNameNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Constant with name {0} not found", _0.as_display() - ), - ) - } - MetadataError::CallNameNotFound(_0) => { - __formatter - .write_fmt( - format_args!("Call with name {0} not found", _0.as_display()), - ) - } - MetadataError::RuntimeTraitNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Runtime trait with name {0} not found", _0.as_display() - ), - ) - } - MetadataError::RuntimeMethodNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Runtime method with name {0} not found", _0.as_display() - ), - ) - } - MetadataError::CallTypeNotFoundInPallet(_0) => { - __formatter - .write_fmt( - format_args!( - "Call type not found in pallet with index {0}", _0 - .as_display() - ), - ) - } - MetadataError::EventTypeNotFoundInPallet(_0) => { - __formatter - .write_fmt( - format_args!( - "Event type not found in pallet with index {0}", _0 - .as_display() - ), - ) - } - MetadataError::StorageNotFoundInPallet(_0) => { - __formatter - .write_fmt( - format_args!( - "Storage details not found in pallet with name {0}", _0 - .as_display() - ), - ) - } - MetadataError::StorageEntryNotFound(_0) => { - __formatter - .write_fmt( - format_args!("Storage entry {0} not found", _0.as_display()), - ) - } - MetadataError::IncompatibleCodegen {} => { - __formatter - .write_str("The generated code is not compatible with the node") - } - MetadataError::CustomValueNameNotFound(_0) => { - __formatter - .write_fmt( - format_args!( - "Custom value with name {0} not found", _0.as_display() - ), - ) - } - } - } - } -} -pub mod events { - //! This module exposes the types and such necessary for working with events. - //! The two main entry points into events are [`crate::OnlineClient::events()`] - //! and calls like [crate::tx::TxProgress::wait_for_finalized_success()]. - mod events_client { - use crate::backend::{Backend, BackendExt, BlockRef}; - use crate::{client::OnlineClientT, error::Error, events::Events, Config}; - use derivative::Derivative; - use std::future::Future; - /// A client for working with events. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct EventsClient { - client: Client, - _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for EventsClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - EventsClient { client: ref __arg_0, _marker: ref __arg_1 } => { - EventsClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl EventsClient { - /// Create a new [`EventsClient`]. - pub fn new(client: Client) -> Self { - Self { - client, - _marker: std::marker::PhantomData, - } - } - } - impl EventsClient - where - T: Config, - Client: OnlineClientT, - { - /// Obtain events at some block hash. - /// - /// # Warning - /// - /// This call only supports blocks produced since the most recent - /// runtime upgrade. You can attempt to retrieve events from older blocks, - /// but may run into errors attempting to work with them. - pub fn at( - &self, - block_ref: impl Into>, - ) -> impl Future, Error>> + Send + 'static { - self.at_or_latest(Some(block_ref.into())) - } - /// Obtain events for the latest block. - pub fn at_latest( - &self, - ) -> impl Future, Error>> + Send + 'static { - self.at_or_latest(None) - } - /// Obtain events at some block hash. - fn at_or_latest( - &self, - block_ref: Option>, - ) -> impl Future, Error>> + Send + 'static { - let client = self.client.clone(); - async move { - let block_ref = match block_ref { - Some(r) => r, - None => client.backend().latest_finalized_block_ref().await?, - }; - let event_bytes = get_event_bytes(client.backend(), block_ref.hash()) - .await?; - Ok(Events::new(client.metadata(), block_ref.hash(), event_bytes)) - } - } - } - fn system_events_key() -> [u8; 32] { - let a = sp_core_hashing::twox_128(b"System"); - let b = sp_core_hashing::twox_128(b"Events"); - let mut res = [0; 32]; - res[0..16].clone_from_slice(&a); - res[16..32].clone_from_slice(&b); - res - } - pub(crate) async fn get_event_bytes( - backend: &dyn Backend, - block_hash: T::Hash, - ) -> Result, Error> { - Ok( - backend - .storage_fetch_value(system_events_key().to_vec(), block_hash) - .await? - .unwrap_or_default(), - ) - } - } - mod events_type { - //! A representation of a block of events. - use super::{Phase, StaticEvent}; - use crate::{ - client::OnlineClientT, error::{Error, MetadataError}, - events::events_client::get_event_bytes, metadata::types::PalletMetadata, - Config, Metadata, - }; - use codec::{Compact, Decode}; - use derivative::Derivative; - use scale_decode::DecodeAsType; - use std::sync::Arc; - /// A collection of events obtained from a block, bundled with the necessary - /// information needed to decode and iterate over them. - #[derivative(Clone(bound = ""))] - pub struct Events { - metadata: Metadata, - block_hash: T::Hash, - event_bytes: Arc<[u8]>, - start_idx: usize, - num_events: u32, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Events { - fn clone(&self) -> Self { - match *self { - Events { - metadata: ref __arg_0, - block_hash: ref __arg_1, - event_bytes: ref __arg_2, - start_idx: ref __arg_3, - num_events: ref __arg_4, - } => { - Events { - metadata: (*__arg_0).clone(), - block_hash: (*__arg_1).clone(), - event_bytes: (*__arg_2).clone(), - start_idx: (*__arg_3).clone(), - num_events: (*__arg_4).clone(), - } - } - } - } - } - impl std::fmt::Debug for Events { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Events") - .field("block_hash", &self.block_hash) - .field("event_bytes", &self.event_bytes) - .field("start_idx", &self.start_idx) - .field("num_events", &self.num_events) - .finish() - } - } - impl Events { - pub(crate) fn new( - metadata: Metadata, - block_hash: T::Hash, - event_bytes: Vec, - ) -> Self { - let cursor = &mut &*event_bytes; - let num_events = >::decode(cursor).unwrap_or(Compact(0)).0; - let start_idx = event_bytes.len() - cursor.len(); - Self { - metadata, - block_hash, - event_bytes: event_bytes.into(), - start_idx, - num_events, - } - } - /// Obtain the events from a block hash given custom metadata and a client. - /// - /// # Notes - /// - /// - Prefer to use [`crate::events::EventsClient::at`] to obtain the events. - /// - Subxt may fail to decode things that aren't from a runtime using the - /// latest metadata version. - /// - The client may not be able to obtain the block at the given hash. Only - /// archive nodes keep hold of all past block information. - pub async fn new_from_client( - metadata: Metadata, - block_hash: T::Hash, - client: Client, - ) -> Result - where - Client: OnlineClientT, - { - let event_bytes = get_event_bytes(client.backend(), block_hash).await?; - Ok(Events::new(metadata, block_hash, event_bytes)) - } - /// The number of events. - pub fn len(&self) -> u32 { - self.num_events - } - /// Are there no events in this block? - pub fn is_empty(&self) -> bool { - self.num_events == 0 - } - /// Return the block hash that these events are from. - pub fn block_hash(&self) -> T::Hash { - self.block_hash - } - /// Iterate over all of the events, using metadata to dynamically - /// decode them as we go, and returning the raw bytes and other associated - /// details. If an error occurs, all subsequent iterations return `None`. - pub fn iter( - &self, - ) -> impl Iterator< - Item = Result, Error>, - > + Send + Sync + 'static { - let event_bytes = self.event_bytes.clone(); - let metadata = self.metadata.clone(); - let num_events = self.num_events; - let mut pos = self.start_idx; - let mut index = 0; - std::iter::from_fn(move || { - if event_bytes.len() <= pos || num_events == index { - None - } else { - match EventDetails::decode_from( - metadata.clone(), - event_bytes.clone(), - pos, - index, - ) { - Ok(event_details) => { - pos += event_details.bytes().len(); - index += 1; - Some(Ok(event_details)) - } - Err(e) => { - pos = event_bytes.len(); - Some(Err(e)) - } - } - } - }) - } - /// Iterate through the events using metadata to dynamically decode and skip - /// them, and return only those which should decode to the provided `Ev` type. - /// If an error occurs, all subsequent iterations return `None`. - pub fn find( - &self, - ) -> impl Iterator> + '_ { - self.iter() - .filter_map(|ev| { - ev.and_then(|ev| ev.as_event::().map_err(Into::into)) - .transpose() - }) - } - /// Iterate through the events using metadata to dynamically decode and skip - /// them, and return the first event found which decodes to the provided `Ev` type. - pub fn find_first(&self) -> Result, Error> { - self.find::().next().transpose() - } - /// Iterate through the events using metadata to dynamically decode and skip - /// them, and return the last event found which decodes to the provided `Ev` type. - pub fn find_last(&self) -> Result, Error> { - self.find::().last().transpose() - } - /// Find an event that decodes to the type provided. Returns true if it was found. - pub fn has(&self) -> Result { - Ok(self.find::().next().transpose()?.is_some()) - } - } - /// The event details. - pub struct EventDetails { - phase: Phase, - /// The index of the event in the list of events in a given block. - index: u32, - all_bytes: Arc<[u8]>, - start_idx: usize, - event_start_idx: usize, - event_fields_start_idx: usize, - event_fields_end_idx: usize, - end_idx: usize, - metadata: Metadata, - topics: Vec, - } - #[automatically_derived] - impl ::core::fmt::Debug for EventDetails - where - T::Hash: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - let names: &'static _ = &[ - "phase", - "index", - "all_bytes", - "start_idx", - "event_start_idx", - "event_fields_start_idx", - "event_fields_end_idx", - "end_idx", - "metadata", - "topics", - ]; - let values: &[&dyn ::core::fmt::Debug] = &[ - &self.phase, - &self.index, - &self.all_bytes, - &self.start_idx, - &self.event_start_idx, - &self.event_fields_start_idx, - &self.event_fields_end_idx, - &self.end_idx, - &self.metadata, - &&self.topics, - ]; - ::core::fmt::Formatter::debug_struct_fields_finish( - f, - "EventDetails", - names, - values, - ) - } - } - #[automatically_derived] - impl ::core::clone::Clone for EventDetails - where - T::Hash: ::core::clone::Clone, - { - #[inline] - fn clone(&self) -> EventDetails { - EventDetails { - phase: ::core::clone::Clone::clone(&self.phase), - index: ::core::clone::Clone::clone(&self.index), - all_bytes: ::core::clone::Clone::clone(&self.all_bytes), - start_idx: ::core::clone::Clone::clone(&self.start_idx), - event_start_idx: ::core::clone::Clone::clone(&self.event_start_idx), - event_fields_start_idx: ::core::clone::Clone::clone( - &self.event_fields_start_idx, - ), - event_fields_end_idx: ::core::clone::Clone::clone( - &self.event_fields_end_idx, - ), - end_idx: ::core::clone::Clone::clone(&self.end_idx), - metadata: ::core::clone::Clone::clone(&self.metadata), - topics: ::core::clone::Clone::clone(&self.topics), - } - } - } - impl EventDetails { - fn decode_from( - metadata: Metadata, - all_bytes: Arc<[u8]>, - start_idx: usize, - index: u32, - ) -> Result, Error> { - let input = &mut &all_bytes[start_idx..]; - let phase = Phase::decode(input)?; - let event_start_idx = all_bytes.len() - input.len(); - let pallet_index = u8::decode(input)?; - let variant_index = u8::decode(input)?; - let event_fields_start_idx = all_bytes.len() - input.len(); - let event_pallet = metadata.pallet_by_index_err(pallet_index)?; - let event_variant = event_pallet - .event_variant_by_index(variant_index) - .ok_or(MetadataError::VariantIndexNotFound(variant_index))?; - { - use ::tracing::__macro_support::Callsite as _; - static __CALLSITE: ::tracing::callsite::DefaultCallsite = { - static META: ::tracing::Metadata<'static> = { - ::tracing_core::metadata::Metadata::new( - "event subxt/src/events/events_type.rs:220", - "subxt::events::events_type", - ::tracing::Level::DEBUG, - ::core::option::Option::Some( - "subxt/src/events/events_type.rs", - ), - ::core::option::Option::Some(220u32), - ::core::option::Option::Some("subxt::events::events_type"), - ::tracing_core::field::FieldSet::new( - &["message"], - ::tracing_core::callsite::Identifier(&__CALLSITE), - ), - ::tracing::metadata::Kind::EVENT, - ) - }; - ::tracing::callsite::DefaultCallsite::new(&META) - }; - let enabled = ::tracing::Level::DEBUG - <= ::tracing::level_filters::STATIC_MAX_LEVEL - && ::tracing::Level::DEBUG - <= ::tracing::level_filters::LevelFilter::current() - && { - let interest = __CALLSITE.interest(); - !interest.is_never() - && ::tracing::__macro_support::__is_enabled( - __CALLSITE.metadata(), - interest, - ) - }; - if enabled { - (|value_set: ::tracing::field::ValueSet| { - let meta = __CALLSITE.metadata(); - ::tracing::Event::dispatch(meta, &value_set); - })({ - #[allow(unused_imports)] - use ::tracing::field::{debug, display, Value}; - let mut iter = __CALLSITE.metadata().fields().iter(); - __CALLSITE - .metadata() - .fields() - .value_set( - &[ - ( - &::core::iter::Iterator::next(&mut iter) - .expect("FieldSet corrupted (this is a bug)"), - ::core::option::Option::Some( - &format_args!( - "Decoding Event \'{0}::{1}\'", event_pallet.name(), & - event_variant.name - ) as &dyn Value, - ), - ), - ], - ) - }); - } else { - } - }; - for field_metadata in &event_variant.fields { - scale_decode::visitor::decode_with_visitor( - input, - field_metadata.ty.id, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) - .map_err(scale_decode::Error::from)?; - } - let event_fields_end_idx = all_bytes.len() - input.len(); - let topics = Vec::::decode(input)?; - let end_idx = all_bytes.len() - input.len(); - Ok(EventDetails { - phase, - index, - start_idx, - event_start_idx, - event_fields_start_idx, - event_fields_end_idx, - end_idx, - all_bytes, - metadata, - topics, - }) - } - /// When was the event produced? - pub fn phase(&self) -> Phase { - self.phase - } - /// What index is this event in the stored events for this block. - pub fn index(&self) -> u32 { - self.index - } - /// The index of the pallet that the event originated from. - pub fn pallet_index(&self) -> u8 { - self.all_bytes[self.event_fields_start_idx - 2] - } - /// The index of the event variant that the event originated from. - pub fn variant_index(&self) -> u8 { - self.all_bytes[self.event_fields_start_idx - 1] - } - /// The name of the pallet from whence the Event originated. - pub fn pallet_name(&self) -> &str { - self.event_metadata().pallet.name() - } - /// The name of the event (ie the name of the variant that it corresponds to). - pub fn variant_name(&self) -> &str { - &self.event_metadata().variant.name - } - /// Fetch details from the metadata for this event. - pub fn event_metadata(&self) -> EventMetadataDetails { - let pallet = self - .metadata - .pallet_by_index(self.pallet_index()) - .expect( - "event pallet to be found; we did this already during decoding", - ); - let variant = pallet - .event_variant_by_index(self.variant_index()) - .expect( - "event variant to be found; we did this already during decoding", - ); - EventMetadataDetails { - pallet, - variant, - } - } - /// Return _all_ of the bytes representing this event, which include, in order: - /// - The phase. - /// - Pallet and event index. - /// - Event fields. - /// - Event Topics. - pub fn bytes(&self) -> &[u8] { - &self.all_bytes[self.start_idx..self.end_idx] - } - /// Return the bytes representing the fields stored in this event. - pub fn field_bytes(&self) -> &[u8] { - &self.all_bytes[self.event_fields_start_idx..self.event_fields_end_idx] - } - /// Decode and provide the event fields back in the form of a [`scale_value::Composite`] - /// type which represents the named or unnamed fields that were present in the event. - pub fn field_values( - &self, - ) -> Result, Error> { - let bytes = &mut self.field_bytes(); - let event_metadata = self.event_metadata(); - let mut fields = event_metadata - .variant - .fields - .iter() - .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); - use scale_decode::DecodeAsFields; - let decoded = >::decode_as_fields(bytes, &mut fields, self.metadata.types())?; - Ok(decoded) - } - /// Attempt to decode these [`EventDetails`] into a type representing the event fields. - /// Such types are exposed in the codegen as `pallet_name::events::EventName` types. - pub fn as_event(&self) -> Result, Error> { - let ev_metadata = self.event_metadata(); - if ev_metadata.pallet.name() == E::PALLET - && ev_metadata.variant.name == E::EVENT - { - let mut fields = ev_metadata - .variant - .fields - .iter() - .map(|f| scale_decode::Field::new(f.ty.id, f.name.as_deref())); - let decoded = E::decode_as_fields( - &mut self.field_bytes(), - &mut fields, - self.metadata.types(), - )?; - Ok(Some(decoded)) - } else { - Ok(None) - } - } - /// Attempt to decode these [`EventDetails`] into a root event type (which includes - /// the pallet and event enum variants as well as the event fields). A compatible - /// type for this is exposed via static codegen as a root level `Event` type. - pub fn as_root_event(&self) -> Result { - let bytes = &self - .all_bytes[self.event_start_idx..self.event_fields_end_idx]; - let decoded = E::decode_as_type( - &mut &bytes[..], - self.metadata.outer_enums().event_enum_ty(), - self.metadata.types(), - )?; - Ok(decoded) - } - /// Return the topics associated with this event. - pub fn topics(&self) -> &[T::Hash] { - &self.topics - } - } - /// Details for the given event plucked from the metadata. - pub struct EventMetadataDetails<'a> { - pub pallet: PalletMetadata<'a>, - pub variant: &'a scale_info::Variant, - } - } - use codec::{Decode, Encode}; - pub use events_client::EventsClient; - pub use events_type::{EventDetails, Events}; - use scale_decode::DecodeAsFields; - /// Trait to uniquely identify the events's identity from the runtime metadata. - /// - /// Generated API structures that represent an event implement this trait. - /// - /// The trait is utilized to decode emitted events from a block, via obtaining the - /// form of the `Event` from the metadata. - pub trait StaticEvent: DecodeAsFields { - /// Pallet name. - const PALLET: &'static str; - /// Event name. - const EVENT: &'static str; - /// Returns true if the given pallet and event names match this event. - fn is_event(pallet: &str, event: &str) -> bool { - Self::PALLET == pallet && Self::EVENT == event - } - } - /// A phase of a block's execution. - pub enum Phase { - /// Applying an extrinsic. - ApplyExtrinsic(u32), - /// Finalizing the block. - Finalization, - /// Initializing the block. - Initialization, - } - #[automatically_derived] - impl ::core::marker::Copy for Phase {} - #[automatically_derived] - impl ::core::clone::Clone for Phase { - #[inline] - fn clone(&self) -> Phase { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Phase { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - Phase::ApplyExtrinsic(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "ApplyExtrinsic", - &__self_0, - ) - } - Phase::Finalization => { - ::core::fmt::Formatter::write_str(f, "Finalization") - } - Phase::Initialization => { - ::core::fmt::Formatter::write_str(f, "Initialization") - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Phase { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Phase {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Phase { - #[inline] - fn eq(&self, other: &Phase) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - Phase::ApplyExtrinsic(__self_0), - Phase::ApplyExtrinsic(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for Phase { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e.chain("Could not decode `Phase`, failed to read variant byte") - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - Phase::ApplyExtrinsic({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `Phase::ApplyExtrinsic.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(Phase::Finalization) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(Phase::Initialization) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into("Could not decode `Phase`, variant doesn't exist"), - ) - })(); - } - } - } - } - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for Phase { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - Phase::ApplyExtrinsic(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - Phase::Finalization => 0_usize, - Phase::Initialization => 0_usize, - _ => 0_usize, - } - } - fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>( - &self, - __codec_dest_edqy: &mut __CodecOutputEdqy, - ) { - match *self { - Phase::ApplyExtrinsic(ref aa) => { - __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - Phase::Finalization => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); - } - Phase::Initialization => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::codec::EncodeLike for Phase {} - }; -} -pub mod metadata { - //! Types representing the metadata obtained from a node. - mod decode_encode_traits { - use super::Metadata; - use crate::error::Error; - /// This trait is implemented for all types that also implement [`scale_decode::DecodeAsType`]. - pub trait DecodeWithMetadata: Sized { - /// Given some metadata and a type ID, attempt to SCALE decode the provided bytes into `Self`. - fn decode_with_metadata( - bytes: &mut &[u8], - type_id: u32, - metadata: &Metadata, - ) -> Result; - } - impl DecodeWithMetadata for T { - fn decode_with_metadata( - bytes: &mut &[u8], - type_id: u32, - metadata: &Metadata, - ) -> Result { - let val = T::decode_as_type(bytes, type_id, metadata.types())?; - Ok(val) - } - } - /// This trait is implemented for all types that also implement [`scale_encode::EncodeAsType`]. - pub trait EncodeWithMetadata { - /// SCALE encode this type to bytes, possibly with the help of metadata. - fn encode_with_metadata( - &self, - type_id: u32, - metadata: &Metadata, - bytes: &mut Vec, - ) -> Result<(), Error>; - } - impl EncodeWithMetadata for T { - /// SCALE encode this type to bytes, possibly with the help of metadata. - fn encode_with_metadata( - &self, - type_id: u32, - metadata: &Metadata, - bytes: &mut Vec, - ) -> Result<(), Error> { - self.encode_as_type_to(type_id, metadata.types(), bytes)?; - Ok(()) - } - } - } - mod metadata_type { - use crate::error::MetadataError; - use std::sync::Arc; - /// A cheaply clone-able representation of the runtime metadata received from a node. - pub struct Metadata { - inner: Arc, - } - #[automatically_derived] - impl ::core::clone::Clone for Metadata { - #[inline] - fn clone(&self) -> Metadata { - Metadata { - inner: ::core::clone::Clone::clone(&self.inner), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Metadata { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "Metadata", - "inner", - &&self.inner, - ) - } - } - impl std::ops::Deref for Metadata { - type Target = subxt_metadata::Metadata; - fn deref(&self) -> &Self::Target { - &self.inner - } - } - impl Metadata { - pub(crate) fn new(md: subxt_metadata::Metadata) -> Self { - Metadata { inner: Arc::new(md) } - } - /// Identical to `metadata.pallet_by_name()`, but returns an error if the pallet is not found. - pub fn pallet_by_name_err( - &self, - name: &str, - ) -> Result { - self.pallet_by_name(name) - .ok_or_else(|| MetadataError::PalletNameNotFound(name.to_owned())) - } - /// Identical to `metadata.pallet_by_index()`, but returns an error if the pallet is not found. - pub fn pallet_by_index_err( - &self, - index: u8, - ) -> Result { - self.pallet_by_index(index) - .ok_or(MetadataError::PalletIndexNotFound(index)) - } - /// Identical to `metadata.runtime_api_trait_by_name()`, but returns an error if the trait is not found. - pub fn runtime_api_trait_by_name_err( - &self, - name: &str, - ) -> Result { - self.runtime_api_trait_by_name(name) - .ok_or_else(|| MetadataError::RuntimeTraitNotFound(name.to_owned())) - } - } - impl From for Metadata { - fn from(md: subxt_metadata::Metadata) -> Self { - Metadata::new(md) - } - } - impl TryFrom for Metadata { - type Error = subxt_metadata::TryFromError; - fn try_from( - value: frame_metadata::RuntimeMetadataPrefixed, - ) -> Result { - subxt_metadata::Metadata::try_from(value).map(Metadata::from) - } - } - impl codec::Decode for Metadata { - fn decode(input: &mut I) -> Result { - subxt_metadata::Metadata::decode(input).map(Metadata::new) - } - } - } - pub use decode_encode_traits::{DecodeWithMetadata, EncodeWithMetadata}; - pub use metadata_type::Metadata; - pub use subxt_metadata as types; -} -pub mod runtime_api { - //! Types associated with executing runtime API calls. - mod runtime_client { - use super::runtime_types::RuntimeApi; - use crate::{backend::BlockRef, client::OnlineClientT, error::Error, Config}; - use derivative::Derivative; - use std::{future::Future, marker::PhantomData}; - /// Execute runtime API calls. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct RuntimeApiClient { - client: Client, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for RuntimeApiClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - RuntimeApiClient { client: ref __arg_0, _marker: ref __arg_1 } => { - RuntimeApiClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl RuntimeApiClient { - /// Create a new [`RuntimeApiClient`] - pub fn new(client: Client) -> Self { - Self { - client, - _marker: PhantomData, - } - } - } - impl RuntimeApiClient - where - T: Config, - Client: OnlineClientT, - { - /// Obtain a runtime API interface at some block hash. - pub fn at( - &self, - block_ref: impl Into>, - ) -> RuntimeApi { - RuntimeApi::new(self.client.clone(), block_ref.into()) - } - /// Obtain a runtime API interface at the latest block hash. - pub fn at_latest( - &self, - ) -> impl Future< - Output = Result, Error>, - > + Send + 'static { - let client = self.client.clone(); - async move { - let block_ref = client.backend().latest_finalized_block_ref().await?; - Ok(RuntimeApi::new(client, block_ref)) - } - } - } - } - mod runtime_payload { - use core::marker::PhantomData; - use derivative::Derivative; - use scale_encode::EncodeAsFields; - use scale_value::Composite; - use std::borrow::Cow; - use crate::dynamic::DecodedValueThunk; - use crate::error::MetadataError; - use crate::{metadata::DecodeWithMetadata, Error, Metadata}; - /// This represents a runtime API payload that can call into the runtime of node. - /// - /// # Components - /// - /// - associated return type - /// - /// Resulting bytes of the call are interpreted into this type. - /// - /// - runtime function name - /// - /// The function name of the runtime API call. This is obtained by concatenating - /// the runtime trait name with the trait's method. - /// - /// For example, the substrate runtime trait [Metadata](https://github.com/paritytech/substrate/blob/cb954820a8d8d765ce75021e244223a3b4d5722d/primitives/api/src/lib.rs#L745) - /// contains the `metadata_at_version` function. The corresponding runtime function - /// is `Metadata_metadata_at_version`. - /// - /// - encoded arguments - /// - /// Each argument of the runtime function must be scale-encoded. - pub trait RuntimeApiPayload { - /// The return type of the function call. - type ReturnType: DecodeWithMetadata; - /// The runtime API trait name. - fn trait_name(&self) -> &str; - /// The runtime API method name. - fn method_name(&self) -> &str; - /// Scale encode the arguments data. - fn encode_args_to( - &self, - metadata: &Metadata, - out: &mut Vec, - ) -> Result<(), Error>; - /// Encode arguments data and return the output. This is a convenience - /// wrapper around [`RuntimeApiPayload::encode_args_to`]. - fn encode_args(&self, metadata: &Metadata) -> Result, Error> { - let mut v = Vec::new(); - self.encode_args_to(metadata, &mut v)?; - Ok(v) - } - /// Returns the statically generated validation hash. - fn validation_hash(&self) -> Option<[u8; 32]> { - None - } - } - /// A runtime API payload containing the generic argument data - /// and interpreting the result of the call as `ReturnTy`. - /// - /// This can be created from static values (ie those generated - /// via the `subxt` macro) or dynamic values via [`dynamic`]. - #[derivative( - Clone(bound = "ArgsData: Clone"), - Debug(bound = "ArgsData: std::fmt::Debug"), - Eq(bound = "ArgsData: std::cmp::Eq"), - Ord(bound = "ArgsData: std::cmp::Ord"), - PartialEq(bound = "ArgsData: std::cmp::PartialEq"), - PartialOrd(bound = "ArgsData: std::cmp::PartialOrd") - )] - pub struct Payload { - trait_name: Cow<'static, str>, - method_name: Cow<'static, str>, - args_data: ArgsData, - validation_hash: Option<[u8; 32]>, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Payload - where - ArgsData: Clone, - { - fn clone(&self) -> Self { - match *self { - Payload { - trait_name: ref __arg_0, - method_name: ref __arg_1, - args_data: ref __arg_2, - validation_hash: ref __arg_3, - _marker: ref __arg_4, - } => { - Payload { - trait_name: (*__arg_0).clone(), - method_name: (*__arg_1).clone(), - args_data: (*__arg_2).clone(), - validation_hash: (*__arg_3).clone(), - _marker: (*__arg_4).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Payload - where - ArgsData: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Payload { - trait_name: ref __arg_0, - method_name: ref __arg_1, - args_data: ref __arg_2, - validation_hash: ref __arg_3, - _marker: ref __arg_4, - } => { - let mut __debug_trait_builder = __f.debug_struct("Payload"); - let _ = __debug_trait_builder.field("trait_name", &&(*__arg_0)); - let _ = __debug_trait_builder.field("method_name", &&(*__arg_1)); - let _ = __debug_trait_builder.field("args_data", &&(*__arg_2)); - let _ = __debug_trait_builder - .field("validation_hash", &&(*__arg_3)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_4)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for Payload - where - ArgsData: std::cmp::Eq, - {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for Payload - where - ArgsData: std::cmp::PartialEq, - { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - Payload { - trait_name: ref __self_0, - method_name: ref __self_1, - args_data: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Payload { - trait_name: ref __other_0, - method_name: ref __other_1, - args_data: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - && &(*__self_3) == &(*__other_3) - && &(*__self_4) == &(*__other_4) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialOrd for Payload - where - ArgsData: std::cmp::PartialOrd, - { - fn partial_cmp( - &self, - other: &Self, - ) -> ::std::option::Option<::std::cmp::Ordering> { - match *self { - Payload { - trait_name: ref __self_0, - method_name: ref __self_1, - args_data: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Payload { - trait_name: ref __other_0, - method_name: ref __other_1, - args_data: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_0), - &(*__other_0), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_1), - &(*__other_1), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_2), - &(*__other_2), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_3), - &(*__other_3), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_4), - &(*__other_4), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::Ord for Payload - where - ArgsData: std::cmp::Ord, - { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - Payload { - trait_name: ref __self_0, - method_name: ref __self_1, - args_data: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Payload { - trait_name: ref __other_0, - method_name: ref __other_1, - args_data: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_4), &(*__other_4)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - impl RuntimeApiPayload - for Payload { - type ReturnType = ReturnTy; - fn trait_name(&self) -> &str { - &self.trait_name - } - fn method_name(&self) -> &str { - &self.method_name - } - fn encode_args_to( - &self, - metadata: &Metadata, - out: &mut Vec, - ) -> Result<(), Error> { - let api_method = metadata - .runtime_api_trait_by_name_err(&self.trait_name)? - .method_by_name(&self.method_name) - .ok_or_else(|| MetadataError::RuntimeMethodNotFound( - (*self.method_name).to_owned(), - ))?; - let mut fields = api_method - .inputs() - .map(|input| scale_encode::Field::named(input.ty, &input.name)); - self.args_data.encode_as_fields_to(&mut fields, metadata.types(), out)?; - Ok(()) - } - fn validation_hash(&self) -> Option<[u8; 32]> { - self.validation_hash - } - } - /// A dynamic runtime API payload. - pub type DynamicRuntimeApiPayload = Payload, DecodedValueThunk>; - impl Payload { - /// Create a new [`Payload`]. - pub fn new( - trait_name: impl Into, - method_name: impl Into, - args_data: ArgsData, - ) -> Self { - Payload { - trait_name: Cow::Owned(trait_name.into()), - method_name: Cow::Owned(method_name.into()), - args_data, - validation_hash: None, - _marker: PhantomData, - } - } - /// Create a new static [`Payload`] using static function name - /// and scale-encoded argument data. - /// - /// This is only expected to be used from codegen. - #[doc(hidden)] - pub fn new_static( - trait_name: &'static str, - method_name: &'static str, - args_data: ArgsData, - hash: [u8; 32], - ) -> Payload { - Payload { - trait_name: Cow::Borrowed(trait_name), - method_name: Cow::Borrowed(method_name), - args_data, - validation_hash: Some(hash), - _marker: std::marker::PhantomData, - } - } - /// Do not validate this call prior to submitting it. - pub fn unvalidated(self) -> Self { - Self { - validation_hash: None, - ..self - } - } - /// Returns the trait name. - pub fn trait_name(&self) -> &str { - &self.trait_name - } - /// Returns the method name. - pub fn method_name(&self) -> &str { - &self.method_name - } - /// Returns the arguments data. - pub fn args_data(&self) -> &ArgsData { - &self.args_data - } - } - /// Create a new [`DynamicRuntimeApiPayload`]. - pub fn dynamic( - trait_name: impl Into, - method_name: impl Into, - args_data: impl Into>, - ) -> DynamicRuntimeApiPayload { - Payload::new(trait_name, method_name, args_data.into()) - } - } - mod runtime_types { - use crate::{ - backend::{BackendExt, BlockRef}, - client::OnlineClientT, error::{Error, MetadataError}, - metadata::DecodeWithMetadata, Config, - }; - use codec::Decode; - use derivative::Derivative; - use std::{future::Future, marker::PhantomData}; - use super::RuntimeApiPayload; - /// Execute runtime API calls. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct RuntimeApi { - client: Client, - block_ref: BlockRef, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for RuntimeApi - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - RuntimeApi { - client: ref __arg_0, - block_ref: ref __arg_1, - _marker: ref __arg_2, - } => { - RuntimeApi { - client: (*__arg_0).clone(), - block_ref: (*__arg_1).clone(), - _marker: (*__arg_2).clone(), - } - } - } - } - } - impl RuntimeApi { - /// Create a new [`RuntimeApi`] - pub(crate) fn new(client: Client, block_ref: BlockRef) -> Self { - Self { - client, - block_ref, - _marker: PhantomData, - } - } - } - impl RuntimeApi - where - T: Config, - Client: OnlineClientT, - { - /// Execute a raw runtime API call. - pub fn call_raw<'a, Res: Decode>( - &self, - function: &'a str, - call_parameters: Option<&'a [u8]>, - ) -> impl Future> + 'a { - let client = self.client.clone(); - let block_hash = self.block_ref.hash(); - async move { - let data: Res = client - .backend() - .call_decoding(function, call_parameters, block_hash) - .await?; - Ok(data) - } - } - /// Execute a runtime API call. - pub fn call( - &self, - payload: Call, - ) -> impl Future> { - let client = self.client.clone(); - let block_hash = self.block_ref.hash(); - async move { - let metadata = client.metadata(); - let api_trait = metadata - .runtime_api_trait_by_name_err(payload.trait_name())?; - let api_method = api_trait - .method_by_name(payload.method_name()) - .ok_or_else(|| { - MetadataError::RuntimeMethodNotFound( - payload.method_name().to_owned(), - ) - })?; - if let Some(static_hash) = payload.validation_hash() { - let Some(runtime_hash) = api_trait - .method_hash(payload.method_name()) else { - return Err(MetadataError::IncompatibleCodegen.into()); - }; - if static_hash != runtime_hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - } - let params = payload.encode_args(&metadata)?; - let call_name = { - let res = ::alloc::fmt::format( - format_args!( - "{0}_{1}", payload.trait_name(), payload.method_name() - ), - ); - res - }; - let bytes = client - .backend() - .call(&call_name, Some(params.as_slice()), block_hash) - .await?; - let value = ::decode_with_metadata( - &mut &bytes[..], - api_method.output_ty(), - &metadata, - )?; - Ok(value) - } - } - } - } - pub use runtime_client::RuntimeApiClient; - pub use runtime_payload::{ - dynamic, DynamicRuntimeApiPayload, Payload, RuntimeApiPayload, - }; - pub use runtime_types::RuntimeApi; -} -pub mod storage { - //! Types associated with accessing and working with storage items. - mod storage_address { - use crate::{ - dynamic::DecodedValueThunk, - error::{Error, MetadataError, StorageAddressError}, - metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, - utils::{Encoded, Static}, - }; - use derivative::Derivative; - use scale_info::TypeDef; - use std::borrow::Cow; - use subxt_metadata::{StorageEntryType, StorageHasher}; - use super::StorageKey; - /// This represents a storage address. Anything implementing this trait - /// can be used to fetch and iterate over storage entries. - pub trait StorageAddress { - /// The target type of the value that lives at this address. - type Target: DecodeWithMetadata; - /// The keys type used to construct this address. - type Keys: StorageKey; - /// Can an entry be fetched from this address? - /// Set this type to [`Yes`] to enable the corresponding calls to be made. - type IsFetchable; - /// Can a default entry be obtained from this address? - /// Set this type to [`Yes`] to enable the corresponding calls to be made. - type IsDefaultable; - /// Can this address be iterated over? - /// Set this type to [`Yes`] to enable the corresponding calls to be made. - type IsIterable; - /// The name of the pallet that the entry lives under. - fn pallet_name(&self) -> &str; - /// The name of the entry in a given pallet that the item is at. - fn entry_name(&self) -> &str; - /// Output the non-prefix bytes; that is, any additional bytes that need - /// to be appended to the key to dig into maps. - fn append_entry_bytes( - &self, - metadata: &Metadata, - bytes: &mut Vec, - ) -> Result<(), Error>; - /// An optional hash which, if present, will be checked against - /// the node metadata to confirm that the return type matches what - /// we are expecting. - fn validation_hash(&self) -> Option<[u8; 32]> { - None - } - } - /// Used to signal whether a [`StorageAddress`] can be iterated, - /// fetched and returned with a default value in the type system. - pub struct Yes; - /// A concrete storage address. This can be created from static values (ie those generated - /// via the `subxt` macro) or dynamic values via [`dynamic`]. - #[derivative( - Clone(bound = "Keys: Clone"), - Debug(bound = "Keys: std::fmt::Debug"), - Eq(bound = "Keys: std::cmp::Eq"), - Ord(bound = "Keys: std::cmp::Ord"), - PartialEq(bound = "Keys: std::cmp::PartialEq"), - PartialOrd(bound = "Keys: std::cmp::PartialOrd") - )] - pub struct Address< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > { - pallet_name: Cow<'static, str>, - entry_name: Cow<'static, str>, - keys: Keys, - validation_hash: Option<[u8; 32]>, - _marker: std::marker::PhantomData< - (ReturnTy, Fetchable, Defaultable, Iterable), - >, - } - #[allow(unused_qualifications)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::clone::Clone - for Address - where - Keys: Clone, - { - fn clone(&self) -> Self { - match *self { - Address { - pallet_name: ref __arg_0, - entry_name: ref __arg_1, - keys: ref __arg_2, - validation_hash: ref __arg_3, - _marker: ref __arg_4, - } => { - Address { - pallet_name: (*__arg_0).clone(), - entry_name: (*__arg_1).clone(), - keys: (*__arg_2).clone(), - validation_hash: (*__arg_3).clone(), - _marker: (*__arg_4).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::fmt::Debug for Address - where - Keys: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Address { - pallet_name: ref __arg_0, - entry_name: ref __arg_1, - keys: ref __arg_2, - validation_hash: ref __arg_3, - _marker: ref __arg_4, - } => { - let mut __debug_trait_builder = __f.debug_struct("Address"); - let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); - let _ = __debug_trait_builder.field("entry_name", &&(*__arg_1)); - let _ = __debug_trait_builder.field("keys", &&(*__arg_2)); - let _ = __debug_trait_builder - .field("validation_hash", &&(*__arg_3)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_4)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq - for Address - where - Keys: std::cmp::Eq, - {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::cmp::PartialEq - for Address - where - Keys: std::cmp::PartialEq, - { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - Address { - pallet_name: ref __self_0, - entry_name: ref __self_1, - keys: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Address { - pallet_name: ref __other_0, - entry_name: ref __other_1, - keys: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - && &(*__self_3) == &(*__other_3) - && &(*__self_4) == &(*__other_4) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::cmp::PartialOrd - for Address - where - Keys: std::cmp::PartialOrd, - { - fn partial_cmp( - &self, - other: &Self, - ) -> ::std::option::Option<::std::cmp::Ordering> { - match *self { - Address { - pallet_name: ref __self_0, - entry_name: ref __self_1, - keys: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Address { - pallet_name: ref __other_0, - entry_name: ref __other_1, - keys: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_0), - &(*__other_0), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_1), - &(*__other_1), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_2), - &(*__other_2), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_3), - &(*__other_3), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_4), - &(*__other_4), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl< - Keys: StorageKey, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > ::std::cmp::Ord for Address - where - Keys: std::cmp::Ord, - { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - Address { - pallet_name: ref __self_0, - entry_name: ref __self_1, - keys: ref __self_2, - validation_hash: ref __self_3, - _marker: ref __self_4, - } => { - match *other { - Address { - pallet_name: ref __other_0, - entry_name: ref __other_1, - keys: ref __other_2, - validation_hash: ref __other_3, - _marker: ref __other_4, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_4), &(*__other_4)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - /// A storage key for static encoded values. - /// The original value is only present at construction, but can be decoded from the contained bytes. - #[derivative(Clone(bound = ""), Debug(bound = ""))] - pub struct StaticStorageKey { - pub(super) bytes: Static, - pub(super) _marker: std::marker::PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for StaticStorageKey { - fn clone(&self) -> Self { - match *self { - StaticStorageKey { bytes: ref __arg_0, _marker: ref __arg_1 } => { - StaticStorageKey { - bytes: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for StaticStorageKey { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - StaticStorageKey { bytes: ref __arg_0, _marker: ref __arg_1 } => { - let mut __debug_trait_builder = __f - .debug_struct("StaticStorageKey"); - let _ = __debug_trait_builder.field("bytes", &&(*__arg_0)); - let _ = __debug_trait_builder.field("_marker", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - impl StaticStorageKey { - /// Creates a new static storage key - pub fn new(key: &K) -> Self { - StaticStorageKey { - bytes: Static(Encoded(key.encode())), - _marker: std::marker::PhantomData, - } - } - /// Returns the scale-encoded bytes that make up this key - pub fn bytes(&self) -> &[u8] { - &self.bytes.0.0 - } - } - /// A typical storage address constructed at runtime rather than via the `subxt` macro; this - /// has no restriction on what it can be used for (since we don't statically know). - pub type DynamicAddress = Address; - impl DynamicAddress { - /// Creates a new dynamic address. As `Keys` you can use a `Vec` - pub fn new( - pallet_name: impl Into, - entry_name: impl Into, - keys: Keys, - ) -> Self { - Self { - pallet_name: Cow::Owned(pallet_name.into()), - entry_name: Cow::Owned(entry_name.into()), - keys, - validation_hash: None, - _marker: std::marker::PhantomData, - } - } - } - impl< - Keys, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > Address - where - Keys: StorageKey, - ReturnTy: DecodeWithMetadata, - { - /// Create a new [`Address`] using static strings for the pallet and call name. - /// This is only expected to be used from codegen. - #[doc(hidden)] - pub fn new_static( - pallet_name: &'static str, - entry_name: &'static str, - keys: Keys, - hash: [u8; 32], - ) -> Self { - Self { - pallet_name: Cow::Borrowed(pallet_name), - entry_name: Cow::Borrowed(entry_name), - keys, - validation_hash: Some(hash), - _marker: std::marker::PhantomData, - } - } - } - impl< - Keys, - ReturnTy, - Fetchable, - Defaultable, - Iterable, - > Address - where - Keys: StorageKey, - ReturnTy: DecodeWithMetadata, - { - /// Do not validate this storage entry prior to accessing it. - pub fn unvalidated(self) -> Self { - Self { - validation_hash: None, - ..self - } - } - /// Return bytes representing the root of this storage entry (ie a hash of - /// the pallet and entry name). Use [`crate::storage::StorageClient::address_bytes()`] - /// to obtain the bytes representing the entire address. - pub fn to_root_bytes(&self) -> Vec { - super::utils::storage_address_root_bytes(self) - } - } - impl StorageAddress - for Address - where - Keys: StorageKey, - ReturnTy: DecodeWithMetadata, - { - type Target = ReturnTy; - type Keys = Keys; - type IsFetchable = Fetchable; - type IsDefaultable = Defaultable; - type IsIterable = Iterable; - fn pallet_name(&self) -> &str { - &self.pallet_name - } - fn entry_name(&self) -> &str { - &self.entry_name - } - fn append_entry_bytes( - &self, - metadata: &Metadata, - bytes: &mut Vec, - ) -> Result<(), Error> { - let pallet = metadata.pallet_by_name_err(self.pallet_name())?; - let storage = pallet - .storage() - .ok_or_else(|| MetadataError::StorageNotFoundInPallet( - self.pallet_name().to_owned(), - ))?; - let entry = storage - .entry_by_name(self.entry_name()) - .ok_or_else(|| MetadataError::StorageEntryNotFound( - self.entry_name().to_owned(), - ))?; - let keys_iter = self.keys.keys_iter(); - let keys_len = self.keys.keys_len(); - if keys_len == 0 { - return Ok(()); - } - let StorageEntryType::Map { hashers, key_ty, .. } = entry - .entry_type() else { - return Err( - StorageAddressError::WrongNumberOfKeys { - expected: 0, - actual: keys_len, - } - .into(), - ); - }; - let ty = metadata - .types() - .resolve(*key_ty) - .ok_or(MetadataError::TypeNotFound(*key_ty))?; - let type_ids = match &ty.type_def { - TypeDef::Tuple(tuple) => { - either::Either::Left(tuple.fields.iter().map(|f| f.id)) - } - _other => either::Either::Right(std::iter::once(*key_ty)), - }; - if hashers.len() == 1 { - let mut input = Vec::new(); - let iter = keys_iter.zip(type_ids); - for (key, type_id) in iter { - key.encode_with_metadata(type_id, metadata, &mut input)?; - } - hash_bytes(&input, &hashers[0], bytes); - } else if hashers.len() >= type_ids.len() { - let iter = keys_iter.zip(type_ids).zip(hashers); - for ((key, type_id), hasher) in iter { - let mut input = Vec::new(); - key.encode_with_metadata(type_id, metadata, &mut input)?; - hash_bytes(&input, hasher, bytes); - } - } else { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: hashers.len(), - fields: type_ids.len(), - } - .into(), - ); - } - Ok(()) - } - fn validation_hash(&self) -> Option<[u8; 32]> { - self.validation_hash - } - } - /// Construct a new dynamic storage lookup. - pub fn dynamic( - pallet_name: impl Into, - entry_name: impl Into, - storage_entry_keys: Keys, - ) -> DynamicAddress { - DynamicAddress::new(pallet_name, entry_name, storage_entry_keys) - } - /// Take some SCALE encoded bytes and a [`StorageHasher`] and hash the bytes accordingly. - fn hash_bytes(input: &[u8], hasher: &StorageHasher, bytes: &mut Vec) { - match hasher { - StorageHasher::Identity => bytes.extend(input), - StorageHasher::Blake2_128 => { - bytes.extend(sp_core_hashing::blake2_128(input)) - } - StorageHasher::Blake2_128Concat => { - bytes.extend(sp_core_hashing::blake2_128(input)); - bytes.extend(input); - } - StorageHasher::Blake2_256 => { - bytes.extend(sp_core_hashing::blake2_256(input)) - } - StorageHasher::Twox128 => bytes.extend(sp_core_hashing::twox_128(input)), - StorageHasher::Twox256 => bytes.extend(sp_core_hashing::twox_256(input)), - StorageHasher::Twox64Concat => { - bytes.extend(sp_core_hashing::twox_64(input)); - bytes.extend(input); - } - } - } - } - mod storage_client { - use super::{ - storage_type::{validate_storage_address, Storage}, - utils, StorageAddress, - }; - use crate::{ - backend::BlockRef, client::{OfflineClientT, OnlineClientT}, - error::Error, Config, - }; - use derivative::Derivative; - use std::{future::Future, marker::PhantomData}; - /// Query the runtime storage. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct StorageClient { - client: Client, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for StorageClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - StorageClient { client: ref __arg_0, _marker: ref __arg_1 } => { - StorageClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl StorageClient { - /// Create a new [`StorageClient`] - pub fn new(client: Client) -> Self { - Self { - client, - _marker: PhantomData, - } - } - } - impl StorageClient - where - T: Config, - Client: OfflineClientT, - { - /// Run the validation logic against some storage address you'd like to access. Returns `Ok(())` - /// if the address is valid (or if it's not possible to check since the address has no validation hash). - /// Return an error if the address was not valid or something went wrong trying to validate it (ie - /// the pallet or storage entry in question do not exist at all). - pub fn validate( - &self, - address: &Address, - ) -> Result<(), Error> { - let metadata = self.client.metadata(); - let pallet_metadata = metadata - .pallet_by_name_err(address.pallet_name())?; - validate_storage_address(address, pallet_metadata) - } - /// Convert some storage address into the raw bytes that would be submitted to the node in order - /// to retrieve the entries at the root of the associated address. - pub fn address_root_bytes( - &self, - address: &Address, - ) -> Vec { - utils::storage_address_root_bytes(address) - } - /// Convert some storage address into the raw bytes that would be submitted to the node in order - /// to retrieve an entry. This fails if [`StorageAddress::append_entry_bytes`] does; in the built-in - /// implementation this would be if the pallet and storage entry being asked for is not available on the - /// node you're communicating with, or if the metadata is missing some type information (which should not - /// happen). - pub fn address_bytes( - &self, - address: &Address, - ) -> Result, Error> { - utils::storage_address_bytes(address, &self.client.metadata()) - } - } - impl StorageClient - where - T: Config, - Client: OnlineClientT, - { - /// Obtain storage at some block hash. - pub fn at( - &self, - block_ref: impl Into>, - ) -> Storage { - Storage::new(self.client.clone(), block_ref.into()) - } - /// Obtain storage at the latest block hash. - pub fn at_latest( - &self, - ) -> impl Future< - Output = Result, Error>, - > + Send + 'static { - let client = self.client.clone(); - async move { - let block_ref = client.backend().latest_finalized_block_ref().await?; - Ok(Storage::new(client, block_ref)) - } - } - } - } - mod storage_key { - use super::{ - storage_address::StaticStorageKey, - utils::{ - hash_contains_unhashed_value, strip_storage_addess_root_bytes, - strip_storage_hash_bytes, - }, - }; - use crate::{ - dynamic::DecodedValueThunk, error::{Error, StorageAddressError}, - metadata::{DecodeWithMetadata, Metadata}, - utils::{Encoded, Static}, - }; - use scale_encode::EncodeAsType; - use subxt_metadata::StorageHasher; - /// This trait should be implemented by anything that can be used as one or multiple storage keys. - pub trait StorageKey { - /// Iterator over the storage keys, each key implements EncodeAsType to - /// give the corresponding bytes to a `StorageHasher`. - fn keys_iter(&self) -> impl Iterator; - /// How many keys are there in total? Each key is an element that needs to be individually hashed. - fn keys_len(&self) -> usize; - /// Attempts to decode the StorageKey from a storage address that has been stripped of its root bytes. - /// - /// Example: Imagine The `StorageKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. - /// Then the memory layout of the storage address is: - /// ```txt - /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | - /// ``` - /// `cursor` should point into a region after those first 16 bytes, at the start of a new hash. - /// `hashers_and_ty_ids` should consume all the hashers that have been used for decoding, such that there are less hashers coming to the next key. - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static; - } - /// Implement `StorageKey` for `()` which can be used for keyless storage entries. - impl StorageKey for () { - fn keys_iter(&self) -> impl Iterator { - std::iter::empty() - } - fn keys_len(&self) -> usize { - 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - _metadata: &Metadata, - ) -> Result { - if hashers_and_ty_ids.is_empty() { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into(), - ); - } - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; - Ok(()) - } - } - impl StorageKey - for StaticStorageKey { - fn keys_iter(&self) -> impl Iterator { - std::iter::once(&self.bytes as &dyn EncodeAsType) - } - fn keys_len(&self) -> usize { - 1 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into(), - ); - }; - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; - decode_storage_key_from_hash(cursor, hasher, *ty_id, metadata) - } - } - pub fn decode_storage_key_from_hash( - cursor: &mut &[u8], - hasher: &StorageHasher, - ty_id: u32, - metadata: &Metadata, - ) -> Result, Error> { - strip_storage_hash_bytes(cursor, hasher)?; - let bytes = *cursor; - if let Err(err) - = scale_decode::visitor::decode_with_visitor( - cursor, - ty_id, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) { - return Err(scale_decode::Error::from(err).into()); - } - let bytes_decoded = bytes.len() - cursor.len(); - if !hash_contains_unhashed_value(hasher) && bytes_decoded > 0 { - let ty_name = metadata - .types() - .resolve(ty_id) - .expect( - "ty_id is in metadata, because decode_with_visitor did not fail above; qed", - ) - .path - .to_string(); - return Err( - StorageAddressError::HasherCannotReconstructKey { - ty_id, - ty_name, - hasher: *hasher, - } - .into(), - ); - } - let key_bytes = bytes[..bytes_decoded].to_vec(); - let key = StaticStorageKey { - bytes: Static(Encoded(key_bytes)), - _marker: std::marker::PhantomData::, - }; - Ok(key) - } - impl StorageKey for Vec { - fn keys_iter(&self) -> impl Iterator { - self.iter().map(|e| e as &dyn EncodeAsType) - } - fn keys_len(&self) -> usize { - self.len() - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); - let mut result: Vec = ::alloc::vec::Vec::new(); - let mut n = 0; - while !cursor.is_empty() { - let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { - return Err(StorageAddressError::UnexpectedAddressBytes.into()); - }; - strip_storage_hash_bytes(cursor, hasher)?; - let decoded = DecodedValueThunk::decode_with_metadata( - cursor, - *ty_id, - metadata, - )?; - let value = decoded.to_value()?; - result.push(value.remove_context()); - n += 1; - } - *hashers_and_ty_ids = &hashers_and_ty_ids[n..]; - Ok(result) - } - } - #[rustfmt::skip] - const _: () = { - { - impl StorageKey for (A, B) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl StorageKey - for (A, B, C) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - > StorageKey for (A, B, C, D) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - E: StorageKey, - > StorageKey for (A, B, C, D, E) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + (self.4.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + (0 * 4 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[4]; - let key = E::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - E: StorageKey, - F: StorageKey, - > StorageKey for (A, B, C, D, E, F) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + (self.4.keys_len()) - + (self.5.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[4]; - let key = E::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[5]; - let key = F::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - E: StorageKey, - F: StorageKey, - G: StorageKey, - > StorageKey for (A, B, C, D, E, F, G) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + (self.4.keys_len()) - + (self.5.keys_len()) + (self.6.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + (0 * 6 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[4]; - let key = E::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[5]; - let key = F::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[6]; - let key = G::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - { - impl< - A: StorageKey, - B: StorageKey, - C: StorageKey, - D: StorageKey, - E: StorageKey, - F: StorageKey, - G: StorageKey, - H: StorageKey, - > StorageKey for (A, B, C, D, E, F, G, H) { - fn keys_iter(&self) -> impl Iterator { - () - } - fn keys_len(&self) -> usize { - (self.0.keys_len()) + (self.1.keys_len()) + (self.2.keys_len()) - + (self.3.keys_len()) + (self.4.keys_len()) - + (self.5.keys_len()) + (self.6.keys_len()) - + (self.7.keys_len()) + 0 - } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, - ) -> Result - where - Self: Sized + 'static, - { - const TUPLE_LEN: usize = (0 * 0 + 1) + (0 * 1 + 1) + (0 * 2 + 1) - + (0 * 3 + 1) + (0 * 4 + 1) + (0 * 5 + 1) + (0 * 6 + 1) - + (0 * 7 + 1) + 0; - let tuple: Self = ( - { - let (hasher, ty_id) = &hashers_and_ty_ids[0]; - let key = A::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[1]; - let key = B::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[2]; - let key = C::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[3]; - let key = D::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[4]; - let key = E::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[5]; - let key = F::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[6]; - let key = G::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - { - let (hasher, ty_id) = &hashers_and_ty_ids[7]; - let key = H::decode_from_bytes( - cursor, - hashers_and_ty_ids, - metadata, - )?; - key - }, - ); - return Ok(tuple); - } - } - }; - }; - } - mod storage_type { - use super::storage_address::{StorageAddress, Yes}; - use super::utils::strip_storage_addess_root_bytes; - use super::StorageKey; - use crate::{ - backend::{BackendExt, BlockRef}, - client::OnlineClientT, error::{Error, MetadataError, StorageAddressError}, - metadata::{DecodeWithMetadata, Metadata}, - Config, - }; - use codec::Decode; - use derivative::Derivative; - use futures::StreamExt; - use scale_info::TypeDef; - use std::{future::Future, marker::PhantomData}; - use subxt_metadata::StorageHasher; - use subxt_metadata::{PalletMetadata, StorageEntryMetadata, StorageEntryType}; - /// This is returned from a couple of storage functions. - pub use crate::backend::StreamOfResults; - /// Query the runtime storage. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct Storage { - client: Client, - block_ref: BlockRef, - _marker: PhantomData, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Storage - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - Storage { - client: ref __arg_0, - block_ref: ref __arg_1, - _marker: ref __arg_2, - } => { - Storage { - client: (*__arg_0).clone(), - block_ref: (*__arg_1).clone(), - _marker: (*__arg_2).clone(), - } - } - } - } - } - impl Storage { - /// Create a new [`Storage`] - pub(crate) fn new(client: Client, block_ref: BlockRef) -> Self { - Self { - client, - block_ref, - _marker: PhantomData, - } - } - } - impl Storage - where - T: Config, - Client: OnlineClientT, - { - /// Fetch the raw encoded value at the key given. - pub fn fetch_raw( - &self, - key: impl Into>, - ) -> impl Future>, Error>> + 'static { - let client = self.client.clone(); - let key = key.into(); - let block_ref = self.block_ref.clone(); - async move { - let data = client - .backend() - .storage_fetch_value(key, block_ref.hash()) - .await?; - Ok(data) - } - } - /// Stream all of the raw keys underneath the key given - pub fn fetch_raw_keys( - &self, - key: impl Into>, - ) -> impl Future< - Output = Result>, Error>, - > + 'static { - let client = self.client.clone(); - let block_hash = self.block_ref.hash(); - let key = key.into(); - async move { - let keys = client - .backend() - .storage_fetch_descendant_keys(key, block_hash) - .await?; - Ok(keys) - } - } - /// Fetch a decoded value from storage at a given address. - /// - /// # Example - /// - /// ```no_run - /// use subxt::{ PolkadotConfig, OnlineClient }; - /// - /// #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] - /// pub mod polkadot {} - /// - /// # #[tokio::main] - /// # async fn main() { - /// let api = OnlineClient::::new().await.unwrap(); - /// - /// // Address to a storage entry we'd like to access. - /// let address = polkadot::storage().xcm_pallet().queries(&12345); - /// - /// // Fetch just the keys, returning up to 10 keys. - /// let value = api - /// .storage() - /// .at_latest() - /// .await - /// .unwrap() - /// .fetch(&address) - /// .await - /// .unwrap(); - /// - /// println!("Value: {:?}", value); - /// # } - /// ``` - pub fn fetch<'address, Address>( - &self, - address: &'address Address, - ) -> impl Future, Error>> + 'address - where - Address: StorageAddress + 'address, - { - let client = self.clone(); - async move { - let metadata = client.client.metadata(); - let (pallet, entry) = lookup_entry_details( - address.pallet_name(), - address.entry_name(), - &metadata, - )?; - validate_storage_address(address, pallet)?; - let lookup_bytes = super::utils::storage_address_bytes( - address, - &metadata, - )?; - if let Some(data) = client.fetch_raw(lookup_bytes).await? { - let val = decode_storage_with_metadata::< - Address::Target, - >(&mut &*data, &metadata, entry)?; - Ok(Some(val)) - } else { - Ok(None) - } - } - } - /// Fetch a StorageKey that has a default value with an optional block hash. - pub fn fetch_or_default<'address, Address>( - &self, - address: &'address Address, - ) -> impl Future> + 'address - where - Address: StorageAddress - + 'address, - { - let client = self.clone(); - async move { - let pallet_name = address.pallet_name(); - let entry_name = address.entry_name(); - if let Some(data) = client.fetch(address).await? { - Ok(data) - } else { - let metadata = client.client.metadata(); - let (_pallet_metadata, storage_entry) = lookup_entry_details( - pallet_name, - entry_name, - &metadata, - )?; - let return_ty_id = return_type_from_storage_entry_type( - storage_entry.entry_type(), - ); - let bytes = &mut storage_entry.default_bytes(); - let val = Address::Target::decode_with_metadata( - bytes, - return_ty_id, - &metadata, - )?; - Ok(val) - } - } - } - /// Returns an iterator of key value pairs. - /// - /// ```no_run - /// use subxt::{ PolkadotConfig, OnlineClient }; - /// - /// #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] - /// pub mod polkadot {} - /// - /// # #[tokio::main] - /// # async fn main() { - /// let api = OnlineClient::::new().await.unwrap(); - /// - /// // Address to the root of a storage entry that we'd like to iterate over. - /// let address = polkadot::storage().xcm_pallet().version_notifiers_iter(); - /// - /// // Iterate over keys and values at that address. - /// let mut iter = api - /// .storage() - /// .at_latest() - /// .await - /// .unwrap() - /// .iter(address) - /// .await - /// .unwrap(); - /// - /// while let Some(Ok(kv)) = iter.next().await { - /// println!("Key bytes: 0x{}", hex::encode(&kv.key_bytes)); - /// println!("Value: {}", kv.value); - /// } - /// # } - /// ``` - pub fn iter
( - &self, - address: Address, - ) -> impl Future< - Output = Result>, Error>, - > + 'static - where - Address: StorageAddress + 'static, - Address::Keys: 'static + Sized, - { - let client = self.client.clone(); - let block_ref = self.block_ref.clone(); - async move { - let metadata = client.metadata(); - let (pallet, entry) = lookup_entry_details( - address.pallet_name(), - address.entry_name(), - &metadata, - )?; - validate_storage_address(&address, pallet)?; - let entry = entry.entry_type(); - let return_type_id = entry.value_ty(); - let hasher_type_id_pairs = storage_hasher_type_id_pairs( - entry, - &metadata, - )?; - let address_bytes = super::utils::storage_address_bytes( - &address, - &metadata, - )?; - let s = client - .backend() - .storage_fetch_descendant_values(address_bytes, block_ref.hash()) - .await? - .map(move |kv| { - let kv = match kv { - Ok(kv) => kv, - Err(e) => return Err(e), - }; - let value = Address::Target::decode_with_metadata( - &mut &*kv.value, - return_type_id, - &metadata, - )?; - let key_bytes = kv.key; - let cursor = &mut &key_bytes[..]; - strip_storage_addess_root_bytes(cursor)?; - let keys = ::decode_from_bytes( - cursor, - &hasher_type_id_pairs, - &metadata, - )?; - Ok(StorageKeyValuePair::
{ - keys, - key_bytes, - value, - }) - }); - let s = StreamOfResults::new(Box::pin(s)); - Ok(s) - } - } - /// The storage version of a pallet. - /// The storage version refers to the `frame_support::traits::Metadata::StorageVersion` type. - pub async fn storage_version( - &self, - pallet_name: impl AsRef, - ) -> Result { - self.client - .metadata() - .pallet_by_name(pallet_name.as_ref()) - .ok_or_else(|| MetadataError::PalletNameNotFound( - pallet_name.as_ref().into(), - ))?; - pub const STORAGE_VERSION_STORAGE_KEY_POSTFIX: &[u8] = b":__STORAGE_VERSION__:"; - let mut key_bytes: Vec = ::alloc::vec::Vec::new(); - key_bytes - .extend(&sp_core_hashing::twox_128(pallet_name.as_ref().as_bytes())); - key_bytes - .extend( - &sp_core_hashing::twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX), - ); - let storage_version_bytes = self - .fetch_raw(key_bytes) - .await? - .ok_or_else(|| { - { - let res = ::alloc::fmt::format( - format_args!( - "Unexpected: entry for storage version in pallet \"{0}\" not found", - pallet_name.as_ref() - ), - ); - res - } - })?; - u16::decode(&mut &storage_version_bytes[..]).map_err(Into::into) - } - /// Fetch the runtime WASM code. - pub async fn runtime_wasm_code(&self) -> Result, Error> { - const CODE: &str = ":code"; - self.fetch_raw(CODE.as_bytes()) - .await? - .ok_or_else(|| { - { - let res = ::alloc::fmt::format( - format_args!( - "Unexpected: entry for well known key \"{0}\" not found", - CODE - ), - ); - res - } - .into() - }) - } - } - pub(crate) fn storage_hasher_type_id_pairs( - entry: &StorageEntryType, - metadata: &Metadata, - ) -> Result, Error> { - match entry { - StorageEntryType::Plain(_) => Ok(::alloc::vec::Vec::new()), - StorageEntryType::Map { hashers, key_ty, .. } => { - let ty = metadata - .types() - .resolve(*key_ty) - .ok_or(MetadataError::TypeNotFound(*key_ty))?; - match &ty.type_def { - TypeDef::Tuple(tuple) => { - if hashers.len() < tuple.fields.len() { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: hashers.len(), - fields: tuple.fields.len(), - } - .into(), - ); - } - let pairs: Vec<(StorageHasher, u32)> = tuple - .fields - .iter() - .zip(hashers.iter()) - .map(|(e, h)| (*h, e.id)) - .collect(); - Ok(pairs) - } - _other => { - if hashers.is_empty() { - return Err( - StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into(), - ); - } - Ok( - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([(hashers[0], *key_ty)]), - ), - ) - } - } - } - } - } - /// A pair of keys and values together with all the bytes that make up the storage address. - /// `keys` is `None` if non-concat hashers are used. In this case the keys could not be extracted back from the key_bytes. - pub struct StorageKeyValuePair { - /// The bytes that make up the address of the storage entry. - pub key_bytes: Vec, - /// The keys that can be used to construct the address of this storage entry. - pub keys: T::Keys, - /// The value of the storage entry. - pub value: T::Target, - } - #[automatically_derived] - impl ::core::clone::Clone - for StorageKeyValuePair - where - T::Keys: ::core::clone::Clone, - T::Target: ::core::clone::Clone, - { - #[inline] - fn clone(&self) -> StorageKeyValuePair { - StorageKeyValuePair { - key_bytes: ::core::clone::Clone::clone(&self.key_bytes), - keys: ::core::clone::Clone::clone(&self.keys), - value: ::core::clone::Clone::clone(&self.value), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug - for StorageKeyValuePair - where - T::Keys: ::core::fmt::Debug, - T::Target: ::core::fmt::Debug, - { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field3_finish( - f, - "StorageKeyValuePair", - "key_bytes", - &self.key_bytes, - "keys", - &self.keys, - "value", - &&self.value, - ) - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for StorageKeyValuePair - where - T::Keys: ::core::cmp::Eq, - T::Target: ::core::cmp::Eq, - { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for StorageKeyValuePair {} - #[automatically_derived] - impl ::core::cmp::PartialEq - for StorageKeyValuePair - where - T::Keys: ::core::cmp::PartialEq, - T::Target: ::core::cmp::PartialEq, - { - #[inline] - fn eq(&self, other: &StorageKeyValuePair) -> bool { - self.key_bytes == other.key_bytes && self.keys == other.keys - && self.value == other.value - } - } - #[automatically_derived] - impl ::core::cmp::Ord - for StorageKeyValuePair - where - T::Keys: ::core::cmp::Ord, - T::Target: ::core::cmp::Ord, - { - #[inline] - fn cmp(&self, other: &StorageKeyValuePair) -> ::core::cmp::Ordering { - match ::core::cmp::Ord::cmp(&self.key_bytes, &other.key_bytes) { - ::core::cmp::Ordering::Equal => { - match ::core::cmp::Ord::cmp(&self.keys, &other.keys) { - ::core::cmp::Ordering::Equal => { - ::core::cmp::Ord::cmp(&self.value, &other.value) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd - for StorageKeyValuePair - where - T::Keys: ::core::cmp::PartialOrd, - T::Target: ::core::cmp::PartialOrd, - { - #[inline] - fn partial_cmp( - &self, - other: &StorageKeyValuePair, - ) -> ::core::option::Option<::core::cmp::Ordering> { - match ::core::cmp::PartialOrd::partial_cmp( - &self.key_bytes, - &other.key_bytes, - ) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - match ::core::cmp::PartialOrd::partial_cmp( - &self.keys, - &other.keys, - ) { - ::core::option::Option::Some( - ::core::cmp::Ordering::Equal, - ) => { - ::core::cmp::PartialOrd::partial_cmp( - &self.value, - &other.value, - ) - } - cmp => cmp, - } - } - cmp => cmp, - } - } - } - /// Validate a storage address against the metadata. - pub(crate) fn validate_storage_address( - address: &Address, - pallet: PalletMetadata<'_>, - ) -> Result<(), Error> { - if let Some(hash) = address.validation_hash() { - validate_storage(pallet, address.entry_name(), hash)?; - } - Ok(()) - } - /// Return details about the given storage entry. - fn lookup_entry_details<'a>( - pallet_name: &str, - entry_name: &str, - metadata: &'a Metadata, - ) -> Result<(PalletMetadata<'a>, &'a StorageEntryMetadata), Error> { - let pallet_metadata = metadata.pallet_by_name_err(pallet_name)?; - let storage_metadata = pallet_metadata - .storage() - .ok_or_else(|| MetadataError::StorageNotFoundInPallet( - pallet_name.to_owned(), - ))?; - let storage_entry = storage_metadata - .entry_by_name(entry_name) - .ok_or_else(|| MetadataError::StorageEntryNotFound( - entry_name.to_owned(), - ))?; - Ok((pallet_metadata, storage_entry)) - } - /// Validate a storage entry against the metadata. - fn validate_storage( - pallet: PalletMetadata<'_>, - storage_name: &str, - hash: [u8; 32], - ) -> Result<(), Error> { - let Some(expected_hash) = pallet.storage_hash(storage_name) else { - return Err(MetadataError::IncompatibleCodegen.into()); - }; - if expected_hash != hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - Ok(()) - } - /// Fetch the return type out of a [`StorageEntryType`]. - fn return_type_from_storage_entry_type(entry: &StorageEntryType) -> u32 { - match entry { - StorageEntryType::Plain(ty) => *ty, - StorageEntryType::Map { value_ty, .. } => *value_ty, - } - } - /// Given some bytes, a pallet and storage name, decode the response. - fn decode_storage_with_metadata( - bytes: &mut &[u8], - metadata: &Metadata, - storage_metadata: &StorageEntryMetadata, - ) -> Result { - let ty = storage_metadata.entry_type(); - let return_ty = return_type_from_storage_entry_type(ty); - let val = T::decode_with_metadata(bytes, return_ty, metadata)?; - Ok(val) - } - } - pub mod utils { - //! these utility methods complement the [`StorageAddress`] trait, but - //! aren't things that should ever be overridden, and so don't exist on - //! the trait itself. - use subxt_metadata::StorageHasher; - use super::StorageAddress; - use crate::{ - error::{Error, StorageAddressError}, - metadata::Metadata, - }; - /// Return the root of a given [`StorageAddress`]: hash the pallet name and entry name - /// and append those bytes to the output. - pub(crate) fn write_storage_address_root_bytes( - addr: &Address, - out: &mut Vec, - ) { - out.extend(sp_core_hashing::twox_128(addr.pallet_name().as_bytes())); - out.extend(sp_core_hashing::twox_128(addr.entry_name().as_bytes())); - } - /// Outputs the [`storage_address_root_bytes`] as well as any additional bytes that represent - /// a lookup in a storage map at that location. - pub(crate) fn storage_address_bytes( - addr: &Address, - metadata: &Metadata, - ) -> Result, Error> { - let mut bytes = Vec::new(); - write_storage_address_root_bytes(addr, &mut bytes); - addr.append_entry_bytes(metadata, &mut bytes)?; - Ok(bytes) - } - /// Outputs a vector containing the bytes written by [`write_storage_address_root_bytes`]. - pub(crate) fn storage_address_root_bytes( - addr: &Address, - ) -> Vec { - let mut bytes = Vec::new(); - write_storage_address_root_bytes(addr, &mut bytes); - bytes - } - /// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. - pub(crate) fn strip_storage_addess_root_bytes( - address_bytes: &mut &[u8], - ) -> Result<(), StorageAddressError> { - if address_bytes.len() >= 16 { - *address_bytes = &address_bytes[16..]; - Ok(()) - } else { - Err(StorageAddressError::UnexpectedAddressBytes) - } - } - /// Strips the first few bytes off a hash to possibly skip to the plan key value, - /// if [`hash_contains_unhashed_value()`] for this StorageHasher. - /// - /// Returns `Err(..)` if there are not enough bytes. - /// Returns `Ok(())` otherwise - pub fn strip_storage_hash_bytes( - hash: &mut &[u8], - hasher: &StorageHasher, - ) -> Result<(), StorageAddressError> { - let bytes_to_strip = match hasher { - StorageHasher::Blake2_128Concat => 16, - StorageHasher::Twox64Concat => 8, - StorageHasher::Blake2_128 => 16, - StorageHasher::Blake2_256 => 32, - StorageHasher::Twox128 => 16, - StorageHasher::Twox256 => 32, - StorageHasher::Identity => 0, - }; - if hash.len() < bytes_to_strip { - return Err(StorageAddressError::UnexpectedAddressBytes); - } - *hash = &hash[bytes_to_strip..]; - Ok(()) - } - /// This value is contained within the hash for concat-stle hashers - /// ([`StorageHasher::Identity`] or [`StorageHasher::Identity`]) and the - /// identity hash function ([`StorageHasher::Identity`]). - pub fn hash_contains_unhashed_value(hasher: &StorageHasher) -> bool { - match hasher { - StorageHasher::Blake2_128Concat - | StorageHasher::Twox64Concat - | StorageHasher::Identity => true, - _ => false, - } - } - } - pub use storage_client::StorageClient; - pub use storage_type::{Storage, StorageKeyValuePair}; - /// Types representing an address which describes where a storage - /// entry lives and how to properly decode it. - pub mod address { - pub use super::storage_address::{ - dynamic, Address, DynamicAddress, StaticStorageKey, StorageAddress, Yes, - }; - } - pub use storage_key::StorageKey; - pub use storage_address::{dynamic, Address, DynamicAddress, StorageAddress}; -} -pub mod tx { - //! Create and submit extrinsics. - //! - //! An extrinsic is submitted with an "signed extra" and "additional" parameters, which can be - //! different for each chain. The trait [`crate::config::ExtrinsicParams`] determines exactly which - //! additional and signed extra parameters are used when constructing an extrinsic, and is a part - //! of the chain configuration (see [`crate::config::Config`]). - use crate::macros::cfg_substrate_compat; - mod signer { - //! A library to **sub**mit e**xt**rinsics to a - //! [substrate](https://github.com/paritytech/substrate) node via RPC. - use crate::macros::cfg_substrate_compat; - use crate::Config; - /// Signing transactions requires a [`Signer`]. This is responsible for - /// providing the "from" account that the transaction is being signed by, - /// as well as actually signing a SCALE encoded payload. - pub trait Signer { - /// Return the "from" account ID. - fn account_id(&self) -> T::AccountId; - /// Return the "from" address. - fn address(&self) -> T::Address; - /// Takes a signer payload for an extrinsic, and returns a signature based on it. - /// - /// Some signers may fail, for instance because the hardware on which the keys are located has - /// refused the operation. - fn sign(&self, signer_payload: &[u8]) -> T::Signature; - } - } - mod tx_client { - use std::borrow::Cow; - use crate::{ - backend::{BackendExt, BlockRef, TransactionStatus}, - client::{OfflineClientT, OnlineClientT}, - config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, Hasher}, - error::{Error, MetadataError}, - tx::{Signer as SignerT, TxPayload, TxProgress}, - utils::{Encoded, PhantomDataSendSync}, - }; - use codec::{Compact, Decode, Encode}; - use derivative::Derivative; - use sp_core_hashing::blake2_256; - /// A client for working with transactions. - #[derivative(Clone(bound = "Client: Clone"))] - pub struct TxClient { - client: Client, - _marker: PhantomDataSendSync, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for TxClient - where - Client: Clone, - { - fn clone(&self) -> Self { - match *self { - TxClient { client: ref __arg_0, _marker: ref __arg_1 } => { - TxClient { - client: (*__arg_0).clone(), - _marker: (*__arg_1).clone(), - } - } - } - } - } - impl TxClient { - /// Create a new [`TxClient`] - pub fn new(client: Client) -> Self { - Self { - client, - _marker: PhantomDataSendSync::new(), - } - } - } - impl> TxClient { - /// Run the validation logic against some extrinsic you'd like to submit. Returns `Ok(())` - /// if the call is valid (or if it's not possible to check since the call has no validation hash). - /// Return an error if the call was not valid or something went wrong trying to validate it (ie - /// the pallet or call in question do not exist at all). - pub fn validate(&self, call: &Call) -> Result<(), Error> - where - Call: TxPayload, - { - if let Some(details) = call.validation_details() { - let expected_hash = self - .client - .metadata() - .pallet_by_name_err(details.pallet_name)? - .call_hash(details.call_name) - .ok_or_else(|| MetadataError::CallNameNotFound( - details.call_name.to_owned(), - ))?; - if details.hash != expected_hash { - return Err(MetadataError::IncompatibleCodegen.into()); - } - } - Ok(()) - } - /// Return the SCALE encoded bytes representing the call data of the transaction. - pub fn call_data(&self, call: &Call) -> Result, Error> - where - Call: TxPayload, - { - let metadata = self.client.metadata(); - let mut bytes = Vec::new(); - call.encode_call_data_to(&metadata, &mut bytes)?; - Ok(bytes) - } - /// Creates an unsigned extrinsic without submitting it. - pub fn create_unsigned( - &self, - call: &Call, - ) -> Result, Error> - where - Call: TxPayload, - { - self.validate(call)?; - let extrinsic = { - let mut encoded_inner = Vec::new(); - 4u8.encode_to(&mut encoded_inner); - call.encode_call_data_to( - &self.client.metadata(), - &mut encoded_inner, - )?; - let len = Compact( - u32::try_from(encoded_inner.len()) - .expect("extrinsic size expected to be <4GB"), - ); - let mut encoded = Vec::new(); - len.encode_to(&mut encoded); - encoded.extend(encoded_inner); - encoded - }; - Ok(SubmittableExtrinsic::from_bytes(self.client.clone(), extrinsic)) - } - /// Create a partial extrinsic. - pub fn create_partial_signed_with_nonce( - &self, - call: &Call, - account_nonce: u64, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - { - self.validate(call)?; - let call_data = self.call_data(call)?; - let additional_and_extra_params = >::new(account_nonce, self.client.clone(), other_params)?; - Ok(PartialExtrinsic { - client: self.client.clone(), - call_data, - additional_and_extra_params, - }) - } - /// Creates a signed extrinsic without submitting it. - pub fn create_signed_with_nonce( - &self, - call: &Call, - signer: &Signer, - account_nonce: u64, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - Signer: SignerT, - { - self.validate(call)?; - let partial_signed = self - .create_partial_signed_with_nonce( - call, - account_nonce, - other_params, - )?; - Ok(partial_signed.sign(signer)) - } - } - impl TxClient - where - T: Config, - C: OnlineClientT, - { - /// Get the account nonce for a given account ID. - pub async fn account_nonce( - &self, - account_id: &T::AccountId, - ) -> Result { - let block_ref = self - .client - .backend() - .latest_finalized_block_ref() - .await?; - crate::blocks::get_account_nonce( - &self.client, - account_id, - block_ref.hash(), - ) - .await - } - /// Creates a partial signed extrinsic, without submitting it. - pub async fn create_partial_signed( - &self, - call: &Call, - account_id: &T::AccountId, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - { - let account_nonce = self.account_nonce(account_id).await?; - self.create_partial_signed_with_nonce(call, account_nonce, other_params) - } - /// Creates a signed extrinsic, without submitting it. - pub async fn create_signed( - &self, - call: &Call, - signer: &Signer, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - Signer: SignerT, - { - let account_nonce = self.account_nonce(&signer.account_id()).await?; - self.create_signed_with_nonce(call, signer, account_nonce, other_params) - } - /// Creates and signs an extrinsic and submits it to the chain. Passes default parameters - /// to construct the "signed extra" and "additional" payloads needed by the extrinsic. - /// - /// Returns a [`TxProgress`], which can be used to track the status of the transaction - /// and obtain details about it, once it has made it into a block. - pub async fn sign_and_submit_then_watch_default( - &self, - call: &Call, - signer: &Signer, - ) -> Result, Error> - where - Call: TxPayload, - Signer: SignerT, - >::OtherParams: Default, - { - self.sign_and_submit_then_watch(call, signer, Default::default()).await - } - /// Creates and signs an extrinsic and submits it to the chain. - /// - /// Returns a [`TxProgress`], which can be used to track the status of the transaction - /// and obtain details about it, once it has made it into a block. - pub async fn sign_and_submit_then_watch( - &self, - call: &Call, - signer: &Signer, - other_params: >::OtherParams, - ) -> Result, Error> - where - Call: TxPayload, - Signer: SignerT, - { - self.create_signed(call, signer, other_params) - .await? - .submit_and_watch() - .await - } - /// Creates and signs an extrinsic and submits to the chain for block inclusion. Passes - /// default parameters to construct the "signed extra" and "additional" payloads needed - /// by the extrinsic. - /// - /// Returns `Ok` with the extrinsic hash if it is valid extrinsic. - /// - /// # Note - /// - /// Success does not mean the extrinsic has been included in the block, just that it is valid - /// and has been included in the transaction pool. - pub async fn sign_and_submit_default( - &self, - call: &Call, - signer: &Signer, - ) -> Result - where - Call: TxPayload, - Signer: SignerT, - >::OtherParams: Default, - { - self.sign_and_submit(call, signer, Default::default()).await - } - /// Creates and signs an extrinsic and submits to the chain for block inclusion. - /// - /// Returns `Ok` with the extrinsic hash if it is valid extrinsic. - /// - /// # Note - /// - /// Success does not mean the extrinsic has been included in the block, just that it is valid - /// and has been included in the transaction pool. - pub async fn sign_and_submit( - &self, - call: &Call, - signer: &Signer, - other_params: >::OtherParams, - ) -> Result - where - Call: TxPayload, - Signer: SignerT, - { - self.create_signed(call, signer, other_params).await?.submit().await - } - } - /// This payload contains the information needed to produce an extrinsic. - pub struct PartialExtrinsic { - client: C, - call_data: Vec, - additional_and_extra_params: T::ExtrinsicParams, - } - impl PartialExtrinsic - where - T: Config, - C: OfflineClientT, - { - fn with_signer_payload(&self, f: F) -> R - where - F: for<'a> FnOnce(Cow<'a, [u8]>) -> R, - { - let mut bytes = self.call_data.clone(); - self.additional_and_extra_params.encode_extra_to(&mut bytes); - self.additional_and_extra_params.encode_additional_to(&mut bytes); - if bytes.len() > 256 { - f(Cow::Borrowed(blake2_256(&bytes).as_ref())) - } else { - f(Cow::Owned(bytes)) - } - } - /// Return the signer payload for this extrinsic. These are the bytes that must - /// be signed in order to produce a valid signature for the extrinsic. - pub fn signer_payload(&self) -> Vec { - self.with_signer_payload(|bytes| bytes.to_vec()) - } - /// Return the bytes representing the call data for this partially constructed - /// extrinsic. - pub fn call_data(&self) -> &[u8] { - &self.call_data - } - /// Convert this [`PartialExtrinsic`] into a [`SubmittableExtrinsic`], ready to submit. - /// The provided `signer` is responsible for providing the "from" address for the transaction, - /// as well as providing a signature to attach to it. - pub fn sign(&self, signer: &Signer) -> SubmittableExtrinsic - where - Signer: SignerT, - { - let signature = self.with_signer_payload(|bytes| signer.sign(&bytes)); - self.sign_with_address_and_signature(&signer.address(), &signature) - } - /// Convert this [`PartialExtrinsic`] into a [`SubmittableExtrinsic`], ready to submit. - /// An address, and something representing a signature that can be SCALE encoded, are both - /// needed in order to construct it. If you have a `Signer` to hand, you can use - /// [`PartialExtrinsic::sign()`] instead. - pub fn sign_with_address_and_signature( - &self, - address: &T::Address, - signature: &T::Signature, - ) -> SubmittableExtrinsic { - let extrinsic = { - let mut encoded_inner = Vec::new(); - (0b10000000 + 4u8).encode_to(&mut encoded_inner); - address.encode_to(&mut encoded_inner); - signature.encode_to(&mut encoded_inner); - self.additional_and_extra_params.encode_extra_to(&mut encoded_inner); - encoded_inner.extend(&self.call_data); - let len = Compact( - u32::try_from(encoded_inner.len()) - .expect("extrinsic size expected to be <4GB"), - ); - let mut encoded = Vec::new(); - len.encode_to(&mut encoded); - encoded.extend(encoded_inner); - encoded - }; - SubmittableExtrinsic::from_bytes(self.client.clone(), extrinsic) - } - } - /// This represents an extrinsic that has been signed and is ready to submit. - pub struct SubmittableExtrinsic { - client: C, - encoded: Encoded, - marker: std::marker::PhantomData, - } - impl SubmittableExtrinsic - where - T: Config, - C: OfflineClientT, - { - /// Create a [`SubmittableExtrinsic`] from some already-signed and prepared - /// extrinsic bytes, and some client (anything implementing [`OfflineClientT`] - /// or [`OnlineClientT`]). - /// - /// Prefer to use [`TxClient`] to create and sign extrinsics. This is simply - /// exposed in case you want to skip this process and submit something you've - /// already created. - pub fn from_bytes(client: C, tx_bytes: Vec) -> Self { - Self { - client, - encoded: Encoded(tx_bytes), - marker: std::marker::PhantomData, - } - } - /// Calculate and return the hash of the extrinsic, based on the configured hasher. - pub fn hash(&self) -> T::Hash { - T::Hasher::hash_of(&self.encoded) - } - /// Returns the SCALE encoded extrinsic bytes. - pub fn encoded(&self) -> &[u8] { - &self.encoded.0 - } - /// Consumes [`SubmittableExtrinsic`] and returns the SCALE encoded - /// extrinsic bytes. - pub fn into_encoded(self) -> Vec { - self.encoded.0 - } - } - impl SubmittableExtrinsic - where - T: Config, - C: OnlineClientT, - { - /// Submits the extrinsic to the chain. - /// - /// Returns a [`TxProgress`], which can be used to track the status of the transaction - /// and obtain details about it, once it has made it into a block. - pub async fn submit_and_watch(&self) -> Result, Error> { - let ext_hash = self.hash(); - let sub = self - .client - .backend() - .submit_transaction(&self.encoded.0) - .await?; - Ok(TxProgress::new(sub, self.client.clone(), ext_hash)) - } - /// Submits the extrinsic to the chain for block inclusion. - /// - /// It's usually better to call `submit_and_watch` to get an idea of the progress of the - /// submission and whether it's eventually successful or not. This call does not guarantee - /// success, and is just sending the transaction to the chain. - pub async fn submit(&self) -> Result { - let ext_hash = self.hash(); - let mut sub = self - .client - .backend() - .submit_transaction(&self.encoded.0) - .await?; - match sub.next().await { - Some(Ok(status)) => { - match status { - TransactionStatus::Validated - | TransactionStatus::Broadcasted { .. } - | TransactionStatus::InBestBlock { .. } - | TransactionStatus::NoLongerInBestBlock - | TransactionStatus::InFinalizedBlock { .. } => Ok(ext_hash), - TransactionStatus::Error { message } => { - Err( - Error::Other({ - let res = ::alloc::fmt::format( - format_args!("Transaction error: {0}", message), - ); - res - }), - ) - } - TransactionStatus::Invalid { message } => { - Err( - Error::Other({ - let res = ::alloc::fmt::format( - format_args!("Transaction invalid: {0}", message), - ); - res - }), - ) - } - TransactionStatus::Dropped { message } => { - Err( - Error::Other({ - let res = ::alloc::fmt::format( - format_args!("Transaction dropped: {0}", message), - ); - res - }), - ) - } - } - } - Some(Err(e)) => Err(e), - None => { - Err( - Error::Other( - "Transaction broadcast was unsuccessful; stream terminated early" - .into(), - ), - ) - } - } - } - /// Validate a transaction by submitting it to the relevant Runtime API. A transaction that is - /// valid can be added to a block, but may still end up in an error state. - /// - /// Returns `Ok` with a [`ValidationResult`], which is the result of attempting to dry run the extrinsic. - pub async fn validate(&self) -> Result { - let latest_block_ref = self - .client - .backend() - .latest_finalized_block_ref() - .await?; - self.validate_at(latest_block_ref).await - } - /// Validate a transaction by submitting it to the relevant Runtime API. A transaction that is - /// valid can be added to a block, but may still end up in an error state. - /// - /// Returns `Ok` with a [`ValidationResult`], which is the result of attempting to dry run the extrinsic. - pub async fn validate_at( - &self, - at: impl Into>, - ) -> Result { - let block_hash = at.into().hash(); - let mut params = Vec::with_capacity(8 + self.encoded.0.len() + 8); - 2u8.encode_to(&mut params); - params.extend(self.encoded().iter()); - block_hash.encode_to(&mut params); - let res: Vec = self - .client - .backend() - .call( - "TaggedTransactionQueue_validate_transaction", - Some(¶ms), - block_hash, - ) - .await?; - ValidationResult::try_from_bytes(res) - } - /// This returns an estimate for what the extrinsic is expected to cost to execute, less any tips. - /// The actual amount paid can vary from block to block based on node traffic and other factors. - pub async fn partial_fee_estimate(&self) -> Result { - let mut params = self.encoded().to_vec(); - (self.encoded().len() as u32).encode_to(&mut params); - let latest_block_ref = self - .client - .backend() - .latest_finalized_block_ref() - .await?; - let (_, _, _, partial_fee) = self - .client - .backend() - .call_decoding::< - (Compact, Compact, u8, u128), - >( - "TransactionPaymentApi_query_info", - Some(¶ms), - latest_block_ref.hash(), - ) - .await?; - Ok(partial_fee) - } - } - impl ValidationResult { - #[allow(clippy::get_first)] - fn try_from_bytes(bytes: Vec) -> Result { - if bytes.get(0) == Some(&0) { - let res = TransactionValid::decode(&mut &bytes[1..])?; - Ok(ValidationResult::Valid(res)) - } else if bytes.get(0) == Some(&1) && bytes.get(1) == Some(&0) { - let res = TransactionInvalid::decode(&mut &bytes[2..])?; - Ok(ValidationResult::Invalid(res)) - } else if bytes.get(0) == Some(&1) && bytes.get(1) == Some(&1) { - let res = TransactionUnknown::decode(&mut &bytes[2..])?; - Ok(ValidationResult::Unknown(res)) - } else { - Err(crate::Error::Unknown(bytes)) - } - } - } - /// The result of performing [`SubmittableExtrinsic::validate()`]. - pub enum ValidationResult { - /// The transaction is valid - Valid(TransactionValid), - /// The transaction is invalid - Invalid(TransactionInvalid), - /// Unable to validate the transaction - Unknown(TransactionUnknown), - } - #[automatically_derived] - impl ::core::clone::Clone for ValidationResult { - #[inline] - fn clone(&self) -> ValidationResult { - match self { - ValidationResult::Valid(__self_0) => { - ValidationResult::Valid(::core::clone::Clone::clone(__self_0)) - } - ValidationResult::Invalid(__self_0) => { - ValidationResult::Invalid(::core::clone::Clone::clone(__self_0)) - } - ValidationResult::Unknown(__self_0) => { - ValidationResult::Unknown(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for ValidationResult { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - ValidationResult::Valid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Valid", - &__self_0, - ) - } - ValidationResult::Invalid(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Invalid", - &__self_0, - ) - } - ValidationResult::Unknown(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Unknown", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for ValidationResult {} - #[automatically_derived] - impl ::core::cmp::PartialEq for ValidationResult { - #[inline] - fn eq(&self, other: &ValidationResult) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - ValidationResult::Valid(__self_0), - ValidationResult::Valid(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - ValidationResult::Invalid(__self_0), - ValidationResult::Invalid(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - ValidationResult::Unknown(__self_0), - ValidationResult::Unknown(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - impl ValidationResult { - /// Is the transaction valid. - pub fn is_valid(&self) -> bool { - match self { - ValidationResult::Valid(_) => true, - _ => false, - } - } - } - /// Transaction is valid; here is some more information about it. - pub struct TransactionValid { - /// Priority of the transaction. - /// - /// Priority determines the ordering of two transactions that have all - /// their dependencies (required tags) satisfied. - pub priority: u64, - /// Transaction dependencies - /// - /// A non-empty list signifies that some other transactions which provide - /// given tags are required to be included before that one. - pub requires: Vec>, - /// Provided tags - /// - /// A list of tags this transaction provides. Successfully importing the transaction - /// will enable other transactions that depend on (require) those tags to be included as well. - /// Provided and required tags allow Substrate to build a dependency graph of transactions - /// and import them in the right (linear) order. - pub provides: Vec>, - /// Transaction longevity - /// - /// Longevity describes minimum number of blocks the validity is correct. - /// After this period transaction should be removed from the pool or revalidated. - pub longevity: u64, - /// A flag indicating if the transaction should be propagated to other peers. - /// - /// By setting `false` here the transaction will still be considered for - /// including in blocks that are authored on the current node, but will - /// never be sent to other peers. - pub propagate: bool, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for TransactionValid { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(TransactionValid { - priority: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::priority`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - requires: { - let __codec_res_edqy = , - > as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::requires`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - provides: { - let __codec_res_edqy = , - > as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::provides`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - longevity: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::longevity`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - propagate: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionValid::propagate`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for TransactionValid { - #[inline] - fn clone(&self) -> TransactionValid { - TransactionValid { - priority: ::core::clone::Clone::clone(&self.priority), - requires: ::core::clone::Clone::clone(&self.requires), - provides: ::core::clone::Clone::clone(&self.provides), - longevity: ::core::clone::Clone::clone(&self.longevity), - propagate: ::core::clone::Clone::clone(&self.propagate), - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionValid { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field5_finish( - f, - "TransactionValid", - "priority", - &self.priority, - "requires", - &self.requires, - "provides", - &self.provides, - "longevity", - &self.longevity, - "propagate", - &&self.propagate, - ) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionValid {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionValid { - #[inline] - fn eq(&self, other: &TransactionValid) -> bool { - self.priority == other.priority && self.requires == other.requires - && self.provides == other.provides - && self.longevity == other.longevity - && self.propagate == other.propagate - } - } - /// The runtime was unable to validate the transaction. - pub enum TransactionUnknown { - /// Could not lookup some information that is required to validate the transaction. - CannotLookup, - /// No validator found for the given unsigned transaction. - NoUnsignedValidator, - /// Any other custom unknown validity that is not covered by this enum. - Custom(u8), - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for TransactionUnknown { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `TransactionUnknown`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionUnknown::CannotLookup) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionUnknown::NoUnsignedValidator, - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionUnknown::Custom({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionUnknown::Custom.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `TransactionUnknown`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for TransactionUnknown { - #[inline] - fn clone(&self) -> TransactionUnknown { - match self { - TransactionUnknown::CannotLookup => TransactionUnknown::CannotLookup, - TransactionUnknown::NoUnsignedValidator => { - TransactionUnknown::NoUnsignedValidator - } - TransactionUnknown::Custom(__self_0) => { - TransactionUnknown::Custom(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionUnknown { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionUnknown::CannotLookup => { - ::core::fmt::Formatter::write_str(f, "CannotLookup") - } - TransactionUnknown::NoUnsignedValidator => { - ::core::fmt::Formatter::write_str(f, "NoUnsignedValidator") - } - TransactionUnknown::Custom(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Custom", - &__self_0, - ) - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionUnknown {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionUnknown { - #[inline] - fn eq(&self, other: &TransactionUnknown) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionUnknown::Custom(__self_0), - TransactionUnknown::Custom(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - /// The transaction is invalid. - pub enum TransactionInvalid { - /// The call of the transaction is not expected. - Call, - /// General error to do with the inability to pay some fees (e.g. account balance too low). - Payment, - /// General error to do with the transaction not yet being valid (e.g. nonce too high). - Future, - /// General error to do with the transaction being outdated (e.g. nonce too low). - Stale, - /// General error to do with the transaction's proofs (e.g. signature). - /// - /// # Possible causes - /// - /// When using a signed extension that provides additional data for signing, it is required - /// that the signing and the verifying side use the same additional data. Additional - /// data will only be used to generate the signature, but will not be part of the transaction - /// itself. As the verifying side does not know which additional data was used while signing - /// it will only be able to assume a bad signature and cannot express a more meaningful error. - BadProof, - /// The transaction birth block is ancient. - /// - /// # Possible causes - /// - /// For `FRAME`-based runtimes this would be caused by `current block number - /// - Era::birth block number > BlockHashCount`. (e.g. in Polkadot `BlockHashCount` = 2400, so - /// a - /// transaction with birth block number 1337 would be valid up until block number 1337 + 2400, - /// after which point the transaction would be considered to have an ancient birth block.) - AncientBirthBlock, - /// The transaction would exhaust the resources of current block. - /// - /// The transaction might be valid, but there are not enough resources - /// left in the current block. - ExhaustsResources, - /// Any other custom invalid validity that is not covered by this enum. - Custom(u8), - /// An extrinsic with a Mandatory dispatch resulted in Error. This is indicative of either a - /// malicious validator or a buggy `provide_inherent`. In any case, it can result in - /// dangerously overweight blocks and therefore if found, invalidates the block. - BadMandatory, - /// An extrinsic with a mandatory dispatch tried to be validated. - /// This is invalid; only inherent extrinsics are allowed to have mandatory dispatches. - MandatoryValidation, - /// The sending address is disabled or known to be invalid. - BadSigner, - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for TransactionInvalid { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `TransactionInvalid`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::Call) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::Payment) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::Future) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 3usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::Stale) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 4usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::BadProof) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 5usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionInvalid::AncientBirthBlock, - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 6usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionInvalid::ExhaustsResources, - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 7usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionInvalid::Custom({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `TransactionInvalid::Custom.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 8usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::BadMandatory) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 9usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - TransactionInvalid::MandatoryValidation, - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 10usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(TransactionInvalid::BadSigner) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `TransactionInvalid`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - #[automatically_derived] - impl ::core::clone::Clone for TransactionInvalid { - #[inline] - fn clone(&self) -> TransactionInvalid { - match self { - TransactionInvalid::Call => TransactionInvalid::Call, - TransactionInvalid::Payment => TransactionInvalid::Payment, - TransactionInvalid::Future => TransactionInvalid::Future, - TransactionInvalid::Stale => TransactionInvalid::Stale, - TransactionInvalid::BadProof => TransactionInvalid::BadProof, - TransactionInvalid::AncientBirthBlock => { - TransactionInvalid::AncientBirthBlock - } - TransactionInvalid::ExhaustsResources => { - TransactionInvalid::ExhaustsResources - } - TransactionInvalid::Custom(__self_0) => { - TransactionInvalid::Custom(::core::clone::Clone::clone(__self_0)) - } - TransactionInvalid::BadMandatory => TransactionInvalid::BadMandatory, - TransactionInvalid::MandatoryValidation => { - TransactionInvalid::MandatoryValidation - } - TransactionInvalid::BadSigner => TransactionInvalid::BadSigner, - } - } - } - #[automatically_derived] - impl ::core::fmt::Debug for TransactionInvalid { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - TransactionInvalid::Call => { - ::core::fmt::Formatter::write_str(f, "Call") - } - TransactionInvalid::Payment => { - ::core::fmt::Formatter::write_str(f, "Payment") - } - TransactionInvalid::Future => { - ::core::fmt::Formatter::write_str(f, "Future") - } - TransactionInvalid::Stale => { - ::core::fmt::Formatter::write_str(f, "Stale") - } - TransactionInvalid::BadProof => { - ::core::fmt::Formatter::write_str(f, "BadProof") - } - TransactionInvalid::AncientBirthBlock => { - ::core::fmt::Formatter::write_str(f, "AncientBirthBlock") - } - TransactionInvalid::ExhaustsResources => { - ::core::fmt::Formatter::write_str(f, "ExhaustsResources") - } - TransactionInvalid::Custom(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Custom", - &__self_0, - ) - } - TransactionInvalid::BadMandatory => { - ::core::fmt::Formatter::write_str(f, "BadMandatory") - } - TransactionInvalid::MandatoryValidation => { - ::core::fmt::Formatter::write_str(f, "MandatoryValidation") - } - TransactionInvalid::BadSigner => { - ::core::fmt::Formatter::write_str(f, "BadSigner") - } - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for TransactionInvalid {} - #[automatically_derived] - impl ::core::cmp::PartialEq for TransactionInvalid { - #[inline] - fn eq(&self, other: &TransactionInvalid) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - TransactionInvalid::Custom(__self_0), - TransactionInvalid::Custom(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => true, - } - } - } - } - mod tx_payload { - //! This module contains the trait and types used to represent - //! transactions that can be submitted. - use crate::{ - dynamic::Value, error::{Error, MetadataError}, - metadata::Metadata, - }; - use codec::Encode; - use derivative::Derivative; - use scale_encode::EncodeAsFields; - use scale_value::{Composite, ValueDef, Variant}; - use std::{borrow::Cow, sync::Arc}; - /// This represents a transaction payload that can be submitted - /// to a node. - pub trait TxPayload { - /// Encode call data to the provided output. - fn encode_call_data_to( - &self, - metadata: &Metadata, - out: &mut Vec, - ) -> Result<(), Error>; - /// Encode call data and return the output. This is a convenience - /// wrapper around [`TxPayload::encode_call_data_to`]. - fn encode_call_data(&self, metadata: &Metadata) -> Result, Error> { - let mut v = Vec::new(); - self.encode_call_data_to(metadata, &mut v)?; - Ok(v) - } - /// Returns the details needed to validate the call, which - /// include a statically generated hash, the pallet name, - /// and the call name. - fn validation_details(&self) -> Option> { - None - } - } - pub struct ValidationDetails<'a> { - /// The pallet name. - pub pallet_name: &'a str, - /// The call name. - pub call_name: &'a str, - /// A hash (this is generated at compile time in our codegen) - /// to compare against the runtime code. - pub hash: [u8; 32], - } - /// A transaction payload containing some generic `CallData`. - #[derivative( - Clone(bound = "CallData: Clone"), - Debug(bound = "CallData: std::fmt::Debug"), - Eq(bound = "CallData: std::cmp::Eq"), - Ord(bound = "CallData: std::cmp::Ord"), - PartialEq(bound = "CallData: std::cmp::PartialEq"), - PartialOrd(bound = "CallData: std::cmp::PartialOrd") - )] - pub struct Payload { - pallet_name: Cow<'static, str>, - call_name: Cow<'static, str>, - call_data: CallData, - validation_hash: Option<[u8; 32]>, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for Payload - where - CallData: Clone, - { - fn clone(&self) -> Self { - match *self { - Payload { - pallet_name: ref __arg_0, - call_name: ref __arg_1, - call_data: ref __arg_2, - validation_hash: ref __arg_3, - } => { - Payload { - pallet_name: (*__arg_0).clone(), - call_name: (*__arg_1).clone(), - call_data: (*__arg_2).clone(), - validation_hash: (*__arg_3).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for Payload - where - CallData: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - Payload { - pallet_name: ref __arg_0, - call_name: ref __arg_1, - call_data: ref __arg_2, - validation_hash: ref __arg_3, - } => { - let mut __debug_trait_builder = __f.debug_struct("Payload"); - let _ = __debug_trait_builder.field("pallet_name", &&(*__arg_0)); - let _ = __debug_trait_builder.field("call_name", &&(*__arg_1)); - let _ = __debug_trait_builder.field("call_data", &&(*__arg_2)); - let _ = __debug_trait_builder - .field("validation_hash", &&(*__arg_3)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for Payload - where - CallData: std::cmp::Eq, - {} - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for Payload - where - CallData: std::cmp::PartialEq, - { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - Payload { - pallet_name: ref __self_0, - call_name: ref __self_1, - call_data: ref __self_2, - validation_hash: ref __self_3, - } => { - match *other { - Payload { - pallet_name: ref __other_0, - call_name: ref __other_1, - call_data: ref __other_2, - validation_hash: ref __other_3, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - && &(*__self_2) == &(*__other_2) - && &(*__self_3) == &(*__other_3) - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialOrd for Payload - where - CallData: std::cmp::PartialOrd, - { - fn partial_cmp( - &self, - other: &Self, - ) -> ::std::option::Option<::std::cmp::Ordering> { - match *self { - Payload { - pallet_name: ref __self_0, - call_name: ref __self_1, - call_data: ref __self_2, - validation_hash: ref __self_3, - } => { - match *other { - Payload { - pallet_name: ref __other_0, - call_name: ref __other_1, - call_data: ref __other_2, - validation_hash: ref __other_3, - } => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_0), - &(*__other_0), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_1), - &(*__other_1), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_2), - &(*__other_2), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - match ::std::cmp::PartialOrd::partial_cmp( - &(*__self_3), - &(*__other_3), - ) { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) => { - ::std::option::Option::Some(::std::cmp::Ordering::Equal) - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::Ord for Payload - where - CallData: std::cmp::Ord, - { - fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { - match *self { - Payload { - pallet_name: ref __self_0, - call_name: ref __self_1, - call_data: ref __self_2, - validation_hash: ref __self_3, - } => { - match *other { - Payload { - pallet_name: ref __other_0, - call_name: ref __other_1, - call_data: ref __other_2, - validation_hash: ref __other_3, - } => { - match ::std::cmp::Ord::cmp(&(*__self_0), &(*__other_0)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_1), &(*__other_1)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_2), &(*__other_2)) { - ::std::cmp::Ordering::Equal => { - match ::std::cmp::Ord::cmp(&(*__self_3), &(*__other_3)) { - ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal, - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - __derive_ordering_other => __derive_ordering_other, - } - } - } - } - } - } - } - /// A boxed transaction payload. - pub type BoxedPayload = Payload>; - /// The type of a payload typically used for dynamic transaction payloads. - pub type DynamicPayload = Payload>; - impl Payload { - /// Create a new [`Payload`]. - pub fn new( - pallet_name: impl Into, - call_name: impl Into, - call_data: CallData, - ) -> Self { - Payload { - pallet_name: Cow::Owned(pallet_name.into()), - call_name: Cow::Owned(call_name.into()), - call_data, - validation_hash: None, - } - } - /// Create a new [`Payload`] using static strings for the pallet and call name. - /// This is only expected to be used from codegen. - #[doc(hidden)] - pub fn new_static( - pallet_name: &'static str, - call_name: &'static str, - call_data: CallData, - validation_hash: [u8; 32], - ) -> Self { - Payload { - pallet_name: Cow::Borrowed(pallet_name), - call_name: Cow::Borrowed(call_name), - call_data, - validation_hash: Some(validation_hash), - } - } - /// Box the payload. - pub fn boxed(self) -> BoxedPayload - where - CallData: EncodeAsFields + Send + Sync + 'static, - { - BoxedPayload { - pallet_name: self.pallet_name, - call_name: self.call_name, - call_data: Arc::new(self.call_data), - validation_hash: self.validation_hash, - } - } - /// Do not validate this call prior to submitting it. - pub fn unvalidated(self) -> Self { - Self { - validation_hash: None, - ..self - } - } - /// Returns the call data. - pub fn call_data(&self) -> &CallData { - &self.call_data - } - /// Returns the pallet name. - pub fn pallet_name(&self) -> &str { - &self.pallet_name - } - /// Returns the call name. - pub fn call_name(&self) -> &str { - &self.call_name - } - } - impl Payload> { - /// Convert the dynamic `Composite` payload into a [`Value`]. - /// This is useful if you want to use this as an argument for a - /// larger dynamic call that wants to use this as a nested call. - pub fn into_value(self) -> Value<()> { - let call = Value { - context: (), - value: ValueDef::Variant(Variant { - name: self.call_name.into_owned(), - values: self.call_data, - }), - }; - Value::unnamed_variant(self.pallet_name, [call]) - } - } - impl TxPayload for Payload { - fn encode_call_data_to( - &self, - metadata: &Metadata, - out: &mut Vec, - ) -> Result<(), Error> { - let pallet = metadata.pallet_by_name_err(&self.pallet_name)?; - let call = pallet - .call_variant_by_name(&self.call_name) - .ok_or_else(|| MetadataError::CallNameNotFound( - (*self.call_name).to_owned(), - ))?; - let pallet_index = pallet.index(); - let call_index = call.index; - pallet_index.encode_to(out); - call_index.encode_to(out); - let mut fields = call - .fields - .iter() - .map(|f| scale_encode::Field::new(f.ty.id, f.name.as_deref())); - self.call_data.encode_as_fields_to(&mut fields, metadata.types(), out)?; - Ok(()) - } - fn validation_details(&self) -> Option> { - self.validation_hash - .map(|hash| ValidationDetails { - pallet_name: &self.pallet_name, - call_name: &self.call_name, - hash, - }) - } - } - /// Construct a transaction at runtime; essentially an alias to [`Payload::new()`] - /// which provides a [`Composite`] value for the call data. - pub fn dynamic( - pallet_name: impl Into, - call_name: impl Into, - call_data: impl Into>, - ) -> DynamicPayload { - Payload::new(pallet_name, call_name, call_data.into()) - } - } - mod tx_progress { - //! Types representing extrinsics/transactions that have been submitted to a node. - use std::task::Poll; - use crate::utils::strip_compact_prefix; - use crate::{ - backend::{BlockRef, StreamOfResults, TransactionStatus as BackendTxStatus}, - client::OnlineClientT, - error::{DispatchError, Error, RpcError, TransactionError}, - events::EventsClient, Config, - }; - use derivative::Derivative; - use futures::{Stream, StreamExt}; - /// This struct represents a subscription to the progress of some transaction. - pub struct TxProgress { - sub: Option>>, - ext_hash: T::Hash, - client: C, - } - impl std::fmt::Debug for TxProgress { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("TxProgress") - .field("sub", &"") - .field("ext_hash", &self.ext_hash) - .field("client", &"") - .finish() - } - } - impl Unpin for TxProgress {} - impl TxProgress { - /// Instantiate a new [`TxProgress`] from a custom subscription. - pub fn new( - sub: StreamOfResults>, - client: C, - ext_hash: T::Hash, - ) -> Self { - Self { - sub: Some(sub), - client, - ext_hash, - } - } - /// Return the hash of the extrinsic. - pub fn extrinsic_hash(&self) -> T::Hash { - self.ext_hash - } - } - impl TxProgress - where - T: Config, - C: OnlineClientT, - { - /// Return the next transaction status when it's emitted. This just delegates to the - /// [`futures::Stream`] implementation for [`TxProgress`], but allows you to - /// avoid importing that trait if you don't otherwise need it. - pub async fn next(&mut self) -> Option, Error>> { - StreamExt::next(self).await - } - /// Wait for the transaction to be finalized, and return a [`TxInBlock`] - /// instance when it is, or an error if there was a problem waiting for finalization. - /// - /// **Note:** consumes `self`. If you'd like to perform multiple actions as the state of the - /// transaction progresses, use [`TxProgress::next()`] instead. - /// - /// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some - /// probability that the transaction will not make it into a block but there is no guarantee - /// that this is true. In those cases the stream is closed however, so you currently have no way to find - /// out if they finally made it into a block or not. - pub async fn wait_for_finalized(mut self) -> Result, Error> { - while let Some(status) = self.next().await { - match status? { - TxStatus::InFinalizedBlock(s) => return Ok(s), - TxStatus::Error { message } => { - return Err(TransactionError::Error(message).into()); - } - TxStatus::Invalid { message } => { - return Err(TransactionError::Invalid(message).into()); - } - TxStatus::Dropped { message } => { - return Err(TransactionError::Dropped(message).into()); - } - _ => continue, - } - } - Err(RpcError::SubscriptionDropped.into()) - } - /// Wait for the transaction to be finalized, and for the transaction events to indicate - /// that the transaction was successful. Returns the events associated with the transaction, - /// as well as a couple of other details (block hash and extrinsic hash). - /// - /// **Note:** consumes self. If you'd like to perform multiple actions as progress is made, - /// use [`TxProgress::next()`] instead. - /// - /// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some - /// probability that the transaction will not make it into a block but there is no guarantee - /// that this is true. In those cases the stream is closed however, so you currently have no way to find - /// out if they finally made it into a block or not. - pub async fn wait_for_finalized_success( - self, - ) -> Result, Error> { - let evs = self.wait_for_finalized().await?.wait_for_success().await?; - Ok(evs) - } - } - impl Stream for TxProgress { - type Item = Result, Error>; - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - let sub = match self.sub.as_mut() { - Some(sub) => sub, - None => return Poll::Ready(None), - }; - sub.poll_next_unpin(cx) - .map_ok(|status| { - match status { - BackendTxStatus::Validated => TxStatus::Validated, - BackendTxStatus::Broadcasted { num_peers } => { - TxStatus::Broadcasted { num_peers } - } - BackendTxStatus::NoLongerInBestBlock => { - TxStatus::NoLongerInBestBlock - } - BackendTxStatus::InBestBlock { hash } => { - TxStatus::InBestBlock( - TxInBlock::new(hash, self.ext_hash, self.client.clone()), - ) - } - BackendTxStatus::InFinalizedBlock { hash } => { - self.sub = None; - TxStatus::InFinalizedBlock( - TxInBlock::new(hash, self.ext_hash, self.client.clone()), - ) - } - BackendTxStatus::Error { message } => { - self.sub = None; - TxStatus::Error { message } - } - BackendTxStatus::Invalid { message } => { - self.sub = None; - TxStatus::Invalid { message } - } - BackendTxStatus::Dropped { message } => { - self.sub = None; - TxStatus::Dropped { message } - } - } - }) - } - } - /// Possible transaction statuses returned from our [`TxProgress::next()`] call. - #[derivative(Debug(bound = "C: std::fmt::Debug"))] - pub enum TxStatus { - /// Transaction is part of the future queue. - Validated, - /// The transaction has been broadcast to other nodes. - Broadcasted { - /// Number of peers it's been broadcast to. - num_peers: u32, - }, - /// Transaction is no longer in a best block. - NoLongerInBestBlock, - /// Transaction has been included in block with given hash. - InBestBlock(TxInBlock), - /// Transaction has been finalized by a finality-gadget, e.g GRANDPA - InFinalizedBlock(TxInBlock), - /// Something went wrong in the node. - Error { - /// Human readable message; what went wrong. - message: String, - }, - /// Transaction is invalid (bad nonce, signature etc). - Invalid { - /// Human readable message; why was it invalid. - message: String, - }, - /// The transaction was dropped. - Dropped { - /// Human readable message; why was it dropped. - message: String, - }, - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for TxStatus - where - C: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - TxStatus::Validated => { - let mut __debug_trait_builder = __f.debug_tuple("Validated"); - __debug_trait_builder.finish() - } - TxStatus::Broadcasted { num_peers: ref __arg_0 } => { - let mut __debug_trait_builder = __f.debug_struct("Broadcasted"); - let _ = __debug_trait_builder.field("num_peers", &&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::NoLongerInBestBlock => { - let mut __debug_trait_builder = __f - .debug_tuple("NoLongerInBestBlock"); - __debug_trait_builder.finish() - } - TxStatus::InBestBlock(ref __arg_0) => { - let mut __debug_trait_builder = __f.debug_tuple("InBestBlock"); - let _ = __debug_trait_builder.field(&&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::InFinalizedBlock(ref __arg_0) => { - let mut __debug_trait_builder = __f - .debug_tuple("InFinalizedBlock"); - let _ = __debug_trait_builder.field(&&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::Error { message: ref __arg_0 } => { - let mut __debug_trait_builder = __f.debug_struct("Error"); - let _ = __debug_trait_builder.field("message", &&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::Invalid { message: ref __arg_0 } => { - let mut __debug_trait_builder = __f.debug_struct("Invalid"); - let _ = __debug_trait_builder.field("message", &&(*__arg_0)); - __debug_trait_builder.finish() - } - TxStatus::Dropped { message: ref __arg_0 } => { - let mut __debug_trait_builder = __f.debug_struct("Dropped"); - let _ = __debug_trait_builder.field("message", &&(*__arg_0)); - __debug_trait_builder.finish() - } - } - } - } - impl TxStatus { - /// A convenience method to return the finalized details. Returns - /// [`None`] if the enum variant is not [`TxStatus::InFinalizedBlock`]. - pub fn as_finalized(&self) -> Option<&TxInBlock> { - match self { - Self::InFinalizedBlock(val) => Some(val), - _ => None, - } - } - /// A convenience method to return the best block details. Returns - /// [`None`] if the enum variant is not [`TxStatus::InBestBlock`]. - pub fn as_in_block(&self) -> Option<&TxInBlock> { - match self { - Self::InBestBlock(val) => Some(val), - _ => None, - } - } - } - /// This struct represents a transaction that has made it into a block. - #[derivative(Debug(bound = "C: std::fmt::Debug"))] - pub struct TxInBlock { - block_ref: BlockRef, - ext_hash: T::Hash, - client: C, - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for TxInBlock - where - C: std::fmt::Debug, - { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - TxInBlock { - block_ref: ref __arg_0, - ext_hash: ref __arg_1, - client: ref __arg_2, - } => { - let mut __debug_trait_builder = __f.debug_struct("TxInBlock"); - let _ = __debug_trait_builder.field("block_ref", &&(*__arg_0)); - let _ = __debug_trait_builder.field("ext_hash", &&(*__arg_1)); - let _ = __debug_trait_builder.field("client", &&(*__arg_2)); - __debug_trait_builder.finish() - } - } - } - } - impl TxInBlock { - pub(crate) fn new( - block_ref: BlockRef, - ext_hash: T::Hash, - client: C, - ) -> Self { - Self { - block_ref, - ext_hash, - client, - } - } - /// Return the hash of the block that the transaction has made it into. - pub fn block_hash(&self) -> T::Hash { - self.block_ref.hash() - } - /// Return the hash of the extrinsic that was submitted. - pub fn extrinsic_hash(&self) -> T::Hash { - self.ext_hash - } - } - impl> TxInBlock { - /// Fetch the events associated with this transaction. If the transaction - /// was successful (ie no `ExtrinsicFailed`) events were found, then we return - /// the events associated with it. If the transaction was not successful, or - /// something else went wrong, we return an error. - /// - /// **Note:** If multiple `ExtrinsicFailed` errors are returned (for instance - /// because a pallet chooses to emit one as an event, which is considered - /// abnormal behaviour), it is not specified which of the errors is returned here. - /// You can use [`TxInBlock::fetch_events`] instead if you'd like to - /// work with multiple "error" events. - /// - /// **Note:** This has to download block details from the node and decode events - /// from them. - pub async fn wait_for_success( - &self, - ) -> Result, Error> { - let events = self.fetch_events().await?; - for ev in events.iter() { - let ev = ev?; - if ev.pallet_name() == "System" - && ev.variant_name() == "ExtrinsicFailed" - { - let dispatch_error = DispatchError::decode_from( - ev.field_bytes(), - self.client.metadata(), - )?; - return Err(dispatch_error.into()); - } - } - Ok(events) - } - /// Fetch all of the events associated with this transaction. This succeeds whether - /// the transaction was a success or not; it's up to you to handle the error and - /// success events however you prefer. - /// - /// **Note:** This has to download block details from the node and decode events - /// from them. - pub async fn fetch_events( - &self, - ) -> Result, Error> { - let block_body = self - .client - .backend() - .block_body(self.block_ref.hash()) - .await? - .ok_or(Error::Transaction(TransactionError::BlockNotFound))?; - let extrinsic_idx = block_body - .iter() - .position(|ext| { - use crate::config::Hasher; - let Ok((_, stripped)) = strip_compact_prefix(ext) else { - return false; - }; - let hash = T::Hasher::hash_of(&stripped); - hash == self.ext_hash - }) - .ok_or(Error::Transaction(TransactionError::BlockNotFound))?; - let events = EventsClient::new(self.client.clone()) - .at(self.block_ref.clone()) - .await?; - Ok( - crate::blocks::ExtrinsicEvents::new( - self.ext_hash, - extrinsic_idx as u32, - events, - ), - ) - } - } - } - pub use self::{ - signer::Signer, - tx_client::{ - PartialExtrinsic, SubmittableExtrinsic, TransactionInvalid, - TransactionUnknown, TxClient, ValidationResult, - }, - tx_payload::{dynamic, BoxedPayload, DynamicPayload, Payload, TxPayload}, - tx_progress::{TxInBlock, TxProgress, TxStatus}, - }; -} -pub mod utils { - //! Miscellaneous utility helpers. - mod account_id { - //! The "default" Substrate/Polkadot AccountId. This is used in codegen, as well as signing related bits. - //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_core::AccountId32` - //! for instance, to gain functionality without forcing a dependency on Substrate crates here. - use codec::{Decode, Encode}; - use serde::{Deserialize, Serialize}; - /// A 32-byte cryptographic identifier. This is a simplified version of Substrate's - /// `sp_core::crypto::AccountId32`. To obtain more functionality, convert this into - /// that type. - pub struct AccountId32(pub [u8; 32]); - #[automatically_derived] - impl ::core::clone::Clone for AccountId32 { - #[inline] - fn clone(&self) -> AccountId32 { - AccountId32(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::cmp::Eq for AccountId32 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for AccountId32 {} - #[automatically_derived] - impl ::core::cmp::PartialEq for AccountId32 { - #[inline] - fn eq(&self, other: &AccountId32) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Ord for AccountId32 { - #[inline] - fn cmp(&self, other: &AccountId32) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for AccountId32 { - #[inline] - fn partial_cmp( - &self, - other: &AccountId32, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for AccountId32 { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.0) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.0) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.0, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike for AccountId32 {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for AccountId32 { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok( - AccountId32({ - let __codec_res_edqy = <[u8; 32] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `AccountId32.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for AccountId32 { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "AccountId32", - &&self.0, - ) - } - } - impl ::scale_encode::EncodeAsType for AccountId32 { - #[allow(unused_variables)] - fn encode_as_type_to( - &self, - __encode_as_type_type_id: u32, - __encode_as_type_types: &::scale_encode::PortableRegistry, - __encode_as_type_out: &mut ::scale_encode::Vec, - ) -> Result<(), ::scale_encode::Error> { - let AccountId32(_0) = self; - ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ) - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - } - impl ::scale_encode::EncodeAsFields for AccountId32 { - #[allow(unused_variables)] - fn encode_as_fields_to( - &self, - __encode_as_type_fields: &mut dyn ::scale_encode::FieldIter<'_>, - __encode_as_type_types: &::scale_encode::PortableRegistry, - __encode_as_type_out: &mut ::scale_encode::Vec, - ) -> Result<(), ::scale_encode::Error> { - let AccountId32(_0) = self; - ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ) - .encode_as_fields_to( - __encode_as_type_fields, - __encode_as_type_types, - __encode_as_type_out, - ) - } - } - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for AccountId32 { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = AccountId32; - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - self.visit_tuple(&mut value.as_tuple(), type_id) - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: value.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = value; - Ok( - AccountId32({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ) - } - } - impl ::scale_decode::DecodeAsFields for AccountId32 { - fn decode_as_fields<'info>( - input: &mut &[u8], - fields: &mut dyn ::scale_decode::FieldIter<'info>, - types: &'info ::scale_decode::PortableRegistry, - ) -> Result { - let path = ::scale_decode::EMPTY_SCALE_INFO_PATH; - let mut composite = ::scale_decode::visitor::types::Composite::new( - input, - path, - fields, - types, - false, - ); - use ::scale_decode::{Visitor, IntoVisitor}; - let val = ::into_visitor() - .visit_composite( - &mut composite, - ::scale_decode::visitor::TypeId(0), - ); - composite.skip_decoding()?; - *input = composite.bytes_from_undecoded(); - val.map_err(From::from) - } - } - }; - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo for AccountId32 { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "AccountId32", - "subxt::utils::account_id", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .docs( - &[ - "A 32-byte cryptographic identifier. This is a simplified version of Substrate's", - "`sp_core::crypto::AccountId32`. To obtain more functionality, convert this into", - "that type.", - ], - ) - .composite( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 32]>().type_name("[u8; 32]")), - ) - } - } - }; - impl AsRef<[u8]> for AccountId32 { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } - } - impl AsRef<[u8; 32]> for AccountId32 { - fn as_ref(&self) -> &[u8; 32] { - &self.0 - } - } - impl From<[u8; 32]> for AccountId32 { - fn from(x: [u8; 32]) -> Self { - AccountId32(x) - } - } - impl AccountId32 { - fn to_ss58check(&self) -> String { - const SUBSTRATE_SS58_PREFIX: u8 = 42; - let mut v = <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([SUBSTRATE_SS58_PREFIX]), - ); - v.extend(self.0); - let r = ss58hash(&v); - v.extend(&r[0..2]); - use base58::ToBase58; - v.to_base58() - } - fn from_ss58check(s: &str) -> Result { - const CHECKSUM_LEN: usize = 2; - let body_len = 32; - use base58::FromBase58; - let data = s.from_base58().map_err(|_| FromSs58Error::BadBase58)?; - if data.len() < 2 { - return Err(FromSs58Error::BadLength); - } - let prefix_len = match data[0] { - 0..=63 => 1, - 64..=127 => 2, - _ => return Err(FromSs58Error::InvalidPrefix), - }; - if data.len() != prefix_len + body_len + CHECKSUM_LEN { - return Err(FromSs58Error::BadLength); - } - let hash = ss58hash(&data[0..body_len + prefix_len]); - let checksum = &hash[0..CHECKSUM_LEN]; - if data[body_len + prefix_len..body_len + prefix_len + CHECKSUM_LEN] - != *checksum - { - return Err(FromSs58Error::InvalidChecksum); - } - let result = data[prefix_len..body_len + prefix_len] - .try_into() - .map_err(|_| FromSs58Error::BadLength)?; - Ok(AccountId32(result)) - } - } - /// An error obtained from trying to interpret an SS58 encoded string into an AccountId32 - #[allow(missing_docs)] - pub enum FromSs58Error { - #[error("Base 58 requirement is violated")] - BadBase58, - #[error("Length is bad")] - BadLength, - #[error("Invalid checksum")] - InvalidChecksum, - #[error("Invalid SS58 prefix byte.")] - InvalidPrefix, - } - #[allow(unused_qualifications)] - impl std::error::Error for FromSs58Error {} - #[allow(unused_qualifications)] - impl ::core::fmt::Display for FromSs58Error { - fn fmt( - &self, - __formatter: &mut ::core::fmt::Formatter, - ) -> ::core::fmt::Result { - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match self { - FromSs58Error::BadBase58 {} => { - __formatter.write_str("Base 58 requirement is violated") - } - FromSs58Error::BadLength {} => __formatter.write_str("Length is bad"), - FromSs58Error::InvalidChecksum {} => { - __formatter.write_str("Invalid checksum") - } - FromSs58Error::InvalidPrefix {} => { - __formatter.write_str("Invalid SS58 prefix byte.") - } - } - } - } - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::clone::Clone for FromSs58Error { - #[inline] - fn clone(&self) -> FromSs58Error { - *self - } - } - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::marker::Copy for FromSs58Error {} - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::cmp::Eq for FromSs58Error { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::marker::StructuralPartialEq for FromSs58Error {} - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::cmp::PartialEq for FromSs58Error { - #[inline] - fn eq(&self, other: &FromSs58Error) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } - } - #[automatically_derived] - #[allow(missing_docs)] - impl ::core::fmt::Debug for FromSs58Error { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - FromSs58Error::BadBase58 => "BadBase58", - FromSs58Error::BadLength => "BadLength", - FromSs58Error::InvalidChecksum => "InvalidChecksum", - FromSs58Error::InvalidPrefix => "InvalidPrefix", - }, - ) - } - } - fn ss58hash(data: &[u8]) -> Vec { - use blake2::{Blake2b512, Digest}; - const PREFIX: &[u8] = b"SS58PRE"; - let mut ctx = Blake2b512::new(); - ctx.update(PREFIX); - ctx.update(data); - ctx.finalize().to_vec() - } - impl Serialize for AccountId32 { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self.to_ss58check()) - } - } - impl<'de> Deserialize<'de> for AccountId32 { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - AccountId32::from_ss58check(&String::deserialize(deserializer)?) - .map_err(|e| serde::de::Error::custom({ - let res = ::alloc::fmt::format(format_args!("{0:?}", e)); - res - })) - } - } - impl std::fmt::Display for AccountId32 { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.write_fmt(format_args!("{0}", self.to_ss58check())) - } - } - impl std::str::FromStr for AccountId32 { - type Err = FromSs58Error; - fn from_str(s: &str) -> Result { - AccountId32::from_ss58check(s) - } - } - } - pub mod bits { - //! Generic `scale_bits` over `bitvec`-like `BitOrder` and `BitFormat` types. - use codec::{Compact, Input}; - use scale_bits::{ - scale::format::{Format, OrderFormat, StoreFormat}, - Bits, - }; - use scale_decode::IntoVisitor; - use std::marker::PhantomData; - /// Associates `bitvec::store::BitStore` trait with corresponding, type-erased `scale_bits::StoreFormat` enum. - /// - /// Used to decode bit sequences by providing `scale_bits::StoreFormat` using - /// `bitvec`-like type type parameters. - pub trait BitStore { - /// Corresponding `scale_bits::StoreFormat` value. - const FORMAT: StoreFormat; - /// Number of bits that the backing store types holds. - const BITS: u32; - } - impl BitStore for u8 { - const FORMAT: StoreFormat = StoreFormat::U8; - const BITS: u32 = ::BITS; - } - impl BitStore for u16 { - const FORMAT: StoreFormat = StoreFormat::U16; - const BITS: u32 = ::BITS; - } - impl BitStore for u32 { - const FORMAT: StoreFormat = StoreFormat::U32; - const BITS: u32 = ::BITS; - } - impl BitStore for u64 { - const FORMAT: StoreFormat = StoreFormat::U64; - const BITS: u32 = ::BITS; - } - /// Associates `bitvec::order::BitOrder` trait with corresponding, type-erased `scale_bits::OrderFormat` enum. - /// - /// Used to decode bit sequences in runtime by providing `scale_bits::OrderFormat` using - /// `bitvec`-like type type parameters. - pub trait BitOrder { - /// Corresponding `scale_bits::OrderFormat` value. - const FORMAT: OrderFormat; - } - ///Type-level value that corresponds to `scale_bits::OrderFormat::Lsb0` at run-time - /// and `bitvec::order::BitOrder::Lsb0` at the type level. - pub enum Lsb0 {} - #[automatically_derived] - impl ::core::clone::Clone for Lsb0 { - #[inline] - fn clone(&self) -> Lsb0 { - match *self {} - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Lsb0 { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self {} - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Lsb0 {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Lsb0 { - #[inline] - fn eq(&self, other: &Lsb0) -> bool { - match *self {} - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Lsb0 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - impl BitOrder for Lsb0 { - const FORMAT: OrderFormat = OrderFormat::Lsb0; - } - ///Type-level value that corresponds to `scale_bits::OrderFormat::Msb0` at run-time - /// and `bitvec::order::BitOrder::Msb0` at the type level. - pub enum Msb0 {} - #[automatically_derived] - impl ::core::clone::Clone for Msb0 { - #[inline] - fn clone(&self) -> Msb0 { - match *self {} - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Msb0 { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match *self {} - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Msb0 {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Msb0 { - #[inline] - fn eq(&self, other: &Msb0) -> bool { - match *self {} - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Msb0 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} - } - impl BitOrder for Msb0 { - const FORMAT: OrderFormat = OrderFormat::Msb0; - } - /// Constructs a run-time format parameters based on the corresponding type-level parameters. - fn bit_format() -> Format { - Format { - order: Order::FORMAT, - store: Store::FORMAT, - } - } - /// `scale_bits::Bits` generic over the bit store (`u8`/`u16`/`u32`/`u64`) and bit order (LSB, MSB) - /// used for SCALE encoding/decoding. Uses `scale_bits::Bits`-default `u8` and LSB format underneath. - pub struct DecodedBits { - bits: Bits, - _marker: PhantomData<(Store, Order)>, - } - #[automatically_derived] - impl ::core::fmt::Debug - for DecodedBits { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "DecodedBits", - "bits", - &self.bits, - "_marker", - &&self._marker, - ) - } - } - #[automatically_derived] - impl< - Store: ::core::clone::Clone, - Order: ::core::clone::Clone, - > ::core::clone::Clone for DecodedBits { - #[inline] - fn clone(&self) -> DecodedBits { - DecodedBits { - bits: ::core::clone::Clone::clone(&self.bits), - _marker: ::core::clone::Clone::clone(&self._marker), - } - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for DecodedBits {} - #[automatically_derived] - impl< - Store: ::core::cmp::PartialEq, - Order: ::core::cmp::PartialEq, - > ::core::cmp::PartialEq for DecodedBits { - #[inline] - fn eq(&self, other: &DecodedBits) -> bool { - self.bits == other.bits && self._marker == other._marker - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for DecodedBits { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - } - } - impl DecodedBits { - /// Extracts the underlying `scale_bits::Bits` value. - pub fn into_bits(self) -> Bits { - self.bits - } - /// References the underlying `scale_bits::Bits` value. - pub fn as_bits(&self) -> &Bits { - &self.bits - } - } - impl core::iter::FromIterator for DecodedBits { - fn from_iter>(iter: T) -> Self { - DecodedBits { - bits: Bits::from_iter(iter), - _marker: PhantomData, - } - } - } - impl codec::Decode - for DecodedBits { - fn decode(input: &mut I) -> Result { - /// Equivalent of `BitSlice::MAX_BITS` on 32bit machine. - const ARCH32BIT_BITSLICE_MAX_BITS: u32 = 0x1fff_ffff; - let Compact(bits) = >::decode(input)?; - if bits > ARCH32BIT_BITSLICE_MAX_BITS { - return Err("Attempt to decode a BitVec with too many bits".into()); - } - let elements = (bits / Store::BITS) + u32::from(bits % Store::BITS != 0); - let bytes_in_elem = Store::BITS.saturating_div(u8::BITS); - let bytes_needed = (elements * bytes_in_elem) as usize; - let mut storage = codec::Encode::encode(&Compact(bits)); - let prefix_len = storage.len(); - storage.reserve_exact(bytes_needed); - storage.extend(::alloc::vec::from_elem(0, bytes_needed)); - input.read(&mut storage[prefix_len..])?; - let decoder = scale_bits::decode_using_format_from( - &storage, - bit_format::(), - )?; - let bits = decoder.collect::, _>>()?; - let bits = Bits::from_iter(bits); - Ok(DecodedBits { - bits, - _marker: PhantomData, - }) - } - } - impl codec::Encode - for DecodedBits { - fn size_hint(&self) -> usize { - self.bits.size_hint() - } - fn encoded_size(&self) -> usize { - self.bits.encoded_size() - } - fn encode(&self) -> Vec { - scale_bits::encode_using_format( - self.bits.iter(), - bit_format::(), - ) - } - } - #[doc(hidden)] - pub struct DecodedBitsVisitor(std::marker::PhantomData<(S, O)>); - impl scale_decode::Visitor for DecodedBitsVisitor { - type Value<'scale, 'info> = DecodedBits; - type Error = scale_decode::Error; - fn unchecked_decode_as_type<'scale, 'info>( - self, - input: &mut &'scale [u8], - type_id: scale_decode::visitor::TypeId, - types: &'info scale_info::PortableRegistry, - ) -> scale_decode::visitor::DecodeAsTypeResult< - Self, - Result, Self::Error>, - > { - let res = scale_decode::visitor::decode_with_visitor( - input, - type_id.0, - types, - Bits::into_visitor(), - ) - .map(|bits| DecodedBits { - bits, - _marker: PhantomData, - }); - scale_decode::visitor::DecodeAsTypeResult::Decoded(res) - } - } - impl scale_decode::IntoVisitor for DecodedBits { - type Visitor = DecodedBitsVisitor; - fn into_visitor() -> Self::Visitor { - DecodedBitsVisitor(PhantomData) - } - } - impl scale_encode::EncodeAsType for DecodedBits { - fn encode_as_type_to( - &self, - type_id: u32, - types: &scale_info::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - self.bits.encode_as_type_to(type_id, types, out) - } - } - } - mod era { - use scale_decode::DecodeAsType; - use scale_encode::EncodeAsType; - /// An era to describe the longevity of a transaction. - pub enum Era { - /// The transaction is valid forever. The genesis hash must be present in the signed content. - #[default] - Immortal, - /// The transaction will expire. Use [`Era::mortal`] to construct this with correct values. - /// - /// When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter - /// of `system` module. - Mortal { - /// The number of blocks that the tx will be valid for after the checkpoint block - /// hash found in the signer payload. - period: u64, - /// The phase in the period that this transaction's lifetime begins (and, importantly, - /// implies which block hash is included in the signature material). If the `period` is - /// greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that - /// `period` is. - phase: u64, - }, - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Era {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Era { - #[inline] - fn eq(&self, other: &Era) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - Era::Mortal { period: __self_0, phase: __self_1 }, - Era::Mortal { period: __arg1_0, phase: __arg1_1 }, - ) => *__self_0 == *__arg1_0 && *__self_1 == *__arg1_1, - _ => true, - } - } - } - #[automatically_derived] - impl ::core::default::Default for Era { - #[inline] - fn default() -> Era { - Self::Immortal - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Era { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Era { - #[inline] - fn clone(&self) -> Era { - let _: ::core::clone::AssertParamIsClone; - *self - } - } - #[automatically_derived] - impl ::core::marker::Copy for Era {} - #[automatically_derived] - impl ::core::fmt::Debug for Era { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - Era::Immortal => ::core::fmt::Formatter::write_str(f, "Immortal"), - Era::Mortal { period: __self_0, phase: __self_1 } => { - ::core::fmt::Formatter::debug_struct_field2_finish( - f, - "Mortal", - "period", - __self_0, - "phase", - &__self_1, - ) - } - } - } - } - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl _serde::Serialize for Era { - fn serialize<__S>( - &self, - __serializer: __S, - ) -> _serde::__private::Result<__S::Ok, __S::Error> - where - __S: _serde::Serializer, - { - match *self { - Era::Immortal => { - _serde::Serializer::serialize_unit_variant( - __serializer, - "Era", - 0u32, - "Immortal", - ) - } - Era::Mortal { ref period, ref phase } => { - let mut __serde_state = _serde::Serializer::serialize_struct_variant( - __serializer, - "Era", - 1u32, - "Mortal", - 0 + 1 + 1, - )?; - _serde::ser::SerializeStructVariant::serialize_field( - &mut __serde_state, - "period", - period, - )?; - _serde::ser::SerializeStructVariant::serialize_field( - &mut __serde_state, - "phase", - phase, - )?; - _serde::ser::SerializeStructVariant::end(__serde_state) - } - } - } - } - }; - #[doc(hidden)] - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - #[allow(unused_extern_crates, clippy::useless_attribute)] - extern crate serde as _serde; - #[automatically_derived] - impl<'de> _serde::Deserialize<'de> for Era { - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "variant identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value), - &"variant index 0 <= i < 2", - ), - ) - } - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "Immortal" => _serde::__private::Ok(__Field::__field0), - "Mortal" => _serde::__private::Ok(__Field::__field1), - _ => { - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"Immortal" => _serde::__private::Ok(__Field::__field0), - b"Mortal" => _serde::__private::Ok(__Field::__field1), - _ => { - let __value = &_serde::__private::from_utf8_lossy(__value); - _serde::__private::Err( - _serde::de::Error::unknown_variant(__value, VARIANTS), - ) - } - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Era; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "enum Era", - ) - } - fn visit_enum<__A>( - self, - __data: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::EnumAccess<'de>, - { - match _serde::de::EnumAccess::variant(__data)? { - (__Field::__field0, __variant) => { - _serde::de::VariantAccess::unit_variant(__variant)?; - _serde::__private::Ok(Era::Immortal) - } - (__Field::__field1, __variant) => { - #[allow(non_camel_case_types)] - #[doc(hidden)] - enum __Field { - __field0, - __field1, - __ignore, - } - #[doc(hidden)] - struct __FieldVisitor; - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "field identifier", - ) - } - fn visit_u64<__E>( - self, - __value: u64, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - 0u64 => _serde::__private::Ok(__Field::__field0), - 1u64 => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_str<__E>( - self, - __value: &str, - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - "period" => _serde::__private::Ok(__Field::__field0), - "phase" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - fn visit_bytes<__E>( - self, - __value: &[u8], - ) -> _serde::__private::Result - where - __E: _serde::de::Error, - { - match __value { - b"period" => _serde::__private::Ok(__Field::__field0), - b"phase" => _serde::__private::Ok(__Field::__field1), - _ => _serde::__private::Ok(__Field::__ignore), - } - } - } - impl<'de> _serde::Deserialize<'de> for __Field { - #[inline] - fn deserialize<__D>( - __deserializer: __D, - ) -> _serde::__private::Result - where - __D: _serde::Deserializer<'de>, - { - _serde::Deserializer::deserialize_identifier( - __deserializer, - __FieldVisitor, - ) - } - } - #[doc(hidden)] - struct __Visitor<'de> { - marker: _serde::__private::PhantomData, - lifetime: _serde::__private::PhantomData<&'de ()>, - } - impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> { - type Value = Era; - fn expecting( - &self, - __formatter: &mut _serde::__private::Formatter, - ) -> _serde::__private::fmt::Result { - _serde::__private::Formatter::write_str( - __formatter, - "struct variant Era::Mortal", - ) - } - #[inline] - fn visit_seq<__A>( - self, - mut __seq: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::SeqAccess<'de>, - { - let __field0 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 0usize, - &"struct variant Era::Mortal with 2 elements", - ), - ); - } - }; - let __field1 = match _serde::de::SeqAccess::next_element::< - u64, - >(&mut __seq)? { - _serde::__private::Some(__value) => __value, - _serde::__private::None => { - return _serde::__private::Err( - _serde::de::Error::invalid_length( - 1usize, - &"struct variant Era::Mortal with 2 elements", - ), - ); - } - }; - _serde::__private::Ok(Era::Mortal { - period: __field0, - phase: __field1, - }) - } - #[inline] - fn visit_map<__A>( - self, - mut __map: __A, - ) -> _serde::__private::Result - where - __A: _serde::de::MapAccess<'de>, - { - let mut __field0: _serde::__private::Option = _serde::__private::None; - let mut __field1: _serde::__private::Option = _serde::__private::None; - while let _serde::__private::Some(__key) - = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { - match __key { - __Field::__field0 => { - if _serde::__private::Option::is_some(&__field0) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("period"), - ); - } - __field0 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - __Field::__field1 => { - if _serde::__private::Option::is_some(&__field1) { - return _serde::__private::Err( - <__A::Error as _serde::de::Error>::duplicate_field("phase"), - ); - } - __field1 = _serde::__private::Some( - _serde::de::MapAccess::next_value::(&mut __map)?, - ); - } - _ => { - let _ = _serde::de::MapAccess::next_value::< - _serde::de::IgnoredAny, - >(&mut __map)?; - } - } - } - let __field0 = match __field0 { - _serde::__private::Some(__field0) => __field0, - _serde::__private::None => { - _serde::__private::de::missing_field("period")? - } - }; - let __field1 = match __field1 { - _serde::__private::Some(__field1) => __field1, - _serde::__private::None => { - _serde::__private::de::missing_field("phase")? - } - }; - _serde::__private::Ok(Era::Mortal { - period: __field0, - phase: __field1, - }) - } - } - #[doc(hidden)] - const FIELDS: &'static [&'static str] = &[ - "period", - "phase", - ]; - _serde::de::VariantAccess::struct_variant( - __variant, - FIELDS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - } - } - #[doc(hidden)] - const VARIANTS: &'static [&'static str] = &["Immortal", "Mortal"]; - _serde::Deserializer::deserialize_enum( - __deserializer, - "Era", - VARIANTS, - __Visitor { - marker: _serde::__private::PhantomData::, - lifetime: _serde::__private::PhantomData, - }, - ) - } - } - }; - const _: () = { - pub struct Visitor(::core::marker::PhantomData<()>); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor for Era { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor for Visitor { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = Era; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "Immortal" { - return Ok(Era::Immortal); - } - if value.name() == "Mortal" { - let fields = value.fields(); - return if fields.has_unnamed_fields() { - if fields.remaining() != 2usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 2usize, - }), - ); - } - let vals = fields; - Ok(Era::Mortal { - period: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("period"))? - }, - phase: { - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_field("phase"))? - }, - }) - } else { - let vals: ::scale_decode::BTreeMap, _> = fields - .map(|res| res.map(|item| (item.name(), item))) - .collect::>()?; - Ok(Era::Mortal { - period: { - let val = *vals - .get(&Some("period")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "period".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("period"))? - }, - phase: { - let val = *vals - .get(&Some("phase")) - .ok_or_else(|| ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindField { - name: "phase".to_string(), - }))?; - val.decode_as_type().map_err(|e| e.at_field("phase"))? - }, - }) - }; - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new(["Immortal", "Mortal"]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - impl ::scale_encode::EncodeAsType for Era { - #[allow(unused_variables)] - fn encode_as_type_to( - &self, - __encode_as_type_type_id: u32, - __encode_as_type_types: &::scale_encode::PortableRegistry, - __encode_as_type_out: &mut ::scale_encode::Vec, - ) -> Result<(), ::scale_encode::Error> { - match self { - Self::Immortal => { - ::scale_encode::Variant { - name: "Immortal", - fields: ::scale_encode::Composite( - ([] - as [( - Option<&'static str>, - &dyn ::scale_encode::EncodeAsType, - ); 0]) - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Mortal { period, phase } => { - ::scale_encode::Variant { - name: "Mortal", - fields: ::scale_encode::Composite( - [ - ( - Some("period"), - period as &dyn ::scale_encode::EncodeAsType, - ), - (Some("phase"), phase as &dyn ::scale_encode::EncodeAsType), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - _ => { - ::core::panicking::panic( - "internal error: entered unreachable code", - ) - } - } - } - } - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo for Era { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "Era", - "subxt::utils::era", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .docs(&["An era to describe the longevity of a transaction."]) - .variant( - ::scale_info::build::Variants::new() - .variant( - "Immortal", - |v| { - v - .index(0usize as ::core::primitive::u8) - .docs( - &[ - "The transaction is valid forever. The genesis hash must be present in the signed content.", - ], - ) - }, - ) - .variant( - "Mortal", - |v| { - v - .index(1usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::named() - .field(|f| { - f - .ty::() - .name("period") - .type_name("u64") - .docs( - &[ - "The number of blocks that the tx will be valid for after the checkpoint block", - "hash found in the signer payload.", - ], - ) - }) - .field(|f| { - f - .ty::() - .name("phase") - .type_name("u64") - .docs( - &[ - "The phase in the period that this transaction's lifetime begins (and, importantly,", - "implies which block hash is included in the signature material). If the `period` is", - "greater than 1 << 12, then it will be a factor of the times greater than 1<<12 that", - "`period` is.", - ], - ) - }), - ) - .docs( - &[ - "The transaction will expire. Use [`Era::mortal`] to construct this with correct values.", - "", - "When used on `FRAME`-based runtimes, `period` cannot exceed `BlockHashCount` parameter", - "of `system` module.", - ], - ) - }, - ), - ) - } - } - }; - impl Era { - /// Create a new era based on a period (which should be a power of two between 4 and 65536 - /// inclusive) and a block number on which it should start (or, for long periods, be shortly - /// after the start). - /// - /// If using `Era` in the context of `FRAME` runtime, make sure that `period` - /// does not exceed `BlockHashCount` parameter passed to `system` module, since that - /// prunes old blocks and renders transactions immediately invalid. - pub fn mortal(period: u64, current: u64) -> Self { - let period = period - .checked_next_power_of_two() - .unwrap_or(1 << 16) - .clamp(4, 1 << 16); - let phase = current % period; - let quantize_factor = (period >> 12).max(1); - let quantized_phase = phase / quantize_factor * quantize_factor; - Self::Mortal { - period, - phase: quantized_phase, - } - } - } - impl codec::Encode for Era { - fn encode_to(&self, output: &mut T) { - match self { - Self::Immortal => output.push_byte(0), - Self::Mortal { period, phase } => { - let quantize_factor = (*period >> 12).max(1); - let encoded = (period.trailing_zeros() - 1).clamp(1, 15) as u16 - | ((phase / quantize_factor) << 4) as u16; - encoded.encode_to(output); - } - } - } - } - impl codec::Decode for Era { - fn decode(input: &mut I) -> Result { - let first = input.read_byte()?; - if first == 0 { - Ok(Self::Immortal) - } else { - let encoded = first as u64 + ((input.read_byte()? as u64) << 8); - let period = 2 << (encoded % (1 << 4)); - let quantize_factor = (period >> 12).max(1); - let phase = (encoded >> 4) * quantize_factor; - if period >= 4 && phase < period { - Ok(Self::Mortal { period, phase }) - } else { - Err("Invalid period and phase".into()) - } - } - } - } - } - mod multi_address { - //! The "default" Substrate/Polkadot Address type. This is used in codegen, as well as signing related bits. - //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_runtime::MultiAddress` - //! for instance, to gain functionality without forcing a dependency on Substrate crates here. - use codec::{Decode, Encode}; - /// A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's - /// `sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion - /// functionality is provided via `From` impls if the `substrate-compat` feature is enabled). - pub enum MultiAddress { - /// It's an account ID (pubkey). - Id(AccountId), - /// It's an account index. - Index(#[codec(compact)] AccountIndex), - /// It's some arbitrary raw bytes. - Raw(Vec), - /// It's a 32 byte representation. - Address32([u8; 32]), - /// Its a 20 byte representation. - Address20([u8; 20]), - } - #[automatically_derived] - impl< - AccountId: ::core::clone::Clone, - AccountIndex: ::core::clone::Clone, - > ::core::clone::Clone for MultiAddress { - #[inline] - fn clone(&self) -> MultiAddress { - match self { - MultiAddress::Id(__self_0) => { - MultiAddress::Id(::core::clone::Clone::clone(__self_0)) - } - MultiAddress::Index(__self_0) => { - MultiAddress::Index(::core::clone::Clone::clone(__self_0)) - } - MultiAddress::Raw(__self_0) => { - MultiAddress::Raw(::core::clone::Clone::clone(__self_0)) - } - MultiAddress::Address32(__self_0) => { - MultiAddress::Address32(::core::clone::Clone::clone(__self_0)) - } - MultiAddress::Address20(__self_0) => { - MultiAddress::Address20(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq - for MultiAddress { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq; - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq<[u8; 32]>; - let _: ::core::cmp::AssertParamIsEq<[u8; 20]>; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for MultiAddress {} - #[automatically_derived] - impl< - AccountId: ::core::cmp::PartialEq, - AccountIndex: ::core::cmp::PartialEq, - > ::core::cmp::PartialEq for MultiAddress { - #[inline] - fn eq(&self, other: &MultiAddress) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - ( - MultiAddress::Index(__self_0), - MultiAddress::Index(__arg1_0), - ) => *__self_0 == *__arg1_0, - (MultiAddress::Raw(__self_0), MultiAddress::Raw(__arg1_0)) => { - *__self_0 == *__arg1_0 - } - ( - MultiAddress::Address32(__self_0), - MultiAddress::Address32(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MultiAddress::Address20(__self_0), - MultiAddress::Address20(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl< - AccountId: ::core::cmp::Ord, - AccountIndex: ::core::cmp::Ord, - > ::core::cmp::Ord for MultiAddress { - #[inline] - fn cmp( - &self, - other: &MultiAddress, - ) -> ::core::cmp::Ordering { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) { - ::core::cmp::Ordering::Equal => { - match (self, other) { - (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { - ::core::cmp::Ord::cmp(__self_0, __arg1_0) - } - ( - MultiAddress::Index(__self_0), - MultiAddress::Index(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiAddress::Raw(__self_0), - MultiAddress::Raw(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiAddress::Address32(__self_0), - MultiAddress::Address32(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiAddress::Address20(__self_0), - MultiAddress::Address20(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl< - AccountId: ::core::cmp::PartialOrd, - AccountIndex: ::core::cmp::PartialOrd, - > ::core::cmp::PartialOrd for MultiAddress { - #[inline] - fn partial_cmp( - &self, - other: &MultiAddress, - ) -> ::core::option::Option<::core::cmp::Ordering> { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match (self, other) { - (MultiAddress::Id(__self_0), MultiAddress::Id(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - (MultiAddress::Index(__self_0), MultiAddress::Index(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - (MultiAddress::Raw(__self_0), MultiAddress::Raw(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - ( - MultiAddress::Address32(__self_0), - MultiAddress::Address32(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - ( - MultiAddress::Address20(__self_0), - MultiAddress::Address20(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode - for MultiAddress - where - AccountId: ::codec::Encode, - AccountId: ::codec::Encode, - AccountIndex: ::codec::HasCompact, - { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - MultiAddress::Id(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiAddress::Index(ref aa) => { - 0_usize - .saturating_add( - ::codec::Encode::size_hint( - &<::Type as ::codec::EncodeAsRef< - '_, - AccountIndex, - >>::RefType::from(aa), - ), - ) - } - MultiAddress::Raw(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiAddress::Address32(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiAddress::Address20(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - _ => 0_usize, - } - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - match *self { - MultiAddress::Id(ref aa) => { - __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiAddress::Index(ref aa) => { - __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); - { - ::codec::Encode::encode_to( - &<::Type as ::codec::EncodeAsRef< - '_, - AccountIndex, - >>::RefType::from(aa), - __codec_dest_edqy, - ); - } - } - MultiAddress::Raw(ref aa) => { - __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiAddress::Address32(ref aa) => { - __codec_dest_edqy.push_byte(3usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiAddress::Address20(ref aa) => { - __codec_dest_edqy.push_byte(4usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::codec::EncodeLike - for MultiAddress - where - AccountId: ::codec::Encode, - AccountId: ::codec::Encode, - AccountIndex: ::codec::HasCompact, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode - for MultiAddress - where - AccountId: ::codec::Decode, - AccountId: ::codec::Decode, - AccountIndex: ::codec::HasCompact, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `MultiAddress`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Id({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Id.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Index({ - let __codec_res_edqy = <::Type as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Index.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy.into() - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Raw({ - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Raw.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 3usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Address32({ - let __codec_res_edqy = <[u8; 32] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Address32.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 4usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiAddress::< - AccountId, - AccountIndex, - >::Address20({ - let __codec_res_edqy = <[u8; 20] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiAddress::Address20.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `MultiAddress`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - #[automatically_derived] - impl< - AccountId: ::core::fmt::Debug, - AccountIndex: ::core::fmt::Debug, - > ::core::fmt::Debug for MultiAddress { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - MultiAddress::Id(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Id", - &__self_0, - ) - } - MultiAddress::Index(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Index", - &__self_0, - ) - } - MultiAddress::Raw(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Raw", - &__self_0, - ) - } - MultiAddress::Address32(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Address32", - &__self_0, - ) - } - MultiAddress::Address20(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Address20", - &__self_0, - ) - } - } - } - } - impl ::scale_encode::EncodeAsType - for MultiAddress - where - AccountId: ::scale_encode::EncodeAsType, - AccountIndex: ::scale_encode::EncodeAsType, - { - #[allow(unused_variables)] - fn encode_as_type_to( - &self, - __encode_as_type_type_id: u32, - __encode_as_type_types: &::scale_encode::PortableRegistry, - __encode_as_type_out: &mut ::scale_encode::Vec, - ) -> Result<(), ::scale_encode::Error> { - match self { - Self::Id(_0) => { - ::scale_encode::Variant { - name: "Id", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Index(_0) => { - ::scale_encode::Variant { - name: "Index", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Raw(_0) => { - ::scale_encode::Variant { - name: "Raw", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Address32(_0) => { - ::scale_encode::Variant { - name: "Address32", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - Self::Address20(_0) => { - ::scale_encode::Variant { - name: "Address20", - fields: ::scale_encode::Composite( - [ - ( - None as Option<&'static str>, - _0 as &dyn ::scale_encode::EncodeAsType, - ), - ] - .into_iter(), - ), - } - .encode_as_type_to( - __encode_as_type_type_id, - __encode_as_type_types, - __encode_as_type_out, - ) - } - _ => { - ::core::panicking::panic( - "internal error: entered unreachable code", - ) - } - } - } - } - const _: () = { - pub struct Visitor( - ::core::marker::PhantomData<(AccountId, AccountIndex)>, - ); - use ::scale_decode::vec; - use ::scale_decode::ToString; - impl ::scale_decode::IntoVisitor - for MultiAddress - where - AccountId: ::scale_decode::IntoVisitor, - ::scale_decode::Error: From< - <::Visitor as ::scale_decode::Visitor>::Error, - >, - AccountIndex: ::scale_decode::IntoVisitor, - ::scale_decode::Error: From< - <::Visitor as ::scale_decode::Visitor>::Error, - >, - { - type Visitor = Visitor; - fn into_visitor() -> Self::Visitor { - Visitor(::core::marker::PhantomData) - } - } - impl ::scale_decode::Visitor - for Visitor - where - AccountId: ::scale_decode::IntoVisitor, - ::scale_decode::Error: From< - <::Visitor as ::scale_decode::Visitor>::Error, - >, - AccountIndex: ::scale_decode::IntoVisitor, - ::scale_decode::Error: From< - <::Visitor as ::scale_decode::Visitor>::Error, - >, - { - type Error = ::scale_decode::Error; - type Value<'scale, 'info> = MultiAddress; - fn visit_variant<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Variant<'scale, 'info>, - type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.name() == "Id" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Id({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Index" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Index({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Raw" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Raw({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Address32" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Address32({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - if value.name() == "Address20" { - let fields = value.fields(); - if fields.remaining() != 1usize { - return Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::WrongLength { - actual_len: fields.remaining(), - expected_len: 1usize, - }), - ); - } - let vals = fields; - return Ok( - MultiAddress::Address20({ - let val = vals - .next() - .expect( - "field count should have been checked already on tuple type; please file a bug report", - )?; - val.decode_as_type().map_err(|e| e.at_idx(0usize))? - }), - ); - } - Err( - ::scale_decode::Error::new(::scale_decode::error::ErrorKind::CannotFindVariant { - got: value.name().to_string(), - expected: <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - "Id", - "Index", - "Raw", - "Address32", - "Address20", - ]), - ), - }), - ) - } - fn visit_composite<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Composite, - ); - } - value.decode_item(self).unwrap() - } - fn visit_tuple<'scale, 'info>( - self, - value: &mut ::scale_decode::visitor::types::Tuple<'scale, 'info>, - _type_id: ::scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - if value.remaining() != 1 { - return self - .visit_unexpected( - ::scale_decode::visitor::Unexpected::Tuple, - ); - } - value.decode_item(self).unwrap() - } - } - }; - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo - for MultiAddress - where - AccountId: ::scale_info::TypeInfo + 'static, - AccountIndex: ::scale_info::scale::HasCompact, - AccountId: ::scale_info::TypeInfo + 'static, - AccountIndex: ::scale_info::TypeInfo + 'static, - { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "MultiAddress", - "subxt::utils::multi_address", - &[], - ), - ) - .type_params( - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - ::scale_info::TypeParameter::new( - "AccountId", - ::core::option::Option::Some( - ::scale_info::meta_type::(), - ), - ), - ::scale_info::TypeParameter::new( - "AccountIndex", - ::core::option::Option::Some( - ::scale_info::meta_type::(), - ), - ), - ]), - ), - ) - .docs( - &[ - "A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's", - "`sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion", - "functionality is provided via `From` impls if the `substrate-compat` feature is enabled).", - ], - ) - .variant( - ::scale_info::build::Variants::new() - .variant( - "Id", - |v| { - v - .index(0usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::().type_name("AccountId")), - ) - .docs(&["It's an account ID (pubkey)."]) - }, - ) - .variant( - "Index", - |v| { - v - .index(1usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| { - f.compact::().type_name("AccountIndex") - }), - ) - .docs(&["It's an account index."]) - }, - ) - .variant( - "Raw", - |v| { - v - .index(2usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::>().type_name("Vec")), - ) - .docs(&["It's some arbitrary raw bytes."]) - }, - ) - .variant( - "Address32", - |v| { - v - .index(3usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 32]>().type_name("[u8; 32]")), - ) - .docs(&["It's a 32 byte representation."]) - }, - ) - .variant( - "Address20", - |v| { - v - .index(4usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 20]>().type_name("[u8; 20]")), - ) - .docs(&["Its a 20 byte representation."]) - }, - ), - ) - } - } - }; - impl From - for MultiAddress { - fn from(a: AccountId) -> Self { - Self::Id(a) - } - } - } - mod multi_signature { - //! The "default" Substrate/Polkadot Signature type. This is used in codegen, as well as signing related bits. - //! This doesn't contain much functionality itself, but is easy to convert to/from an `sp_runtime::MultiSignature` - //! for instance, to gain functionality without forcing a dependency on Substrate crates here. - use codec::{Decode, Encode}; - /// Signature container that can store known signature types. This is a simplified version of - /// `sp_runtime::MultiSignature`. To obtain more functionality, convert this into that type. - pub enum MultiSignature { - /// An Ed25519 signature. - Ed25519([u8; 64]), - /// An Sr25519 signature. - Sr25519([u8; 64]), - /// An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID). - Ecdsa([u8; 65]), - } - #[automatically_derived] - impl ::core::clone::Clone for MultiSignature { - #[inline] - fn clone(&self) -> MultiSignature { - match self { - MultiSignature::Ed25519(__self_0) => { - MultiSignature::Ed25519(::core::clone::Clone::clone(__self_0)) - } - MultiSignature::Sr25519(__self_0) => { - MultiSignature::Sr25519(::core::clone::Clone::clone(__self_0)) - } - MultiSignature::Ecdsa(__self_0) => { - MultiSignature::Ecdsa(::core::clone::Clone::clone(__self_0)) - } - } - } - } - #[automatically_derived] - impl ::core::cmp::Eq for MultiSignature { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; - let _: ::core::cmp::AssertParamIsEq<[u8; 64]>; - let _: ::core::cmp::AssertParamIsEq<[u8; 65]>; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for MultiSignature {} - #[automatically_derived] - impl ::core::cmp::PartialEq for MultiSignature { - #[inline] - fn eq(&self, other: &MultiSignature) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - && match (self, other) { - ( - MultiSignature::Ed25519(__self_0), - MultiSignature::Ed25519(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MultiSignature::Sr25519(__self_0), - MultiSignature::Sr25519(__arg1_0), - ) => *__self_0 == *__arg1_0, - ( - MultiSignature::Ecdsa(__self_0), - MultiSignature::Ecdsa(__arg1_0), - ) => *__self_0 == *__arg1_0, - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - } - #[automatically_derived] - impl ::core::cmp::Ord for MultiSignature { - #[inline] - fn cmp(&self, other: &MultiSignature) -> ::core::cmp::Ordering { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match ::core::cmp::Ord::cmp(&__self_tag, &__arg1_tag) { - ::core::cmp::Ordering::Equal => { - match (self, other) { - ( - MultiSignature::Ed25519(__self_0), - MultiSignature::Ed25519(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiSignature::Sr25519(__self_0), - MultiSignature::Sr25519(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - ( - MultiSignature::Ecdsa(__self_0), - MultiSignature::Ecdsa(__arg1_0), - ) => ::core::cmp::Ord::cmp(__self_0, __arg1_0), - _ => unsafe { ::core::intrinsics::unreachable() } - } - } - cmp => cmp, - } - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for MultiSignature { - #[inline] - fn partial_cmp( - &self, - other: &MultiSignature, - ) -> ::core::option::Option<::core::cmp::Ordering> { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match (self, other) { - ( - MultiSignature::Ed25519(__self_0), - MultiSignature::Ed25519(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - ( - MultiSignature::Sr25519(__self_0), - MultiSignature::Sr25519(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - ( - MultiSignature::Ecdsa(__self_0), - MultiSignature::Ecdsa(__arg1_0), - ) => ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0), - _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for MultiSignature { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - MultiSignature::Ed25519(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiSignature::Sr25519(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - MultiSignature::Ecdsa(ref aa) => { - 0_usize.saturating_add(::codec::Encode::size_hint(aa)) - } - _ => 0_usize, - } - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - match *self { - MultiSignature::Ed25519(ref aa) => { - __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiSignature::Sr25519(ref aa) => { - __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - MultiSignature::Ecdsa(ref aa) => { - __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); - ::codec::Encode::encode_to(aa, __codec_dest_edqy); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::codec::EncodeLike for MultiSignature {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for MultiSignature { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `MultiSignature`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiSignature::Ed25519({ - let __codec_res_edqy = <[u8; 64] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiSignature::Ed25519.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiSignature::Sr25519({ - let __codec_res_edqy = <[u8; 64] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiSignature::Sr25519.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy - == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok( - MultiSignature::Ecdsa({ - let __codec_res_edqy = <[u8; 65] as ::codec::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `MultiSignature::Ecdsa.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `MultiSignature`, variant doesn't exist", - ), - ) - })(); - } - } - } - } - }; - #[automatically_derived] - impl ::core::fmt::Debug for MultiSignature { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - match self { - MultiSignature::Ed25519(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Ed25519", - &__self_0, - ) - } - MultiSignature::Sr25519(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Sr25519", - &__self_0, - ) - } - MultiSignature::Ecdsa(__self_0) => { - ::core::fmt::Formatter::debug_tuple_field1_finish( - f, - "Ecdsa", - &__self_0, - ) - } - } - } - } - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo for MultiSignature { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "MultiSignature", - "subxt::utils::multi_signature", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .docs( - &[ - "Signature container that can store known signature types. This is a simplified version of", - "`sp_runtime::MultiSignature`. To obtain more functionality, convert this into that type.", - ], - ) - .variant( - ::scale_info::build::Variants::new() - .variant( - "Ed25519", - |v| { - v - .index(0usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 64]>().type_name("[u8; 64]")), - ) - .docs(&["An Ed25519 signature."]) - }, - ) - .variant( - "Sr25519", - |v| { - v - .index(1usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 64]>().type_name("[u8; 64]")), - ) - .docs(&["An Sr25519 signature."]) - }, - ) - .variant( - "Ecdsa", - |v| { - v - .index(2usize as ::core::primitive::u8) - .fields( - ::scale_info::build::Fields::unnamed() - .field(|f| f.ty::<[u8; 65]>().type_name("[u8; 65]")), - ) - .docs( - &[ - "An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID).", - ], - ) - }, - ), - ) - } - } - }; - } - mod static_type { - use codec::{Decode, Encode}; - use scale_decode::{visitor::DecodeAsTypeResult, IntoVisitor, Visitor}; - use scale_encode::EncodeAsType; - /// If the type inside this implements [`Encode`], this will implement [`scale_encode::EncodeAsType`]. - /// If the type inside this implements [`Decode`], this will implement [`scale_decode::DecodeAsType`]. - /// - /// In either direction, we ignore any type information and just attempt to encode/decode statically - /// via the [`Encode`] and [`Decode`] implementations. This can be useful as an adapter for types which - /// do not implement [`scale_encode::EncodeAsType`] and [`scale_decode::DecodeAsType`] themselves, but - /// it's best to avoid using it where possible as it will not take into account any type information, - /// and is thus more likely to encode or decode incorrectly. - pub struct Static(pub T); - #[automatically_derived] - impl ::core::fmt::Debug for Static { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Static", &&self.0) - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for Static - where - T: ::codec::Encode, - T: ::codec::Encode, - { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.0) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.0) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.0, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike for Static - where - T: ::codec::Encode, - T: ::codec::Encode, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for Static - where - T: ::codec::Decode, - T: ::codec::Decode, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok( - Static::< - T, - >({ - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `Static.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - } - } - }; - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Static {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Static { - #[inline] - fn eq(&self, other: &Static) -> bool { - self.0 == other.0 - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Static { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for Static { - #[inline] - fn clone(&self) -> Static { - Static(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::cmp::PartialOrd for Static { - #[inline] - fn partial_cmp( - &self, - other: &Static, - ) -> ::core::option::Option<::core::cmp::Ordering> { - ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::cmp::Ord for Static { - #[inline] - fn cmp(&self, other: &Static) -> ::core::cmp::Ordering { - ::core::cmp::Ord::cmp(&self.0, &other.0) - } - } - #[automatically_derived] - impl ::core::hash::Hash for Static { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.0, state) - } - } - impl EncodeAsType for Static { - fn encode_as_type_to( - &self, - _type_id: u32, - _types: &scale_decode::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - self.0.encode_to(out); - Ok(()) - } - } - pub struct StaticDecodeAsTypeVisitor(std::marker::PhantomData); - impl Visitor for StaticDecodeAsTypeVisitor { - type Value<'scale, 'info> = Static; - type Error = scale_decode::Error; - fn unchecked_decode_as_type<'scale, 'info>( - self, - input: &mut &'scale [u8], - _type_id: scale_decode::visitor::TypeId, - _types: &'info scale_info::PortableRegistry, - ) -> DecodeAsTypeResult< - Self, - Result, Self::Error>, - > { - use scale_decode::{visitor::DecodeError, Error}; - let decoded = T::decode(input) - .map(Static) - .map_err(|e| Error::new(DecodeError::CodecError(e).into())); - DecodeAsTypeResult::Decoded(decoded) - } - } - impl IntoVisitor for Static { - type Visitor = StaticDecodeAsTypeVisitor; - fn into_visitor() -> Self::Visitor { - StaticDecodeAsTypeVisitor(std::marker::PhantomData) - } - } - impl From for Static { - fn from(value: T) -> Self { - Static(value) - } - } - impl std::ops::Deref for Static { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl std::ops::DerefMut for Static { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - } - mod unchecked_extrinsic { - //! The "default" Substrate/Polkadot UncheckedExtrinsic. - //! This is used in codegen for runtime API calls. - //! - //! The inner bytes represent the encoded extrinsic expected by the - //! runtime APIs. Deriving `EncodeAsType` would lead to the inner - //! bytes to be re-encoded (length prefixed). - use std::marker::PhantomData; - use codec::{Decode, Encode}; - use scale_decode::{ - visitor::DecodeAsTypeResult, DecodeAsType, IntoVisitor, Visitor, - }; - use super::{Encoded, Static}; - /// The unchecked extrinsic from substrate. - pub struct UncheckedExtrinsic( - Static, - #[codec(skip)] - PhantomData<(Address, Call, Signature, Extra)>, - ); - #[automatically_derived] - impl< - Address: ::core::clone::Clone, - Call: ::core::clone::Clone, - Signature: ::core::clone::Clone, - Extra: ::core::clone::Clone, - > ::core::clone::Clone for UncheckedExtrinsic { - #[inline] - fn clone(&self) -> UncheckedExtrinsic { - UncheckedExtrinsic( - ::core::clone::Clone::clone(&self.0), - ::core::clone::Clone::clone(&self.1), - ) - } - } - #[automatically_derived] - impl< - Address: ::core::fmt::Debug, - Call: ::core::fmt::Debug, - Signature: ::core::fmt::Debug, - Extra: ::core::fmt::Debug, - > ::core::fmt::Debug for UncheckedExtrinsic { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field2_finish( - f, - "UncheckedExtrinsic", - &self.0, - &&self.1, - ) - } - } - #[automatically_derived] - impl< - Address: ::core::cmp::Eq, - Call: ::core::cmp::Eq, - Signature: ::core::cmp::Eq, - Extra: ::core::cmp::Eq, - > ::core::cmp::Eq for UncheckedExtrinsic { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - let _: ::core::cmp::AssertParamIsEq< - PhantomData<(Address, Call, Signature, Extra)>, - >; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq - for UncheckedExtrinsic {} - #[automatically_derived] - impl< - Address: ::core::cmp::PartialEq, - Call: ::core::cmp::PartialEq, - Signature: ::core::cmp::PartialEq, - Extra: ::core::cmp::PartialEq, - > ::core::cmp::PartialEq - for UncheckedExtrinsic { - #[inline] - fn eq( - &self, - other: &UncheckedExtrinsic, - ) -> bool { - self.0 == other.0 && self.1 == other.1 - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode - for UncheckedExtrinsic { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.0) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.0) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.0, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike - for UncheckedExtrinsic {} - }; - impl< - Address, - Call, - Signature, - Extra, - > UncheckedExtrinsic { - /// Construct a new [`UncheckedExtrinsic`]. - pub fn new(bytes: Vec) -> Self { - Self(Static(Encoded(bytes)), PhantomData) - } - /// Get the bytes of the encoded extrinsic. - pub fn bytes(&self) -> &[u8] { - self.0.0.0.as_slice() - } - } - impl Decode - for UncheckedExtrinsic { - fn decode(input: &mut I) -> Result { - let xt_vec: Vec = Decode::decode(input)?; - Ok(UncheckedExtrinsic::new(xt_vec)) - } - } - impl scale_encode::EncodeAsType - for UncheckedExtrinsic { - fn encode_as_type_to( - &self, - type_id: u32, - types: &scale_info::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - self.0.encode_as_type_to(type_id, types, out) - } - } - impl From> - for UncheckedExtrinsic { - fn from(bytes: Vec) -> Self { - UncheckedExtrinsic::new(bytes) - } - } - impl< - Address, - Call, - Signature, - Extra, - > From> for Vec { - fn from(bytes: UncheckedExtrinsic) -> Self { - bytes.0.0.0 - } - } - pub struct UncheckedExtrinsicDecodeAsTypeVisitor< - Address, - Call, - Signature, - Extra, - >( - PhantomData<(Address, Call, Signature, Extra)>, - ); - impl Visitor - for UncheckedExtrinsicDecodeAsTypeVisitor { - type Value<'scale, 'info> = UncheckedExtrinsic< - Address, - Call, - Signature, - Extra, - >; - type Error = scale_decode::Error; - fn unchecked_decode_as_type<'scale, 'info>( - self, - input: &mut &'scale [u8], - type_id: scale_decode::visitor::TypeId, - types: &'info scale_info::PortableRegistry, - ) -> DecodeAsTypeResult< - Self, - Result, Self::Error>, - > { - DecodeAsTypeResult::Decoded( - Self::Value::decode_as_type(input, type_id.0, types), - ) - } - } - impl IntoVisitor - for UncheckedExtrinsic { - type Visitor = UncheckedExtrinsicDecodeAsTypeVisitor< - Address, - Call, - Signature, - Extra, - >; - fn into_visitor() -> Self::Visitor { - UncheckedExtrinsicDecodeAsTypeVisitor(PhantomData) - } - } - } - mod wrapper_opaque { - use super::PhantomDataSendSync; - use codec::{Compact, Decode, DecodeAll, Encode}; - use derivative::Derivative; - use scale_decode::{IntoVisitor, Visitor}; - use scale_encode::EncodeAsType; - /// A wrapper for any type `T` which implement encode/decode in a way compatible with `Vec`. - /// [`WrapperKeepOpaque`] stores the type only in its opaque format, aka as a `Vec`. To - /// access the real type `T` [`Self::try_decode`] needs to be used. - #[derivative( - Debug(bound = ""), - Clone(bound = ""), - PartialEq(bound = ""), - Eq(bound = ""), - Default(bound = ""), - Hash(bound = "") - )] - pub struct WrapperKeepOpaque { - data: Vec, - _phantom: PhantomDataSendSync, - } - #[allow(unused_qualifications)] - impl ::std::clone::Clone for WrapperKeepOpaque { - fn clone(&self) -> Self { - match *self { - WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { - WrapperKeepOpaque { - data: (*__arg_0).clone(), - _phantom: (*__arg_1).clone(), - } - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for WrapperKeepOpaque { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { - let mut __debug_trait_builder = __f - .debug_struct("WrapperKeepOpaque"); - let _ = __debug_trait_builder.field("data", &&(*__arg_0)); - let _ = __debug_trait_builder.field("_phantom", &&(*__arg_1)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::default::Default for WrapperKeepOpaque { - fn default() -> Self { - WrapperKeepOpaque { - data: ::std::default::Default::default(), - _phantom: ::std::default::Default::default(), - } - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for WrapperKeepOpaque {} - #[allow(unused_qualifications)] - impl ::std::hash::Hash for WrapperKeepOpaque { - fn hash<__HT>(&self, __state: &mut __HT) - where - __HT: ::std::hash::Hasher, - { - match *self { - WrapperKeepOpaque { data: ref __arg_0, _phantom: ref __arg_1 } => { - ::std::hash::Hash::hash(&(*__arg_0), __state); - ::std::hash::Hash::hash(&(*__arg_1), __state); - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for WrapperKeepOpaque { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - WrapperKeepOpaque { - data: ref __self_0, - _phantom: ref __self_1, - } => { - match *other { - WrapperKeepOpaque { - data: ref __other_0, - _phantom: ref __other_1, - } => { - true && &(*__self_0) == &(*__other_0) - && &(*__self_1) == &(*__other_1) - } - } - } - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for WrapperKeepOpaque - where - PhantomDataSendSync: ::codec::Encode, - PhantomDataSendSync: ::codec::Encode, - { - fn size_hint(&self) -> usize { - 0_usize - .saturating_add(::codec::Encode::size_hint(&self.data)) - .saturating_add(::codec::Encode::size_hint(&self._phantom)) - } - fn encode_to< - __CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::codec::Encode::encode_to(&self.data, __codec_dest_edqy); - ::codec::Encode::encode_to(&self._phantom, __codec_dest_edqy); - } - } - #[automatically_derived] - impl ::codec::EncodeLike for WrapperKeepOpaque - where - PhantomDataSendSync: ::codec::Encode, - PhantomDataSendSync: ::codec::Encode, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for WrapperKeepOpaque - where - PhantomDataSendSync: ::codec::Decode, - PhantomDataSendSync: ::codec::Decode, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(WrapperKeepOpaque:: { - data: { - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `WrapperKeepOpaque::data`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - _phantom: { - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `WrapperKeepOpaque::_phantom`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - impl WrapperKeepOpaque { - /// Try to decode the wrapped type from the inner `data`. - /// - /// Returns `None` if the decoding failed. - pub fn try_decode(&self) -> Option - where - T: Decode, - { - T::decode_all(&mut &self.data[..]).ok() - } - /// Returns the length of the encoded `T`. - pub fn encoded_len(&self) -> usize { - self.data.len() - } - /// Returns the encoded data. - pub fn encoded(&self) -> &[u8] { - &self.data - } - /// Create from the given encoded `data`. - pub fn from_encoded(data: Vec) -> Self { - Self { - data, - _phantom: PhantomDataSendSync::new(), - } - } - /// Create from some raw value by encoding it. - pub fn from_value(value: T) -> Self - where - T: Encode, - { - Self { - data: value.encode(), - _phantom: PhantomDataSendSync::new(), - } - } - } - impl EncodeAsType for WrapperKeepOpaque { - fn encode_as_type_to( - &self, - type_id: u32, - types: &scale_info::PortableRegistry, - out: &mut Vec, - ) -> Result<(), scale_encode::Error> { - use scale_encode::error::{Error, ErrorKind, Kind}; - let Some(ty) = types.resolve(type_id) else { - return Err(Error::new(ErrorKind::TypeNotFound(type_id))); - }; - let scale_info::TypeDef::Composite(_) = &ty.type_def else { - return Err( - Error::new(ErrorKind::WrongShape { - actual: Kind::Struct, - expected: type_id, - }), - ); - }; - if ty.path.ident().as_deref() != Some("WrapperKeepOpaque") { - return Err( - Error::new(ErrorKind::WrongShape { - actual: Kind::Struct, - expected: type_id, - }), - ); - } - self.data.encode_to(out); - Ok(()) - } - } - pub struct WrapperKeepOpaqueVisitor(std::marker::PhantomData); - impl Visitor for WrapperKeepOpaqueVisitor { - type Value<'scale, 'info> = WrapperKeepOpaque; - type Error = scale_decode::Error; - fn visit_composite<'scale, 'info>( - self, - value: &mut scale_decode::visitor::types::Composite<'scale, 'info>, - _type_id: scale_decode::visitor::TypeId, - ) -> Result, Self::Error> { - use scale_decode::error::{Error, ErrorKind}; - if value.path().ident().as_deref() != Some("WrapperKeepOpaque") { - return Err( - Error::custom_str( - "Type to decode is not 'WrapperTypeKeepOpaque'", - ), - ); - } - if value.remaining() != 2 { - return Err( - Error::new(ErrorKind::WrongLength { - actual_len: value.remaining(), - expected_len: 2, - }), - ); - } - let Compact(len) = value - .decode_item(Compact::::into_visitor()) - .expect("length checked")?; - let field = value.next().expect("length checked")?; - if field.bytes().len() != len as usize { - return Err( - Error::custom_str( - "WrapperTypeKeepOpaque compact encoded length doesn't line up with encoded byte len", - ), - ); - } - Ok(WrapperKeepOpaque { - data: field.bytes().to_vec(), - _phantom: PhantomDataSendSync::new(), - }) - } - } - impl IntoVisitor for WrapperKeepOpaque { - type Visitor = WrapperKeepOpaqueVisitor; - fn into_visitor() -> Self::Visitor { - WrapperKeepOpaqueVisitor(std::marker::PhantomData) - } - } - } - use crate::error::RpcError; - use crate::Error; - use codec::{Compact, Decode, Encode}; - use derivative::Derivative; - use url::Url; - pub use account_id::AccountId32; - pub use era::Era; - pub use multi_address::MultiAddress; - pub use multi_signature::MultiSignature; - pub use static_type::Static; - pub use unchecked_extrinsic::UncheckedExtrinsic; - pub use wrapper_opaque::WrapperKeepOpaque; - #[doc(hidden)] - pub use primitive_types::{H160, H256, H512}; - /// Wraps an already encoded byte vector, prevents being encoded as a raw byte vector as part of - /// the transaction payload - pub struct Encoded(pub Vec); - #[automatically_derived] - impl ::core::clone::Clone for Encoded { - #[inline] - fn clone(&self) -> Encoded { - Encoded(::core::clone::Clone::clone(&self.0)) - } - } - #[automatically_derived] - impl ::core::fmt::Debug for Encoded { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Encoded", &&self.0) - } - } - #[automatically_derived] - impl ::core::cmp::Eq for Encoded { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq>; - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for Encoded {} - #[automatically_derived] - impl ::core::cmp::PartialEq for Encoded { - #[inline] - fn eq(&self, other: &Encoded) -> bool { - self.0 == other.0 - } - } - impl codec::Encode for Encoded { - fn encode(&self) -> Vec { - self.0.to_owned() - } - } - /// Decodes a compact encoded value from the beginning of the provided bytes, - /// returning the value and any remaining bytes. - pub(crate) fn strip_compact_prefix( - bytes: &[u8], - ) -> Result<(u64, &[u8]), codec::Error> { - let cursor = &mut &*bytes; - let val = >::decode(cursor)?; - Ok((val.0, *cursor)) - } - /// A URL is considered secure if it uses a secure scheme ("https" or "wss") or is referring to localhost. - /// - /// Returns an error if the the string could not be parsed into a URL. - pub fn url_is_secure(url: &str) -> Result { - let url = Url::parse(url) - .map_err(|e| Error::Rpc(RpcError::ClientError(Box::new(e))))?; - let secure_scheme = url.scheme() == "https" || url.scheme() == "wss"; - let is_localhost = url - .host() - .is_some_and(|e| match e { - url::Host::Domain(e) => e == "localhost", - url::Host::Ipv4(e) => e.is_loopback(), - url::Host::Ipv6(e) => e.is_loopback(), - }); - Ok(secure_scheme || is_localhost) - } - /// Validates, that the given Url is secure ("https" or "wss" scheme) or is referring to localhost. - pub fn validate_url_is_secure(url: &str) -> Result<(), Error> { - if !url_is_secure(url)? { - Err(Error::Rpc(crate::error::RpcError::InsecureUrl(url.into()))) - } else { - Ok(()) - } - } - /// A version of [`std::marker::PhantomData`] that is also Send and Sync (which is fine - /// because regardless of the generic param, it is always possible to Send + Sync this - /// 0 size type). - #[derivative( - Clone(bound = ""), - PartialEq(bound = ""), - Debug(bound = ""), - Eq(bound = ""), - Default(bound = ""), - Hash(bound = "") - )] - #[scale_info(skip_type_params(T))] - #[doc(hidden)] - pub struct PhantomDataSendSync(core::marker::PhantomData); - #[allow(unused_qualifications)] - impl ::std::clone::Clone for PhantomDataSendSync { - fn clone(&self) -> Self { - match *self { - PhantomDataSendSync(ref __arg_0) => { - PhantomDataSendSync((*__arg_0).clone()) - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::fmt::Debug for PhantomDataSendSync { - fn fmt(&self, __f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - PhantomDataSendSync(ref __arg_0) => { - let mut __debug_trait_builder = __f - .debug_tuple("PhantomDataSendSync"); - let _ = __debug_trait_builder.field(&&(*__arg_0)); - __debug_trait_builder.finish() - } - } - } - } - #[allow(unused_qualifications)] - impl ::std::default::Default for PhantomDataSendSync { - fn default() -> Self { - PhantomDataSendSync(::std::default::Default::default()) - } - } - #[allow(unused_qualifications)] - impl ::std::cmp::Eq for PhantomDataSendSync {} - #[allow(unused_qualifications)] - impl ::std::hash::Hash for PhantomDataSendSync { - fn hash<__HT>(&self, __state: &mut __HT) - where - __HT: ::std::hash::Hasher, - { - match *self { - PhantomDataSendSync(ref __arg_0) => { - ::std::hash::Hash::hash(&(*__arg_0), __state); - } - } - } - } - #[allow(unused_qualifications)] - #[allow(clippy::unneeded_field_pattern)] - impl ::std::cmp::PartialEq for PhantomDataSendSync { - fn eq(&self, other: &Self) -> bool { - true - && match *self { - PhantomDataSendSync(ref __self_0) => { - match *other { - PhantomDataSendSync(ref __other_0) => { - true && &(*__self_0) == &(*__other_0) - } - } - } - } - } - } - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Encode for PhantomDataSendSync - where - core::marker::PhantomData: ::codec::Encode, - core::marker::PhantomData: ::codec::Encode, - { - fn size_hint(&self) -> usize { - ::codec::Encode::size_hint(&&self.0) - } - fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>( - &self, - __codec_dest_edqy: &mut __CodecOutputEdqy, - ) { - ::codec::Encode::encode_to(&&self.0, __codec_dest_edqy) - } - fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> { - ::codec::Encode::encode(&&self.0) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::codec::Encode::using_encoded(&&self.0, f) - } - } - #[automatically_derived] - impl ::codec::EncodeLike for PhantomDataSendSync - where - core::marker::PhantomData: ::codec::Encode, - core::marker::PhantomData: ::codec::Encode, - {} - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::codec::Decode for PhantomDataSendSync - where - core::marker::PhantomData: ::codec::Decode, - core::marker::PhantomData: ::codec::Decode, - { - fn decode<__CodecInputEdqy: ::codec::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok( - PhantomDataSendSync::< - T, - >({ - let __codec_res_edqy = as ::codec::Decode>::decode(__codec_input_edqy); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `PhantomDataSendSync.0`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }), - ) - } - } - }; - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::scale_info::TypeInfo for PhantomDataSendSync - where - core::marker::PhantomData: ::scale_info::TypeInfo + 'static, - T: 'static, - { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "PhantomDataSendSync", - "subxt::utils", - &[], - ), - ) - .type_params( - <[_]>::into_vec( - #[rustc_box] - ::alloc::boxed::Box::new([ - ::scale_info::TypeParameter::new( - "T", - ::core::option::Option::None, - ), - ]), - ), - ) - .docs( - &[ - "A version of [`std::marker::PhantomData`] that is also Send and Sync (which is fine", - "because regardless of the generic param, it is always possible to Send + Sync this", - "0 size type).", - ], - ) - .composite( - ::scale_info::build::Fields::unnamed() - .field(|f| { - f - .ty::>() - .type_name("core::marker::PhantomData") - }), - ) - } - } - }; - impl PhantomDataSendSync { - pub(crate) fn new() -> Self { - Self(core::marker::PhantomData) - } - } - unsafe impl Send for PhantomDataSendSync {} - unsafe impl Sync for PhantomDataSendSync {} - /// This represents a key-value collection and is SCALE compatible - /// with collections like BTreeMap. This has the same type params - /// as `BTreeMap` which allows us to easily swap the two during codegen. - pub type KeyedVec = Vec<(K, V)>; -} -#[macro_use] -mod macros { - pub(crate) use { - cfg_feature, cfg_jsonrpsee, cfg_reconnecting_rpc_client, cfg_substrate_compat, - cfg_unstable_light_client, - }; - #[allow(unused)] - pub(crate) use {cfg_jsonrpsee_native, cfg_jsonrpsee_web}; -} -pub use crate::{ - client::{OfflineClient, OnlineClient}, - config::{Config, PolkadotConfig, SubstrateConfig}, - error::Error, metadata::Metadata, -}; -/// Re-export external crates that are made use of in the subxt API. -pub mod ext { - pub use codec; - pub use frame_metadata; - pub use futures; - pub use scale_bits; - pub use scale_decode; - pub use scale_encode; - pub use scale_value; -} -/// Generate a strongly typed API for interacting with a Substrate runtime from its metadata. -/// -/// # Metadata -/// -/// First, you'll need to get hold of some metadata for the node you'd like to interact with. One -/// way to do this is by using the `subxt` CLI tool: -/// -/// ```bash -/// # Install the CLI tool: -/// cargo install subxt-cli -/// # Use it to download metadata (in this case, from a node running locally) -/// subxt metadata > polkadot_metadata.scale -/// ``` -/// -/// Run `subxt metadata --help` for more options. -/// -/// # Basic usage -/// -/// Annotate a Rust module with the `subxt` attribute referencing the aforementioned metadata file. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// )] -/// mod polkadot {} -/// ``` -/// -/// The `subxt` macro will populate the annotated module with all of the methods and types required -/// for interacting with the runtime that the metadata is in via Subxt. -/// -/// # Configuration -/// -/// This macro supports a number of attributes to configure what is generated: -/// -/// ## `crate = "..."` -/// -/// Use this attribute to specify a custom path to the `subxt` crate: -/// -/// ```rust -/// # pub extern crate subxt; -/// # pub mod path { pub mod to { pub use subxt; } } -/// # fn main() {} -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// crate = "crate::path::to::subxt" -/// )] -/// mod polkadot {} -/// ``` -/// -/// This is useful if you write a library which uses this macro, but don't want to force users to depend on `subxt` -/// at the top level too. By default the path `::subxt` is used. -/// -/// ## `substitute_type(path = "...", with = "...")` -/// -/// This attribute replaces any reference to the generated type at the path given by `path` with a -/// reference to the path given by `with`. -/// -/// ```rust -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// substitute_type(path = "sp_arithmetic::per_things::Perbill", with = "crate::Foo") -/// )] -/// mod polkadot {} -/// -/// # #[derive( -/// # scale_encode::EncodeAsType, -/// # scale_decode::DecodeAsType, -/// # codec::Encode, -/// # codec::Decode, -/// # Clone, -/// # Debug, -/// # )] -/// // In reality this needs some traits implementing on -/// // it to allow it to be used in place of Perbill: -/// pub struct Foo(u32); -/// # impl codec::CompactAs for Foo { -/// # type As = u32; -/// # fn encode_as(&self) -> &Self::As { -/// # &self.0 -/// # } -/// # fn decode_from(x: Self::As) -> Result { -/// # Ok(Foo(x)) -/// # } -/// # } -/// # impl From> for Foo { -/// # fn from(v: codec::Compact) -> Foo { -/// # v.0 -/// # } -/// # } -/// # fn main() {} -/// ``` -/// -/// If the type you're substituting contains generic parameters, you can "pattern match" on those, and -/// make use of them in the substituted type, like so: -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// substitute_type( -/// path = "sp_runtime::multiaddress::MultiAddress", -/// with = "::subxt::utils::Static<::sp_runtime::MultiAddress>" -/// ) -/// )] -/// mod polkadot {} -/// ``` -/// -/// The above is also an example of using the [`crate::utils::Static`] type to wrap some type which doesn't -/// on it's own implement [`scale_encode::EncodeAsType`] or [`scale_decode::DecodeAsType`], which are required traits -/// for any substitute type to implement by default. -/// -/// ## `derive_for_all_types = "..."` -/// -/// By default, all generated types derive a small set of traits. This attribute allows you to derive additional -/// traits on all generated types: -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// derive_for_all_types = "Eq, PartialEq" -/// )] -/// mod polkadot {} -/// ``` -/// -/// Any substituted types (including the default substitutes) must also implement these traits in order to avoid errors -/// here. -/// -/// ## `derive_for_type(path = "...", derive = "...")` -/// -/// Unlike the above, which derives some trait on every generated type, this attribute allows you to derive traits only -/// for specific types. Note that any types which are used inside the specified type may also need to derive the same traits. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// derive_for_all_types = "Eq, PartialEq", -/// derive_for_type(path = "frame_support::PalletId", derive = "Ord, PartialOrd"), -/// derive_for_type(path = "sp_runtime::ModuleError", derive = "Hash"), -/// )] -/// mod polkadot {} -/// ``` -/// -/// ## `runtime_metadata_insecure_url = "..."` -/// -/// This attribute can be used instead of `runtime_metadata_path` and will tell the macro to download metadata from a node running -/// at the provided URL, rather than a node running locally. This can be useful in CI, but is **not recommended** in production code, -/// since it runs at compile time and will cause compilation to fail if the node at the given address is unavailable or unresponsive. -/// -/// ```rust,ignore -/// #[subxt::subxt( -/// runtime_metadata_insecure_url = "wss://rpc.polkadot.io:443" -/// )] -/// mod polkadot {} -/// ``` -/// -/// ## `generate_docs` -/// -/// By default, documentation is not generated via the macro, since IDEs do not typically make use of it. This attribute -/// forces documentation to be generated, too. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// generate_docs -/// )] -/// mod polkadot {} -/// ``` -/// -/// ## `runtime_types_only` -/// -/// By default, the macro will generate various interfaces to make using Subxt simpler in addition with any types that need -/// generating to make this possible. This attribute makes the codegen only generate the types and not the Subxt interface. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// runtime_types_only -/// )] -/// mod polkadot {} -/// ``` -/// -/// ## `no_default_derives` -/// -/// By default, the macro will add all derives necessary for the generated code to play nicely with Subxt. Adding this attribute -/// removes all default derives. -/// -/// ```rust,no_run -/// #[subxt::subxt( -/// runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale", -/// runtime_types_only, -/// no_default_derives, -/// derive_for_all_types="codec::Encode, codec::Decode" -/// )] -/// mod polkadot {} -/// ``` -/// -/// **Note**: At the moment, you must derive at least one of `codec::Encode` or `codec::Decode` or `scale_encode::EncodeAsType` or -/// `scale_decode::DecodeAsType` (because we add `#[codec(..)]` attributes on some fields/types during codegen), and you must use this -/// feature in conjunction with `runtime_types_only` (or manually specify a bunch of defaults to make codegen work properly when -/// generating the subxt interfaces). -/// -/// ## `unstable_metadata` -/// -/// This attribute works only in combination with `runtime_metadata_insecure_url`. By default, the macro will fetch the latest stable -/// version of the metadata from the target node. This attribute makes the codegen attempt to fetch the unstable version of -/// the metadata first. This is **not recommended** in production code, since the unstable metadata a node is providing is likely -/// to be incompatible with Subxt. -/// -/// ```rust,ignore -/// #[subxt::subxt( -/// runtime_metadata_insecure_url = "wss://rpc.polkadot.io:443", -/// unstable_metadata -/// )] -/// mod polkadot {} -/// ``` -pub use subxt_macro::subxt; diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index ef656073a5..f0058b47f4 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -1,7 +1,7 @@ use super::{ storage_address::StaticStorageKey, utils::{ - hash_contains_unhashed_value, strip_storage_hash_bytes, + strip_storage_hash_bytes, }, }; use crate::{ @@ -120,7 +120,7 @@ pub fn decode_storage_key_from_hash( // Note: This validation check makes sure, only zero-sized types can be decoded from // hashers that do not support reconstruction of a value - if !hash_contains_unhashed_value(hasher) && bytes_decoded > 0 { + if !hasher.hash_contains_unhashed_key() && bytes_decoded > 0 { let ty_name = metadata .types() .resolve(ty_id) @@ -199,6 +199,7 @@ macro_rules! impl_tuples { let mut $iter = self.$n.keys_iter(); )+ + // Note: this functions just flattens the iterators (that might all have different types). std::iter::from_fn(move || { let mut i = 0; loop { diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index 332713e477..e561a87a81 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -64,20 +64,10 @@ pub fn strip_storage_hash_bytes( hash: &mut &[u8], hasher: &StorageHasher, ) -> Result<(), StorageAddressError> { - let bytes_to_strip = match hasher { - StorageHasher::Blake2_128Concat => 16, - StorageHasher::Twox64Concat => 8, - StorageHasher::Blake2_128 => 16, - StorageHasher::Blake2_256 => 32, - StorageHasher::Twox128 => 16, - StorageHasher::Twox256 => 32, - StorageHasher::Identity => 0, - }; - + let bytes_to_strip = hasher.hash_bytes_before_unhashed_key(); if hash.len() < bytes_to_strip { return Err(StorageAddressError::UnexpectedAddressBytes); } - *hash = &hash[bytes_to_strip..]; Ok(()) } From 9c27b475490475ce1b07b71357fb40e50b300c96 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Mon, 26 Feb 2024 16:25:41 +0100 Subject: [PATCH 23/39] codegen adjustments --- codegen/src/api/storage.rs | 70 +++++++++++++++---- codegen/src/error.rs | 8 +-- subxt/src/storage/mod.rs | 5 +- subxt/src/storage/storage_address.rs | 25 ------- subxt/src/storage/storage_key.rs | 45 ++++++++++-- subxt/src/storage/utils.rs | 12 +--- .../src/full_client/codegen/polkadot.rs | 22 +++--- .../src/full_client/storage/mod.rs | 6 +- 8 files changed, 108 insertions(+), 85 deletions(-) diff --git a/codegen/src/api/storage.rs b/codegen/src/api/storage.rs index 1329b46928..e6dcac5f43 100644 --- a/codegen/src/api/storage.rs +++ b/codegen/src/api/storage.rs @@ -173,6 +173,10 @@ fn generate_storage_entry_fns( StorageEntryModifier::Optional => quote!(()), }; + // Note: putting `#crate_path::storage::address::StaticStorageKey` into this variable is necessary + // to get the line width below a certain limit. If not done, rustfmt will refuse to format the following big expression. + // for more information see [this post](https://users.rust-lang.org/t/rustfmt-silently-fails-to-work/75485/4). + let static_storage_key: TokenStream = quote!(#crate_path::storage::address::StaticStorageKey); let all_fns = (0..=keys.len()).map(|n_keys| { let keys_slice = &keys[..n_keys]; let (fn_name, is_fetchable, is_iterable) = if n_keys == keys.len() { @@ -186,29 +190,65 @@ fn generate_storage_entry_fns( }; (fn_name, false, true) }; - let is_fetchable_type = is_fetchable.then_some(quote!(#crate_path::storage::address::Yes)).unwrap_or(quote!(())); - let is_iterable_type = is_iterable.then_some(quote!(#crate_path::storage::address::Yes)).unwrap_or(quote!(())); - let (keys, keys_type) = match keys_slice.len(){ - 0 => (quote!( () ), quote!( () )), + let is_fetchable_type = is_fetchable + .then_some(quote!(#crate_path::storage::address::Yes)) + .unwrap_or(quote!(())); + let is_iterable_type = is_iterable + .then_some(quote!(#crate_path::storage::address::Yes)) + .unwrap_or(quote!(())); + + let (keys, keys_type) = match keys_slice.len() { + 0 => (quote!(()), quote!(())), 1 => { - let arg_name = &keys_slice[0].arg_name; - let keys = quote!( #crate_path::storage::address::StaticStorageKey::new(#arg_name.borrow()) ); - let path = &keys_slice[0].alias_type_path; - let path = quote!( #crate_path::storage::address::StaticStorageKey<#path> ); - (keys, path) + let key = &keys_slice[0]; + if key.hasher.hash_contains_unhashed_key() { + let arg = &key.arg_name; + let keys = quote!(#static_storage_key::new(#arg.borrow())); + let path = &key.alias_type_path; + let path = quote!(#static_storage_key<#path>); + (keys, path) + } else { + (quote!(()), quote!(())) + } } - _ => { - let keys_iter = keys_slice.iter().map(|MapEntryKey{arg_name, ..}| quote!( #crate_path::storage::address::StaticStorageKey::new(#arg_name.borrow()) )); + _ => { + let keys_iter = keys_slice.iter().map( + |MapEntryKey { + arg_name, hasher, .. + }| { + if hasher.hash_contains_unhashed_key() { + quote!( #static_storage_key::new(#arg_name.borrow()) ) + } else { + quote!(()) + } + }, + ); let keys = quote!( (#(#keys_iter,)*) ); - let paths_iter = keys_slice.iter().map(|MapEntryKey{alias_type_path, ..}| quote!( #crate_path::storage::address::StaticStorageKey<#alias_type_path> ) ); + let paths_iter = keys_slice.iter().map( + |MapEntryKey { + alias_type_path, + hasher, + .. + }| { + if hasher.hash_contains_unhashed_key() { + quote!( #static_storage_key<#alias_type_path> ) + } else { + quote!(()) + } + }, + ); let paths = quote!( (#(#paths_iter,)*) ); (keys, paths) } }; - let key_args = keys_slice.iter().map(|MapEntryKey{arg_name, alias_type_path, ..}| { - quote!( #arg_name: impl ::std::borrow::Borrow<#alias_type_path> ) - }); + let key_args = keys_slice.iter().map( + |MapEntryKey { + arg_name, + alias_type_path, + .. + }| quote!( #arg_name: impl ::std::borrow::Borrow<#alias_type_path> ), + ); quote!( #docs diff --git a/codegen/src/error.rs b/codegen/src/error.rs index 1414961cf6..b4908006b9 100644 --- a/codegen/src/error.rs +++ b/codegen/src/error.rs @@ -39,14 +39,10 @@ pub enum CodegenError { #[error("Call variant for type {0} must have all named fields. Make sure you are providing a valid substrate-based metadata")] InvalidCallVariant(u32), /// Type should be an variant/enum. - #[error( - "{0} type should be an variant/enum type. Make sure you are providing a valid substrate-based metadata" - )] + #[error("{0} type should be an variant/enum type. Make sure you are providing a valid substrate-based metadata")] InvalidType(String), /// Extrinsic call type could not be found. - #[error( - "Extrinsic call type could not be found. Make sure you are providing a valid substrate-based metadata" - )] + #[error("Extrinsic call type could not be found. Make sure you are providing a valid substrate-based metadata")] MissingCallType, /// There are too many or too few hashers. #[error("Could not Generate functions for storage entry {storage_entry_name}. There are {key_count} keys, but only {hasher_count} hashers. The number of hashers must equal the number of keys or be exactly 1.")] diff --git a/subxt/src/storage/mod.rs b/subxt/src/storage/mod.rs index f1e3b706f9..5cb96f4726 100644 --- a/subxt/src/storage/mod.rs +++ b/subxt/src/storage/mod.rs @@ -18,9 +18,8 @@ pub use storage_type::{Storage, StorageKeyValuePair}; /// Types representing an address which describes where a storage /// entry lives and how to properly decode it. pub mod address { - pub use super::storage_address::{ - dynamic, Address, DynamicAddress, StaticStorageKey, StorageAddress, Yes, - }; + pub use super::storage_address::{dynamic, Address, DynamicAddress, StorageAddress, Yes}; + pub use super::storage_key::{StaticStorageKey, StorageKey}; } pub use storage_key::StorageKey; diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 20e9cab325..1335b3e05d 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -6,7 +6,6 @@ use crate::{ dynamic::DecodedValueThunk, error::{Error, MetadataError, StorageAddressError}, metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, - utils::{Encoded, Static}, }; use derivative::Derivative; @@ -74,30 +73,6 @@ pub struct Address _marker: std::marker::PhantomData<(ReturnTy, Fetchable, Defaultable, Iterable)>, } -/// A storage key for static encoded values. -/// The original value is only present at construction, but can be decoded from the contained bytes. -#[derive(Derivative)] -#[derivative(Clone(bound = ""), Debug(bound = ""))] -pub struct StaticStorageKey { - pub(super) bytes: Static, - pub(super) _marker: std::marker::PhantomData, -} - -impl StaticStorageKey { - /// Creates a new static storage key - pub fn new(key: &K) -> Self { - StaticStorageKey { - bytes: Static(Encoded(key.encode())), - _marker: std::marker::PhantomData, - } - } - - /// Returns the scale-encoded bytes that make up this key - pub fn bytes(&self) -> &[u8] { - &self.bytes.0 .0 - } -} - /// A typical storage address constructed at runtime rather than via the `subxt` macro; this /// has no restriction on what it can be used for (since we don't statically know). pub type DynamicAddress = Address; diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index f0058b47f4..5b60d49c2d 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -1,9 +1,4 @@ -use super::{ - storage_address::StaticStorageKey, - utils::{ - strip_storage_hash_bytes, - }, -}; +use super::utils::strip_storage_hash_bytes; use crate::{ dynamic::DecodedValueThunk, error::{Error, StorageAddressError}, @@ -13,6 +8,8 @@ use crate::{ use scale_encode::EncodeAsType; use subxt_metadata::StorageHasher; +use derivative::Derivative; + /// This trait should be implemented by anything that can be used as one or multiple storage keys. pub trait StorageKey { /// Iterator over the storage keys, each key implements EncodeAsType to @@ -69,8 +66,42 @@ impl StorageKey for () { } } +/// A storage key for static encoded values. +/// The original value is only present at construction, but can be decoded from the contained bytes. +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Debug(bound = ""))] +pub struct StaticStorageKey { + pub(super) bytes: Static, + pub(super) _marker: std::marker::PhantomData, +} + +impl StaticStorageKey { + /// Creates a new static storage key + pub fn new(key: &K) -> Self { + StaticStorageKey { + bytes: Static(Encoded(key.encode())), + _marker: std::marker::PhantomData, + } + } +} + +impl StaticStorageKey { + /// Decodes the encoded inner bytes into the type `K`. + pub fn decoded(&self) -> Result { + let decoded = K::decode(&mut self.bytes())?; + Ok(decoded) + } +} + +impl StaticStorageKey { + /// Returns the scale-encoded bytes that make up this key + pub fn bytes(&self) -> &[u8] { + &self.bytes.0 .0 + } +} + // Note: The ?Sized bound is necessary to support e.g. `StorageKey<[u8]>`. -impl StorageKey for StaticStorageKey { +impl StorageKey for StaticStorageKey { fn keys_iter(&self) -> impl Iterator { std::iter::once(&self.bytes as &dyn EncodeAsType) } diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index e561a87a81..281d587323 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -56,7 +56,7 @@ pub(crate) fn strip_storage_addess_root_bytes( } /// Strips the first few bytes off a hash to possibly skip to the plan key value, -/// if [`hash_contains_unhashed_value()`] for this StorageHasher. +/// if [`StorageHasher::hash_contains_unhashed_key()`] for this StorageHasher. /// /// Returns `Err(..)` if there are not enough bytes. /// Returns `Ok(())` otherwise @@ -71,13 +71,3 @@ pub fn strip_storage_hash_bytes( *hash = &hash[bytes_to_strip..]; Ok(()) } - -/// This value is contained within the hash for concat-stle hashers -/// ([`StorageHasher::Identity`] or [`StorageHasher::Identity`]) and the -/// identity hash function ([`StorageHasher::Identity`]). -pub fn hash_contains_unhashed_value(hasher: &StorageHasher) -> bool { - matches!( - hasher, - StorageHasher::Blake2_128Concat | StorageHasher::Twox64Concat | StorageHasher::Identity - ) -} diff --git a/testing/integration-tests/src/full_client/codegen/polkadot.rs b/testing/integration-tests/src/full_client/codegen/polkadot.rs index 07d42155b7..8ed90e4873 100644 --- a/testing/integration-tests/src/full_client/codegen/polkadot.rs +++ b/testing/integration-tests/src/full_client/codegen/polkadot.rs @@ -35126,7 +35126,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageKey, + (), types::para_id_affinity::ParaIdAffinity, ::subxt::storage::address::Yes, (), @@ -35135,7 +35135,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "OnDemandAssignmentProvider", "ParaIdAffinity", - ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + (), [ 145u8, 117u8, 2u8, 170u8, 99u8, 68u8, 166u8, 236u8, 247u8, 80u8, 202u8, 87u8, 116u8, 244u8, 218u8, 172u8, 41u8, 187u8, 170u8, 163u8, 187u8, @@ -35231,7 +35231,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageKey, + (), types::core_schedules::CoreSchedules, (), (), @@ -35240,7 +35240,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreSchedules", - ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + (), [ 34u8, 85u8, 91u8, 158u8, 28u8, 200u8, 76u8, 188u8, 253u8, 91u8, 153u8, 42u8, 42u8, 227u8, 119u8, 181u8, 247u8, 44u8, 29u8, 24u8, 128u8, 49u8, @@ -35257,10 +35257,7 @@ pub mod api { _0: impl ::std::borrow::Borrow, _1: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ( - ::subxt::storage::address::StaticStorageKey, - ::subxt::storage::address::StaticStorageKey, - ), + ((), ()), types::core_schedules::CoreSchedules, ::subxt::storage::address::Yes, (), @@ -35269,10 +35266,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreSchedules", - ( - ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), - ::subxt::storage::address::StaticStorageKey::new(_1.borrow()), - ), + ((), ()), [ 34u8, 85u8, 91u8, 158u8, 28u8, 200u8, 76u8, 188u8, 253u8, 91u8, 153u8, 42u8, 42u8, 227u8, 119u8, 181u8, 247u8, 44u8, 29u8, 24u8, 128u8, 49u8, @@ -35312,7 +35306,7 @@ pub mod api { &self, _0: impl ::std::borrow::Borrow, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageKey, + (), types::core_descriptors::CoreDescriptors, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -35321,7 +35315,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "CoretimeAssignmentProvider", "CoreDescriptors", - ::subxt::storage::address::StaticStorageKey::new(_0.borrow()), + (), [ 1u8, 90u8, 208u8, 119u8, 150u8, 241u8, 133u8, 74u8, 22u8, 166u8, 13u8, 7u8, 73u8, 136u8, 105u8, 61u8, 251u8, 245u8, 164u8, 7u8, 45u8, 68u8, diff --git a/testing/integration-tests/src/full_client/storage/mod.rs b/testing/integration-tests/src/full_client/storage/mod.rs index bb2585ef1b..4306424dbf 100644 --- a/testing/integration-tests/src/full_client/storage/mod.rs +++ b/testing/integration-tests/src/full_client/storage/mod.rs @@ -169,8 +169,7 @@ async fn storage_partial_lookup() -> Result<(), subxt::Error> { let mut approvals = Vec::new(); while let Some(Ok(kv)) = results.next().await { assert!(kv.key_bytes.starts_with(&addr_bytes)); - kv.keys - .expect("concat hasher used for approvals, so should be Some(..)"); + assert_eq!(kv.keys, ()); // this just checks this is the unit type. approvals.push(kv.value); } assert_eq!(approvals.len(), assets.len()); @@ -192,8 +191,7 @@ async fn storage_partial_lookup() -> Result<(), subxt::Error> { let mut approvals = Vec::new(); while let Some(Ok(kv)) = results.next().await { assert!(kv.key_bytes.starts_with(&addr_bytes)); - kv.keys - .expect("concat hasher used for approvals, so should be Some(..)"); + assert!(kv.keys.decoded().is_ok()); approvals.push(kv.value); } assert_eq!(approvals.len(), 1); From 4bfaa4c0ab4bed028dbf13ea23dfd4a9288ac27b Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Tue, 27 Feb 2024 09:24:33 +0100 Subject: [PATCH 24/39] fix storage hasher codegen test --- codegen/src/api/storage.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/src/api/storage.rs b/codegen/src/api/storage.rs index e6dcac5f43..f6ecd8861a 100644 --- a/codegen/src/api/storage.rs +++ b/codegen/src/api/storage.rs @@ -330,7 +330,7 @@ mod tests { name, modifier: v15::StorageEntryModifier::Optional, ty: v15::StorageEntryType::Map { - hashers: vec![], + hashers: vec![v15::StorageHasher::Blake2_128Concat], key, value: meta_type::(), }, From bd01aab72634405f0141c5892b535ccb3f2d5b30 Mon Sep 17 00:00:00 2001 From: James Wilson Date: Wed, 28 Feb 2024 14:35:45 +0000 Subject: [PATCH 25/39] Suggestions for storage value decoding (#1457) * Storage decode tweaks * doc tweak * more precise error when leftover or not enough bytes --- codegen/src/api/storage.rs | 6 +- metadata/src/lib.rs | 18 ++- subxt/src/error/mod.rs | 12 +- subxt/src/storage/mod.rs | 3 +- subxt/src/storage/storage_key.rs | 197 +++++++++++++++++------------- subxt/src/storage/storage_type.rs | 14 ++- subxt/src/storage/utils.rs | 42 +------ 7 files changed, 145 insertions(+), 147 deletions(-) diff --git a/codegen/src/api/storage.rs b/codegen/src/api/storage.rs index f6ecd8861a..330843ccf7 100644 --- a/codegen/src/api/storage.rs +++ b/codegen/src/api/storage.rs @@ -201,7 +201,7 @@ fn generate_storage_entry_fns( 0 => (quote!(()), quote!(())), 1 => { let key = &keys_slice[0]; - if key.hasher.hash_contains_unhashed_key() { + if key.hasher.ends_with_key() { let arg = &key.arg_name; let keys = quote!(#static_storage_key::new(#arg.borrow())); let path = &key.alias_type_path; @@ -216,7 +216,7 @@ fn generate_storage_entry_fns( |MapEntryKey { arg_name, hasher, .. }| { - if hasher.hash_contains_unhashed_key() { + if hasher.ends_with_key() { quote!( #static_storage_key::new(#arg_name.borrow()) ) } else { quote!(()) @@ -230,7 +230,7 @@ fn generate_storage_entry_fns( hasher, .. }| { - if hasher.hash_contains_unhashed_key() { + if hasher.ends_with_key() { quote!( #static_storage_key<#alias_type_path> ) } else { quote!(()) diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 0b5db7277c..2f3c6c0000 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -476,14 +476,14 @@ pub enum StorageHasher { } impl StorageHasher { - /// The hash produced by a [`StorageHasher`] has 1 or 2 of the following components: - /// 1. A fixed size hash. (not present for [`StorageHasher::Identity`]) - /// 2. The key that was used as an input to the hasher. (only present for + /// The hash produced by a [`StorageHasher`] can have these two components, in order: + /// + /// 1. A fixed size hash. (not present for [`StorageHasher::Identity`]). + /// 2. The SCALE encoded key that was used as an input to the hasher (only present for /// [`StorageHasher::Twox64Concat`], [`StorageHasher::Blake2_128Concat`] or [`StorageHasher::Identity`]). /// - /// This function returns the number of hash bytes that must be skipped to get to the 2. component, the unhashed key. - /// To check whether or not an unhashed key is contained, see [`StorageHasher::hash_bytes_before_unhashed_key`]. - pub fn hash_bytes_before_unhashed_key(&self) -> usize { + /// This function returns the number of bytes used to represent the first of these. + pub fn len_excluding_key(&self) -> usize { match self { StorageHasher::Blake2_128Concat => 16, StorageHasher::Twox64Concat => 8, @@ -495,10 +495,8 @@ impl StorageHasher { } } - /// Returns if the key a hash was produces for, is contained in the hash itself. - /// If this is `true`, [`StorageHasher::hash_bytes_before_unhashed_key`] can be used, - /// to find the offset of the start byte of the key from the start of the hash bytes. - pub fn hash_contains_unhashed_key(&self) -> bool { + /// Returns true if the key used to produce the hash is appended to the hash itself. + pub fn ends_with_key(&self) -> bool { matches!( self, StorageHasher::Blake2_128Concat | StorageHasher::Twox64Concat | StorageHasher::Identity diff --git a/subxt/src/error/mod.rs b/subxt/src/error/mod.rs index 65b8ffaa57..8fb4d7007f 100644 --- a/subxt/src/error/mod.rs +++ b/subxt/src/error/mod.rs @@ -207,16 +207,20 @@ pub enum StorageAddressError { /// The number of fields in the metadata for this storage entry. fields: usize, }, + /// We weren't given enough bytes to decode the storage address/key. + #[error("Not enough remaining bytes to decode the storage address/key")] + NotEnoughBytes, + /// We have leftover bytes after decoding the storage address. + #[error("We have leftover bytes after decoding the storage address")] + TooManyBytes, /// The bytes of a storage address are not the expected address for decoding the storage keys of the address. - #[error("Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata.")] + #[error("Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata")] UnexpectedAddressBytes, /// An invalid hasher was used to reconstruct a value from a chunk of bytes that is part of a storage address. Hashers where the hash does not contain the original value are invalid for this purpose. - #[error("An invalid hasher was used to reconstruct a value of type {ty_name} (id={ty_id}) from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher")] + #[error("An invalid hasher was used to reconstruct a value with type ID {ty_id} from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher")] HasherCannotReconstructKey { /// Type id of the key's type. ty_id: u32, - /// Type name of the key's type. - ty_name: String, /// The invalid hasher that caused this error. hasher: StorageHasher, }, diff --git a/subxt/src/storage/mod.rs b/subxt/src/storage/mod.rs index 5cb96f4726..98f8365274 100644 --- a/subxt/src/storage/mod.rs +++ b/subxt/src/storage/mod.rs @@ -8,8 +8,7 @@ mod storage_address; mod storage_client; mod storage_key; mod storage_type; - -pub mod utils; +mod utils; pub use storage_client::StorageClient; diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 5b60d49c2d..6c0c8b91f5 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -1,11 +1,12 @@ -use super::utils::strip_storage_hash_bytes; use crate::{ - dynamic::DecodedValueThunk, error::{Error, StorageAddressError}, - metadata::{DecodeWithMetadata, Metadata}, + metadata::Metadata, utils::{Encoded, Static}, }; +use scale_decode::{visitor::IgnoreVisitor, DecodeAsType}; use scale_encode::EncodeAsType; +use scale_info::PortableRegistry; +use scale_value::Value; use subxt_metadata::StorageHasher; use derivative::Derivative; @@ -21,17 +22,20 @@ pub trait StorageKey { // But that plays poorly with the `Flatten` and `Chain` structs. fn keys_len(&self) -> usize; - /// Attempts to decode the StorageKey from a storage address that has been stripped of its root bytes. + /// Attempts to decode the StorageKey given some bytes and a set of hashers and type IDs that they are meant to represent. /// - /// Example: Imagine The `StorageKey` is a tuple (A,B) and the hashers are: [Blake2_128Concat, Twox64Concat]. + /// Example: Imagine The `StorageKey` is a tuple `(A,B)` and the hashers are `[Blake2_128Concat, Twox64Concat]`. /// Then the memory layout of the storage address is: + /// /// ```txt - /// | 8 bytes pallet hash | 8 bytes entry hash | 16 bytes hash of A | ... bytes of A | 8 bytes hash of B | ... bytes of B | + /// | 16 byte hash of A | n bytes for SCALE encoded A | 8 byte hash of B | n bytes for SCALE encoded B | /// ``` - /// `cursor` should point into a region after those first 16 bytes, at the start of a new hash. - /// `hashers_and_ty_ids` should consume all the hashers that have been used for decoding, such that there are less hashers coming to the next key. + /// + /// Implementations of this must advance the `bytes` and `hashers_and_ty_ids` cursors to consume any that they are using, or + /// return an error if they cannot appropriately do so. When a tuple of such implementations is given, each implementation + /// in the tuple receives the remaining un-consumed bytes and hashers from the previous ones. fn decode_from_bytes( - cursor: &mut &[u8], + bytes: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], metadata: &Metadata, ) -> Result @@ -39,7 +43,8 @@ pub trait StorageKey { Self: Sized + 'static; } -/// Implement `StorageKey` for `()` which can be used for keyless storage entries. +/// Implement `StorageKey` for `()` which can be used for keyless storage entries, +/// or to otherwise just ignore some entry. impl StorageKey for () { fn keys_iter(&self) -> impl Iterator { std::iter::empty() @@ -50,18 +55,24 @@ impl StorageKey for () { } fn decode_from_bytes( - _cursor: &mut &[u8], + bytes: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - _metadata: &Metadata, + metadata: &Metadata, ) -> Result { - if hashers_and_ty_ids.is_empty() { - return Err(StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, + // If no hashers, we just do nothing (erroring if ). + let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { + if bytes.is_empty() { + return Ok(()); + } else { + return Err(StorageAddressError::TooManyBytes.into()); } - .into()); - } - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; // Advance cursor by 1 + }; + + // Consume the hash bytes (we don't care about the key output here). + consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, metadata.types())?; + // Advance our hasher cursor as well now that we've used it. + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; + Ok(()) } } @@ -71,8 +82,8 @@ impl StorageKey for () { #[derive(Derivative)] #[derivative(Clone(bound = ""), Debug(bound = ""))] pub struct StaticStorageKey { - pub(super) bytes: Static, - pub(super) _marker: std::marker::PhantomData, + bytes: Static, + _marker: std::marker::PhantomData, } impl StaticStorageKey { @@ -111,7 +122,7 @@ impl StorageKey for StaticStorageKey { } fn decode_from_bytes( - cursor: &mut &[u8], + bytes: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], metadata: &Metadata, ) -> Result @@ -125,53 +136,28 @@ impl StorageKey for StaticStorageKey { } .into()); }; - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; // Advance cursor by 1 - decode_storage_key_from_hash(cursor, hasher, *ty_id, metadata) - } -} -pub fn decode_storage_key_from_hash( - cursor: &mut &[u8], - hasher: &StorageHasher, - ty_id: u32, - metadata: &Metadata, -) -> Result, Error> { - strip_storage_hash_bytes(cursor, hasher)?; - - let bytes = *cursor; - if let Err(err) = scale_decode::visitor::decode_with_visitor( - cursor, - ty_id, - metadata.types(), - scale_decode::visitor::IgnoreVisitor, - ) { - return Err(scale_decode::Error::from(err).into()); + // Advance the bytes cursor, returning any key bytes. + let key_bytes = consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, metadata.types())?; + // Advance the hasher cursor now we've used it. + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; + + // if the hasher had no key appended, we can't decode it into a `StaticStorageKey`. + let Some(key_bytes) = key_bytes else { + return Err(StorageAddressError::HasherCannotReconstructKey { + ty_id: *ty_id, + hasher: *hasher, + } + .into()); + }; + + // Return the key bytes. + let key = StaticStorageKey { + bytes: Static(Encoded(key_bytes.to_vec())), + _marker: std::marker::PhantomData::, + }; + Ok(key) } - let bytes_decoded = bytes.len() - cursor.len(); - - // Note: This validation check makes sure, only zero-sized types can be decoded from - // hashers that do not support reconstruction of a value - if !hasher.hash_contains_unhashed_key() && bytes_decoded > 0 { - let ty_name = metadata - .types() - .resolve(ty_id) - .expect("ty_id is in metadata, because decode_with_visitor did not fail above; qed") - .path - .to_string(); - return Err(StorageAddressError::HasherCannotReconstructKey { - ty_id, - ty_name, - hasher: *hasher, - } - .into()); - }; - - let key_bytes = bytes[..bytes_decoded].to_vec(); - let key = StaticStorageKey { - bytes: Static(Encoded(key_bytes)), - _marker: std::marker::PhantomData::, - }; - Ok(key) } impl StorageKey for Vec { @@ -186,32 +172,67 @@ impl StorageKey for Vec { } fn decode_from_bytes( - cursor: &mut &[u8], + bytes: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], metadata: &Metadata, ) -> Result where Self: Sized + 'static, { - let mut hashers_and_ty_ids_iter = hashers_and_ty_ids.iter(); let mut result: Vec = vec![]; - let mut n = 0; - while !cursor.is_empty() { - let Some((hasher, ty_id)) = hashers_and_ty_ids_iter.next() else { - // Still bytes left, but no hashers and type ids anymore to pull from: this is an unexpected error. - return Err(StorageAddressError::UnexpectedAddressBytes.into()); - }; - strip_storage_hash_bytes(cursor, hasher)?; - let decoded = DecodedValueThunk::decode_with_metadata(cursor, *ty_id, metadata)?; - let value = decoded.to_value()?; - result.push(value.remove_context()); - n += 1; + for (hasher, ty_id) in hashers_and_ty_ids.iter() { + match consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, metadata.types())? { + Some(value_bytes) => { + let value = + Value::decode_as_type(&mut &*value_bytes, *ty_id, metadata.types())?; + result.push(value.remove_context()); + } + None => { + result.push(Value::unnamed_composite([])); + } + } + *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; // Advance by 1 each time. + } + + // We've consumed all of the hashers, so we expect to also consume all of the bytes: + if !bytes.is_empty() { + return Err(StorageAddressError::TooManyBytes.into()); } - *hashers_and_ty_ids = &hashers_and_ty_ids[n..]; // Advance cursor by n + Ok(result) } } +// Skip over the hash bytes (including any key at the end), returning bytes +// representing the key if one exists, or None if the hasher has no key appended. +fn consume_hash_returning_key_bytes<'a>( + bytes: &mut &'a [u8], + hasher: StorageHasher, + ty_id: u32, + types: &PortableRegistry, +) -> Result, Error> { + // Strip the bytes off for the actual hash, consuming them. + let bytes_to_strip = hasher.len_excluding_key(); + if bytes.len() < bytes_to_strip { + return Err(StorageAddressError::NotEnoughBytes.into()); + } + *bytes = &bytes[bytes_to_strip..]; + + // Now, find the bytes representing the key, consuming them. + let before_key = *bytes; + if hasher.ends_with_key() { + scale_decode::visitor::decode_with_visitor(bytes, ty_id, types, IgnoreVisitor) + .map_err(|err| Error::Decode(err.into()))?; + + // Return the key bytes, having advanced the input cursor past them. + let key_bytes = &before_key[before_key.len() - bytes.len()..]; + Ok(Some(key_bytes)) + } else { + // There are no key bytes, so return None. + Ok(None) + } +} + /// Generates StorageKey implementations for tuples, e.g. /// ```rs,norun /// impl StorageKey for (StorageKey, StorageKey) { @@ -278,11 +299,11 @@ macro_rules! impl_tuples { #[rustfmt::skip] const _: () = { - impl_tuples!(A iter_a 0, B iter_ab 1); - impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2); - impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3); - impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3, E iter_e 4); - impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5); - impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6); - impl_tuples!(A iter_a 0, B iter_ab 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6, H iter_h 7); + impl_tuples!(A iter_a 0, B iter_b 1); + impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2); + impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3); + impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4); + impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5); + impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6); + impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6, H iter_h 7); }; diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index 20650a817e..34353f478e 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -3,7 +3,6 @@ // see LICENSE for license details. use super::storage_address::{StorageAddress, Yes}; -use super::utils::strip_storage_addess_root_bytes; use super::StorageKey; use crate::{ @@ -311,7 +310,8 @@ where } } -pub(crate) fn storage_hasher_type_id_pairs( +/// Return a vec of hashers and the associated type IDs for the keys that are hashed. +fn storage_hasher_type_id_pairs( entry: &StorageEntryType, metadata: &Metadata, ) -> Result, Error> { @@ -357,6 +357,16 @@ pub(crate) fn storage_hasher_type_id_pairs( } } +/// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. +fn strip_storage_addess_root_bytes(address_bytes: &mut &[u8]) -> Result<(), StorageAddressError> { + if address_bytes.len() >= 16 { + *address_bytes = &address_bytes[16..]; + Ok(()) + } else { + Err(StorageAddressError::UnexpectedAddressBytes) + } +} + /// A pair of keys and values together with all the bytes that make up the storage address. /// `keys` is `None` if non-concat hashers are used. In this case the keys could not be extracted back from the key_bytes. #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index 281d587323..9dda39d7af 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -6,17 +6,12 @@ //! aren't things that should ever be overridden, and so don't exist on //! the trait itself. -use subxt_metadata::StorageHasher; - use super::StorageAddress; -use crate::{ - error::{Error, StorageAddressError}, - metadata::Metadata, -}; +use crate::{error::Error, metadata::Metadata}; /// Return the root of a given [`StorageAddress`]: hash the pallet name and entry name /// and append those bytes to the output. -pub(crate) fn write_storage_address_root_bytes( +pub fn write_storage_address_root_bytes( addr: &Address, out: &mut Vec, ) { @@ -26,7 +21,7 @@ pub(crate) fn write_storage_address_root_bytes( /// Outputs the [`storage_address_root_bytes`] as well as any additional bytes that represent /// a lookup in a storage map at that location. -pub(crate) fn storage_address_bytes( +pub fn storage_address_bytes( addr: &Address, metadata: &Metadata, ) -> Result, Error> { @@ -37,37 +32,8 @@ pub(crate) fn storage_address_bytes( } /// Outputs a vector containing the bytes written by [`write_storage_address_root_bytes`]. -pub(crate) fn storage_address_root_bytes(addr: &Address) -> Vec { +pub fn storage_address_root_bytes(addr: &Address) -> Vec { let mut bytes = Vec::new(); write_storage_address_root_bytes(addr, &mut bytes); bytes } - -/// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. -pub(crate) fn strip_storage_addess_root_bytes( - address_bytes: &mut &[u8], -) -> Result<(), StorageAddressError> { - if address_bytes.len() >= 16 { - *address_bytes = &address_bytes[16..]; - Ok(()) - } else { - Err(StorageAddressError::UnexpectedAddressBytes) - } -} - -/// Strips the first few bytes off a hash to possibly skip to the plan key value, -/// if [`StorageHasher::hash_contains_unhashed_key()`] for this StorageHasher. -/// -/// Returns `Err(..)` if there are not enough bytes. -/// Returns `Ok(())` otherwise -pub fn strip_storage_hash_bytes( - hash: &mut &[u8], - hasher: &StorageHasher, -) -> Result<(), StorageAddressError> { - let bytes_to_strip = hasher.hash_bytes_before_unhashed_key(); - if hash.len() < bytes_to_strip { - return Err(StorageAddressError::UnexpectedAddressBytes); - } - *hash = &hash[bytes_to_strip..]; - Ok(()) -} From a284ed8537f5483b56492830ee47a3026bca437b Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Wed, 28 Feb 2024 13:44:52 +0100 Subject: [PATCH 26/39] integrate nits from PR --- subxt/src/storage/storage_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 6c0c8b91f5..d2bbf45b1b 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -234,7 +234,7 @@ fn consume_hash_returning_key_bytes<'a>( } /// Generates StorageKey implementations for tuples, e.g. -/// ```rs,norun +/// ```rs,no_run /// impl StorageKey for (StorageKey, StorageKey) { /// fn keys_iter(&self) -> impl ExactSizeIterator { /// let arr = [&self.0 as &dyn EncodeAsType, &self.1 as &dyn EncodeAsType]; From 5a68e8e3f572484d62b18af06c7809223c20968f Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Wed, 28 Feb 2024 19:01:45 +0100 Subject: [PATCH 27/39] add fuzztest for storage keys, fix decoding bug --- subxt/src/storage/storage_key.rs | 152 +++++++++++++++++++++++++++--- subxt/src/storage/storage_type.rs | 2 +- 2 files changed, 140 insertions(+), 14 deletions(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index d2bbf45b1b..e1af361c72 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -37,7 +37,7 @@ pub trait StorageKey { fn decode_from_bytes( bytes: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, + types: &PortableRegistry, ) -> Result where Self: Sized + 'static; @@ -57,7 +57,7 @@ impl StorageKey for () { fn decode_from_bytes( bytes: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, + types: &PortableRegistry, ) -> Result { // If no hashers, we just do nothing (erroring if ). let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { @@ -69,7 +69,7 @@ impl StorageKey for () { }; // Consume the hash bytes (we don't care about the key output here). - consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, metadata.types())?; + consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, types)?; // Advance our hasher cursor as well now that we've used it. *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; @@ -124,7 +124,7 @@ impl StorageKey for StaticStorageKey { fn decode_from_bytes( bytes: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, + types: &PortableRegistry, ) -> Result where Self: Sized + 'static, @@ -138,7 +138,7 @@ impl StorageKey for StaticStorageKey { }; // Advance the bytes cursor, returning any key bytes. - let key_bytes = consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, metadata.types())?; + let key_bytes = consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, types)?; // Advance the hasher cursor now we've used it. *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; @@ -174,17 +174,16 @@ impl StorageKey for Vec { fn decode_from_bytes( bytes: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, + types: &PortableRegistry, ) -> Result where Self: Sized + 'static, { let mut result: Vec = vec![]; for (hasher, ty_id) in hashers_and_ty_ids.iter() { - match consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, metadata.types())? { + match consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, types)? { Some(value_bytes) => { - let value = - Value::decode_as_type(&mut &*value_bytes, *ty_id, metadata.types())?; + let value = Value::decode_as_type(&mut &*value_bytes, *ty_id, types)?; result.push(value.remove_context()); } None => { @@ -223,9 +222,9 @@ fn consume_hash_returning_key_bytes<'a>( if hasher.ends_with_key() { scale_decode::visitor::decode_with_visitor(bytes, ty_id, types, IgnoreVisitor) .map_err(|err| Error::Decode(err.into()))?; - // Return the key bytes, having advanced the input cursor past them. - let key_bytes = &before_key[before_key.len() - bytes.len()..]; + let key_bytes = &before_key[..before_key.len() - bytes.len()]; + Ok(Some(key_bytes)) } else { // There are no key bytes, so return None. @@ -278,7 +277,7 @@ macro_rules! impl_tuples { fn decode_from_bytes( cursor: &mut &[u8], hashers_and_ty_ids: &mut &[(StorageHasher, u32)], - metadata: &Metadata, + types: &PortableRegistry, ) -> Result where Self: Sized + 'static, @@ -287,7 +286,7 @@ macro_rules! impl_tuples { let tuple : Self = ( $( { let key = - $ty::decode_from_bytes(cursor, hashers_and_ty_ids, metadata)?; + $ty::decode_from_bytes(cursor, hashers_and_ty_ids, types)?; key }, )+); @@ -307,3 +306,130 @@ const _: () = { impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6); impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6, H iter_h 7); }; + +#[cfg(test)] +mod tests { + + use codec::Encode; + use scale_info::{meta_type, PortableRegistry, Registry, TypeInfo}; + use subxt_metadata::StorageHasher; + + use crate::{metadata::EncodeWithMetadata, utils::Era}; + + use super::{StaticStorageKey, StorageKey}; + + struct KeyBuilder { + registry: Registry, + bytes: Vec, + hashers_and_ty_ids: Vec<(StorageHasher, u32)>, + } + + impl KeyBuilder { + fn new() -> KeyBuilder { + KeyBuilder { + registry: Registry::new(), + bytes: vec![], + hashers_and_ty_ids: vec![], + } + } + + fn add(mut self, value: T, hasher: StorageHasher) -> Self { + let id = self.registry.register_type(&meta_type::()).id; + + self.hashers_and_ty_ids.push((hasher, id)); + for i in 0..hasher.len_excluding_key() { + self.bytes.push(0); + } + value.encode_to(&mut self.bytes); + self + } + + fn build(self) -> (PortableRegistry, Vec, Vec<(StorageHasher, u32)>) { + (self.registry.into(), self.bytes, self.hashers_and_ty_ids) + } + } + + #[test] + fn storage_key_decoding_fuzz() { + let hashers = [ + StorageHasher::Blake2_128, + StorageHasher::Blake2_128Concat, + StorageHasher::Blake2_256, + StorageHasher::Identity, + StorageHasher::Twox128, + StorageHasher::Twox256, + StorageHasher::Twox64Concat, + ]; + + let key_preserving_hashers = [ + StorageHasher::Blake2_128Concat, + StorageHasher::Identity, + StorageHasher::Twox64Concat, + ]; + + type T4A = ( + (), + StaticStorageKey, + StaticStorageKey, + StaticStorageKey, + ); + type T4B = ( + (), + (StaticStorageKey, StaticStorageKey), + StaticStorageKey, + ); + type T4C = ( + ((), StaticStorageKey), + (StaticStorageKey, StaticStorageKey), + ); + + let era = Era::Immortal; + for h0 in hashers { + for h1 in key_preserving_hashers { + for h2 in key_preserving_hashers { + for h3 in key_preserving_hashers { + let (types, bytes, hashers_and_ty_ids) = KeyBuilder::new() + .add((), h0) + .add(13u32, h1) + .add("Hello", h2) + .add(era, h3) + .build(); + + let keys_a = T4A::decode_from_bytes( + &mut &bytes[..], + &mut &hashers_and_ty_ids[..], + &types, + ) + .unwrap(); + + let keys_b = T4B::decode_from_bytes( + &mut &bytes[..], + &mut &hashers_and_ty_ids[..], + &types, + ) + .unwrap(); + + + let keys_c = T4C::decode_from_bytes( + &mut &bytes[..], + &mut &hashers_and_ty_ids[..], + &types, + ) + .unwrap(); + + assert_eq!(keys_a.1.decoded().unwrap(), 13); + assert_eq!(keys_b.1 .0.decoded().unwrap(), 13); + assert_eq!(keys_c.0 .1.decoded().unwrap(), 13); + + assert_eq!(keys_a.2.decoded().unwrap(), "Hello"); + assert_eq!(keys_b.1 .1.decoded().unwrap(), "Hello"); + assert_eq!(keys_c.1 .0.decoded().unwrap(), "Hello"); + assert_eq!(keys_a.3.decoded().unwrap(), era); + assert_eq!(keys_b.2.decoded().unwrap(), era); + assert_eq!(keys_c.1 .1.decoded().unwrap(), era); + } + } + } + } + } +} diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index 34353f478e..8ba697cc67 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -259,7 +259,7 @@ where let keys = ::decode_from_bytes( cursor, &mut &hasher_type_id_pairs[..], - &metadata, + metadata.types(), )?; Ok(StorageKeyValuePair::
{ keys, From e4195b2618e90727a5ca228d8a2421629e1e3ec2 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Wed, 28 Feb 2024 19:10:24 +0100 Subject: [PATCH 28/39] clippy and fmt --- subxt/src/storage/storage_key.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index e1af361c72..3b5a050db3 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -1,6 +1,5 @@ use crate::{ error::{Error, StorageAddressError}, - metadata::Metadata, utils::{Encoded, Static}, }; use scale_decode::{visitor::IgnoreVisitor, DecodeAsType}; @@ -409,7 +408,6 @@ mod tests { ) .unwrap(); - let keys_c = T4C::decode_from_bytes( &mut &bytes[..], &mut &hashers_and_ty_ids[..], From 97962ee5b448943660571b51c94838eba015ddb9 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Thu, 29 Feb 2024 10:26:02 +0100 Subject: [PATCH 29/39] clippy --- subxt/src/storage/storage_key.rs | 4 ++-- testing/integration-tests/src/full_client/storage/mod.rs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 3b5a050db3..3206f70982 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -313,7 +313,7 @@ mod tests { use scale_info::{meta_type, PortableRegistry, Registry, TypeInfo}; use subxt_metadata::StorageHasher; - use crate::{metadata::EncodeWithMetadata, utils::Era}; + use crate::utils::Era; use super::{StaticStorageKey, StorageKey}; @@ -336,7 +336,7 @@ mod tests { let id = self.registry.register_type(&meta_type::()).id; self.hashers_and_ty_ids.push((hasher, id)); - for i in 0..hasher.len_excluding_key() { + for _i in 0..hasher.len_excluding_key() { self.bytes.push(0); } value.encode_to(&mut self.bytes); diff --git a/testing/integration-tests/src/full_client/storage/mod.rs b/testing/integration-tests/src/full_client/storage/mod.rs index 4306424dbf..f281314f45 100644 --- a/testing/integration-tests/src/full_client/storage/mod.rs +++ b/testing/integration-tests/src/full_client/storage/mod.rs @@ -169,7 +169,6 @@ async fn storage_partial_lookup() -> Result<(), subxt::Error> { let mut approvals = Vec::new(); while let Some(Ok(kv)) = results.next().await { assert!(kv.key_bytes.starts_with(&addr_bytes)); - assert_eq!(kv.keys, ()); // this just checks this is the unit type. approvals.push(kv.value); } assert_eq!(approvals.len(), assets.len()); From 9b33cbceb31f41eeb4ff9b84ba33647001540a95 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Thu, 29 Feb 2024 17:52:00 +0100 Subject: [PATCH 30/39] Niklas Suggestions --- codegen/src/error.rs | 2 +- subxt/src/storage/storage_address.rs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/codegen/src/error.rs b/codegen/src/error.rs index b4908006b9..4a77d247af 100644 --- a/codegen/src/error.rs +++ b/codegen/src/error.rs @@ -45,7 +45,7 @@ pub enum CodegenError { #[error("Extrinsic call type could not be found. Make sure you are providing a valid substrate-based metadata")] MissingCallType, /// There are too many or too few hashers. - #[error("Could not Generate functions for storage entry {storage_entry_name}. There are {key_count} keys, but only {hasher_count} hashers. The number of hashers must equal the number of keys or be exactly 1.")] + #[error("Could not generate functions for storage entry {storage_entry_name}. There are {key_count} keys, but only {hasher_count} hashers. The number of hashers must equal the number of keys or be exactly 1.")] InvalidStorageHasherCount { /// The name of the storage entry storage_entry_name: String, diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 1335b3e05d..5facb025b6 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -192,9 +192,10 @@ where // If the key is a tuple, we encode each value to the corresponding tuple type. // If the key is not a tuple, encode a single value to the key type. - let type_ids = match &ty.type_def { - TypeDef::Tuple(tuple) => either::Either::Left(tuple.fields.iter().map(|f| f.id)), - _other => either::Either::Right(std::iter::once(*key_ty)), + let type_ids = if let TypeDef::Tuple(tuple) = &ty.type_def { + either::Either::Left(tuple.fields.iter().map(|f| f.id)) + } else { + either::Either::Right(std::iter::once(*key_ty)) }; if hashers.len() == 1 { From aa5e703de96555acaf2488e745d88189c70f0df4 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Mon, 4 Mar 2024 14:38:32 +0100 Subject: [PATCH 31/39] lifetime issues and iterator impls --- subxt/src/error/mod.rs | 3 - subxt/src/storage/storage_address.rs | 79 +------ subxt/src/storage/storage_key.rs | 324 +++++++++++++++------------ subxt/src/storage/storage_type.rs | 58 +---- subxt/src/storage/utils.rs | 21 ++ 5 files changed, 213 insertions(+), 272 deletions(-) diff --git a/subxt/src/error/mod.rs b/subxt/src/error/mod.rs index 8fb4d7007f..449c83cb60 100644 --- a/subxt/src/error/mod.rs +++ b/subxt/src/error/mod.rs @@ -188,9 +188,6 @@ pub enum TransactionError { #[derive(Clone, Debug, thiserror::Error)] #[non_exhaustive] pub enum StorageAddressError { - /// Storage map type must be a composite type. - #[error("Storage map type must be a composite type")] - MapTypeMustBeTuple, /// Storage lookup does not have the expected number of keys. #[error("Storage lookup requires {expected} keys but got {actual} keys")] WrongNumberOfKeys { diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 5facb025b6..5fe155b524 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -13,7 +13,7 @@ use scale_info::TypeDef; use std::borrow::Cow; use subxt_metadata::{StorageEntryType, StorageHasher}; -use super::StorageKey; +use super::{storage_key::StorageHashersIter, StorageKey}; /// This represents a storage address. Anything implementing this trait /// can be used to fetch and iterate over storage entries. @@ -166,62 +166,8 @@ where .entry_by_name(self.entry_name()) .ok_or_else(|| MetadataError::StorageEntryNotFound(self.entry_name().to_owned()))?; - let keys_iter = self.keys.keys_iter(); - let keys_len = self.keys.keys_len(); - - if keys_len == 0 { - return Ok(()); - } - - let StorageEntryType::Map { - hashers, key_ty, .. - } = entry.entry_type() - else { - // Plain entries are only okay, if keys_len == 0, see early return above. - return Err(StorageAddressError::WrongNumberOfKeys { - expected: 0, - actual: keys_len, - } - .into()); - }; - - let ty = metadata - .types() - .resolve(*key_ty) - .ok_or(MetadataError::TypeNotFound(*key_ty))?; - - // If the key is a tuple, we encode each value to the corresponding tuple type. - // If the key is not a tuple, encode a single value to the key type. - let type_ids = if let TypeDef::Tuple(tuple) = &ty.type_def { - either::Either::Left(tuple.fields.iter().map(|f| f.id)) - } else { - either::Either::Right(std::iter::once(*key_ty)) - }; - - if hashers.len() == 1 { - // One hasher; hash a tuple of all SCALE encoded bytes with the one hash function. - let mut input = Vec::new(); - let iter = keys_iter.zip(type_ids); - for (key, type_id) in iter { - key.encode_with_metadata(type_id, metadata, &mut input)?; - } - hash_bytes(&input, &hashers[0], bytes); - } else if hashers.len() >= type_ids.len() { - // A hasher per field; encode and hash each field independently. - let iter = keys_iter.zip(type_ids).zip(hashers); - for ((key, type_id), hasher) in iter { - let mut input = Vec::new(); - key.encode_with_metadata(type_id, metadata, &mut input)?; - hash_bytes(&input, hasher, bytes); - } - } else { - // Provided more fields than hashers. - return Err(StorageAddressError::WrongNumberOfHashers { - hashers: hashers.len(), - fields: type_ids.len(), - } - .into()); - } + let mut hashers = StorageHashersIter::new(entry.entry_type(), metadata.types())?; + self.keys.encode_to(bytes, &mut hashers, metadata.types())?; Ok(()) } @@ -239,22 +185,3 @@ pub fn dynamic( ) -> DynamicAddress { DynamicAddress::new(pallet_name, entry_name, storage_entry_keys) } - -/// Take some SCALE encoded bytes and a [`StorageHasher`] and hash the bytes accordingly. -fn hash_bytes(input: &[u8], hasher: &StorageHasher, bytes: &mut Vec) { - match hasher { - StorageHasher::Identity => bytes.extend(input), - StorageHasher::Blake2_128 => bytes.extend(sp_core_hashing::blake2_128(input)), - StorageHasher::Blake2_128Concat => { - bytes.extend(sp_core_hashing::blake2_128(input)); - bytes.extend(input); - } - StorageHasher::Blake2_256 => bytes.extend(sp_core_hashing::blake2_256(input)), - StorageHasher::Twox128 => bytes.extend(sp_core_hashing::twox_128(input)), - StorageHasher::Twox256 => bytes.extend(sp_core_hashing::twox_256(input)), - StorageHasher::Twox64Concat => { - bytes.extend(sp_core_hashing::twox_64(input)); - bytes.extend(input); - } - } -} diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 3206f70982..d63424f4ae 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -1,25 +1,120 @@ use crate::{ - error::{Error, StorageAddressError}, + error::{Error, MetadataError, StorageAddressError}, + metadata::EncodeWithMetadata, utils::{Encoded, Static}, }; use scale_decode::{visitor::IgnoreVisitor, DecodeAsType}; use scale_encode::EncodeAsType; -use scale_info::PortableRegistry; +use scale_info::{PortableRegistry, TypeDef}; use scale_value::Value; -use subxt_metadata::StorageHasher; +use subxt_metadata::{StorageEntryType, StorageHasher}; use derivative::Derivative; +use super::utils::hash_bytes; + +pub struct StorageHashersIter { + hashers_and_ty_ids: Vec<(StorageHasher, u32)>, + idx: usize, +} + +impl<'a> StorageHashersIter { + pub fn new(storage_entry: &StorageEntryType, types: &PortableRegistry) -> Result { + let mut hashers_and_ty_ids = vec![]; + + if let StorageEntryType::Map { + hashers, key_ty, .. + } = storage_entry + { + let ty = types + .resolve(*key_ty) + .ok_or(MetadataError::TypeNotFound(*key_ty))?; + + if let TypeDef::Tuple(tuple) = &ty.type_def { + if tuple.fields.len() != hashers.len() { + return Err(StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: tuple.fields.len(), + } + .into()); + } + for (i, f) in tuple.fields.iter().enumerate() { + hashers_and_ty_ids.push((hashers[i], f.id)); + } + } else { + if hashers.len() != 1 { + return Err(StorageAddressError::WrongNumberOfHashers { + hashers: hashers.len(), + fields: 1, + } + .into()); + } + hashers_and_ty_ids.push((hashers[0], *key_ty)); + }; + } + + Ok(Self { + hashers_and_ty_ids, + idx: 0, + }) + } + + pub fn encode_next( + &mut self, + value: &E, + bytes: &mut Vec, + types: &PortableRegistry, + storage_key_fields: usize, + ) -> Result<(), Error> { + let (hasher, ty) = self.next_or_err(storage_key_fields)?; + let input = value.encode_as_type(ty, types)?; + hash_bytes(&input, hasher, bytes); + Ok(()) + } + + pub fn next_or_err( + &mut self, + storage_key_fields: usize, + ) -> Result<(StorageHasher, u32), Error> { + self.next().ok_or_else(|| { + StorageAddressError::WrongNumberOfHashers { + hashers: self.hashers_and_ty_ids.len(), + fields: storage_key_fields, + } + .into() + }) + } + + pub fn reset(&mut self) { + self.idx = 0; + } +} + +impl Iterator for StorageHashersIter { + type Item = (StorageHasher, u32); + + fn next(&mut self) -> Option { + let item = self.hashers_and_ty_ids.get(self.idx).copied()?; + self.idx += 1; + Some(item) + } +} + +impl ExactSizeIterator for StorageHashersIter { + fn len(&self) -> usize { + self.hashers_and_ty_ids.len() - self.idx + } +} + /// This trait should be implemented by anything that can be used as one or multiple storage keys. pub trait StorageKey { - /// Iterator over the storage keys, each key implements EncodeAsType to - /// give the corresponding bytes to a `StorageHasher`. - fn keys_iter(&self) -> impl Iterator; - - /// How many keys are there in total? Each key is an element that needs to be individually hashed. - // Note: Ideally we would use `impl ExactSizeIterator` for `keys_iter` above, - // But that plays poorly with the `Flatten` and `Chain` structs. - fn keys_len(&self) -> usize; + /// Encodes the storage key into some bytes + fn encode_to( + &self, + bytes: &mut Vec, + hashers: &mut StorageHashersIter, + types: &PortableRegistry, + ) -> Result<(), Error>; /// Attempts to decode the StorageKey given some bytes and a set of hashers and type IDs that they are meant to represent. /// @@ -33,9 +128,9 @@ pub trait StorageKey { /// Implementations of this must advance the `bytes` and `hashers_and_ty_ids` cursors to consume any that they are using, or /// return an error if they cannot appropriately do so. When a tuple of such implementations is given, each implementation /// in the tuple receives the remaining un-consumed bytes and hashers from the previous ones. - fn decode_from_bytes( + fn decode( bytes: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result where @@ -45,33 +140,22 @@ pub trait StorageKey { /// Implement `StorageKey` for `()` which can be used for keyless storage entries, /// or to otherwise just ignore some entry. impl StorageKey for () { - fn keys_iter(&self) -> impl Iterator { - std::iter::empty() - } - - fn keys_len(&self) -> usize { - 0 + fn encode_to( + &self, + bytes: &mut Vec, + hashers: &mut StorageHashersIter, + types: &PortableRegistry, + ) -> Result<(), Error> { + hashers.encode_next(&(), bytes, types, 1) } - fn decode_from_bytes( + fn decode( bytes: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result { - // If no hashers, we just do nothing (erroring if ). - let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { - if bytes.is_empty() { - return Ok(()); - } else { - return Err(StorageAddressError::TooManyBytes.into()); - } - }; - - // Consume the hash bytes (we don't care about the key output here). - consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, types)?; - // Advance our hasher cursor as well now that we've used it. - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; - + let (hasher, ty_id) = hashers.next_or_err(1)?; + consume_hash_returning_key_bytes(bytes, hasher, ty_id, types)?; Ok(()) } } @@ -112,42 +196,29 @@ impl StaticStorageKey { // Note: The ?Sized bound is necessary to support e.g. `StorageKey<[u8]>`. impl StorageKey for StaticStorageKey { - fn keys_iter(&self) -> impl Iterator { - std::iter::once(&self.bytes as &dyn EncodeAsType) - } - - fn keys_len(&self) -> usize { - 1 + fn encode_to( + &self, + bytes: &mut Vec, + hashers: &mut StorageHashersIter, + types: &PortableRegistry, + ) -> Result<(), Error> { + hashers.encode_next(&self.bytes, bytes, types, 1) } - fn decode_from_bytes( + fn decode( bytes: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result where Self: Sized + 'static, { - let Some((hasher, ty_id)) = hashers_and_ty_ids.first() else { - return Err(StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into()); - }; - - // Advance the bytes cursor, returning any key bytes. - let key_bytes = consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, types)?; - // Advance the hasher cursor now we've used it. - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; + let (hasher, ty_id) = hashers.next_or_err(1)?; + let key_bytes = consume_hash_returning_key_bytes(bytes, hasher, ty_id, types)?; // if the hasher had no key appended, we can't decode it into a `StaticStorageKey`. let Some(key_bytes) = key_bytes else { - return Err(StorageAddressError::HasherCannotReconstructKey { - ty_id: *ty_id, - hasher: *hasher, - } - .into()); + return Err(StorageAddressError::HasherCannotReconstructKey { ty_id, hasher }.into()); }; // Return the key bytes. @@ -160,36 +231,37 @@ impl StorageKey for StaticStorageKey { } impl StorageKey for Vec { - fn keys_iter(&self) -> impl Iterator { - // Note: this returns the storage root address of the storage entry. - // It gives the same result as if you were to use `vec![]` as a `StorageKey`. - self.iter().map(|e| e as &dyn EncodeAsType) - } - - fn keys_len(&self) -> usize { - self.len() + fn encode_to( + &self, + bytes: &mut Vec, + hashers: &mut StorageHashersIter, + types: &PortableRegistry, + ) -> Result<(), Error> { + for value in self.iter() { + hashers.encode_next(value, bytes, types, self.len())?; + } + Ok(()) } - fn decode_from_bytes( + fn decode( bytes: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result where Self: Sized + 'static, { let mut result: Vec = vec![]; - for (hasher, ty_id) in hashers_and_ty_ids.iter() { - match consume_hash_returning_key_bytes(bytes, *hasher, *ty_id, types)? { + while let Some((hasher, ty_id)) = hashers.next() { + match consume_hash_returning_key_bytes(bytes, hasher, ty_id, types)? { Some(value_bytes) => { - let value = Value::decode_as_type(&mut &*value_bytes, *ty_id, types)?; + let value = Value::decode_as_type(&mut &*value_bytes, ty_id, types)?; result.push(value.remove_context()); } None => { result.push(Value::unnamed_composite([])); } } - *hashers_and_ty_ids = &hashers_and_ty_ids[1..]; // Advance by 1 each time. } // We've consumed all of the hashers, so we expect to also consume all of the bytes: @@ -241,55 +313,27 @@ fn consume_hash_returning_key_bytes<'a>( /// } /// ``` macro_rules! impl_tuples { - ($($ty:ident $iter:ident $n:tt),+) => {{ + ($($ty:ident $n:tt),+) => {{ impl<$($ty: StorageKey),+> StorageKey for ($( $ty ),+) { - fn keys_iter(&self) -> impl Iterator { - - $( - let mut $iter = self.$n.keys_iter(); - )+ - - // Note: this functions just flattens the iterators (that might all have different types). - std::iter::from_fn(move || { - let mut i = 0; - loop { - match i { - $( - $n => { - let el = $iter.next(); - if el.is_some(){ - return el; - } - }, - )+ - _ => return None, - }; - i+=1; - } - }) - } - - fn keys_len(&self) -> usize { - $((self.$n.keys_len())+)+0 + fn encode_to( + &self, + bytes: &mut Vec, + hashers: &mut StorageHashersIter, + types: &PortableRegistry, + ) -> Result<(), Error> { + $( self.$n.encode_to(bytes, hashers, types)?; )+ + Ok(()) } - fn decode_from_bytes( - cursor: &mut &[u8], - hashers_and_ty_ids: &mut &[(StorageHasher, u32)], + fn decode( + bytes: &mut &[u8], + hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result where Self: Sized + 'static, { - // Construct the tuple as a series of expressions. - let tuple : Self = ( $( - { - let key = - $ty::decode_from_bytes(cursor, hashers_and_ty_ids, types)?; - key - }, - )+); - return Ok(tuple) + Ok( ( $( $ty::decode(bytes, hashers, types)?, )+ ) ) } } }}; @@ -297,13 +341,13 @@ macro_rules! impl_tuples { #[rustfmt::skip] const _: () = { - impl_tuples!(A iter_a 0, B iter_b 1); - impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2); - impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3); - impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4); - impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5); - impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6); - impl_tuples!(A iter_a 0, B iter_b 1, C iter_c 2, D iter_d 3, E iter_e 4, F iter_f 5, G iter_g 6, H iter_h 7); + impl_tuples!(A 0, B 1); + impl_tuples!(A 0, B 1, C 2); + impl_tuples!(A 0, B 1, C 2, D 3); + impl_tuples!(A 0, B 1, C 2, D 3, E 4); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6); + impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7); }; #[cfg(test)] @@ -394,26 +438,22 @@ mod tests { .add(era, h3) .build(); - let keys_a = T4A::decode_from_bytes( - &mut &bytes[..], - &mut &hashers_and_ty_ids[..], - &types, - ) - .unwrap(); - - let keys_b = T4B::decode_from_bytes( - &mut &bytes[..], - &mut &hashers_and_ty_ids[..], - &types, - ) - .unwrap(); - - let keys_c = T4C::decode_from_bytes( - &mut &bytes[..], - &mut &hashers_and_ty_ids[..], - &types, - ) - .unwrap(); + let mut iter = super::StorageHashersIter{ hashers_and_ty_ids, idx: 0 }; + let keys_a = + T4A::decode(&mut &bytes[..], &mut iter, &types) + .unwrap(); + + iter.reset(); + + let keys_b = + T4B::decode(&mut &bytes[..], &mut iter, &types) + .unwrap(); + + iter.reset(); + + let keys_c = + T4C::decode(&mut &bytes[..], &mut iter, &types) + .unwrap(); assert_eq!(keys_a.1.decoded().unwrap(), 13); assert_eq!(keys_b.1 .0.decoded().unwrap(), 13); diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index 8ba697cc67..d0220508fc 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -3,6 +3,7 @@ // see LICENSE for license details. use super::storage_address::{StorageAddress, Yes}; +use super::storage_key::StorageHashersIter; use super::StorageKey; use crate::{ @@ -233,11 +234,10 @@ where let entry = entry.entry_type(); let return_type_id = entry.value_ty(); - let hasher_type_id_pairs = storage_hasher_type_id_pairs(entry, &metadata)?; + let mut hashers = StorageHashersIter::new(entry, metadata.types())?; // The address bytes of this entry: let address_bytes = super::utils::storage_address_bytes(&address, &metadata)?; - let s = client .backend() .storage_fetch_descendant_values(address_bytes, block_ref.hash()) @@ -256,11 +256,14 @@ where let key_bytes = kv.key; let cursor = &mut &key_bytes[..]; strip_storage_addess_root_bytes(cursor)?; - let keys = ::decode_from_bytes( + + hashers.reset(); + let keys = ::decode( cursor, - &mut &hasher_type_id_pairs[..], + &mut hashers, metadata.types(), )?; + Ok(StorageKeyValuePair::
{ keys, key_bytes, @@ -310,53 +313,6 @@ where } } -/// Return a vec of hashers and the associated type IDs for the keys that are hashed. -fn storage_hasher_type_id_pairs( - entry: &StorageEntryType, - metadata: &Metadata, -) -> Result, Error> { - match entry { - StorageEntryType::Plain(_) => Ok(vec![]), - StorageEntryType::Map { - hashers, key_ty, .. - } => { - let ty = metadata - .types() - .resolve(*key_ty) - .ok_or(MetadataError::TypeNotFound(*key_ty))?; - match &ty.type_def { - TypeDef::Tuple(tuple) => { - if hashers.len() < tuple.fields.len() { - return Err(StorageAddressError::WrongNumberOfHashers { - hashers: hashers.len(), - fields: tuple.fields.len(), - } - .into()); - } - let pairs: Vec<(StorageHasher, u32)> = tuple - .fields - .iter() - .zip(hashers.iter()) - .map(|(e, h)| (*h, e.id)) - .collect(); - - Ok(pairs) - } - _other => { - if hashers.is_empty() { - return Err(StorageAddressError::WrongNumberOfHashers { - hashers: 0, - fields: 1, - } - .into()); - } - Ok(vec![(hashers[0], *key_ty)]) - } - } - } - } -} - /// Strips the first 16 bytes (8 for the pallet hash, 8 for the entry hash) off some storage address bytes. fn strip_storage_addess_root_bytes(address_bytes: &mut &[u8]) -> Result<(), StorageAddressError> { if address_bytes.len() >= 16 { diff --git a/subxt/src/storage/utils.rs b/subxt/src/storage/utils.rs index 9dda39d7af..12db5a922c 100644 --- a/subxt/src/storage/utils.rs +++ b/subxt/src/storage/utils.rs @@ -6,6 +6,8 @@ //! aren't things that should ever be overridden, and so don't exist on //! the trait itself. +use subxt_metadata::StorageHasher; + use super::StorageAddress; use crate::{error::Error, metadata::Metadata}; @@ -37,3 +39,22 @@ pub fn storage_address_root_bytes(addr: &Address) -> Ve write_storage_address_root_bytes(addr, &mut bytes); bytes } + +/// Take some SCALE encoded bytes and a [`StorageHasher`] and hash the bytes accordingly. +pub fn hash_bytes(input: &[u8], hasher: StorageHasher, bytes: &mut Vec) { + match hasher { + StorageHasher::Identity => bytes.extend(input), + StorageHasher::Blake2_128 => bytes.extend(sp_core_hashing::blake2_128(input)), + StorageHasher::Blake2_128Concat => { + bytes.extend(sp_core_hashing::blake2_128(input)); + bytes.extend(input); + } + StorageHasher::Blake2_256 => bytes.extend(sp_core_hashing::blake2_256(input)), + StorageHasher::Twox128 => bytes.extend(sp_core_hashing::twox_128(input)), + StorageHasher::Twox256 => bytes.extend(sp_core_hashing::twox_256(input)), + StorageHasher::Twox64Concat => { + bytes.extend(sp_core_hashing::twox_64(input)); + bytes.extend(input); + } + } +} From 1eaa75d593a41d5dc846477f5255097f7367a60c Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Mon, 4 Mar 2024 14:51:24 +0100 Subject: [PATCH 32/39] fmt and clippy --- subxt/src/storage/storage_address.rs | 6 ++---- subxt/src/storage/storage_key.rs | 22 +++++++++------------- subxt/src/storage/storage_type.rs | 4 ++-- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index 5fe155b524..c4490abafe 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -4,14 +4,12 @@ use crate::{ dynamic::DecodedValueThunk, - error::{Error, MetadataError, StorageAddressError}, - metadata::{DecodeWithMetadata, EncodeWithMetadata, Metadata}, + error::{Error, MetadataError}, + metadata::{DecodeWithMetadata, Metadata}, }; use derivative::Derivative; -use scale_info::TypeDef; use std::borrow::Cow; -use subxt_metadata::{StorageEntryType, StorageHasher}; use super::{storage_key::StorageHashersIter, StorageKey}; diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index d63424f4ae..c15ef42690 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -1,6 +1,5 @@ use crate::{ error::{Error, MetadataError, StorageAddressError}, - metadata::EncodeWithMetadata, utils::{Encoded, Static}, }; use scale_decode::{visitor::IgnoreVisitor, DecodeAsType}; @@ -18,7 +17,7 @@ pub struct StorageHashersIter { idx: usize, } -impl<'a> StorageHashersIter { +impl StorageHashersIter { pub fn new(storage_entry: &StorageEntryType, types: &PortableRegistry) -> Result { let mut hashers_and_ty_ids = vec![]; @@ -252,7 +251,7 @@ impl StorageKey for Vec { Self: Sized + 'static, { let mut result: Vec = vec![]; - while let Some((hasher, ty_id)) = hashers.next() { + for (hasher, ty_id) in hashers.by_ref() { match consume_hash_returning_key_bytes(bytes, hasher, ty_id, types)? { Some(value_bytes) => { let value = Value::decode_as_type(&mut &*value_bytes, ty_id, types)?; @@ -438,22 +437,19 @@ mod tests { .add(era, h3) .build(); - let mut iter = super::StorageHashersIter{ hashers_and_ty_ids, idx: 0 }; - let keys_a = - T4A::decode(&mut &bytes[..], &mut iter, &types) - .unwrap(); + let mut iter = super::StorageHashersIter { + hashers_and_ty_ids, + idx: 0, + }; + let keys_a = T4A::decode(&mut &bytes[..], &mut iter, &types).unwrap(); iter.reset(); - let keys_b = - T4B::decode(&mut &bytes[..], &mut iter, &types) - .unwrap(); + let keys_b = T4B::decode(&mut &bytes[..], &mut iter, &types).unwrap(); iter.reset(); - let keys_c = - T4C::decode(&mut &bytes[..], &mut iter, &types) - .unwrap(); + let keys_c = T4C::decode(&mut &bytes[..], &mut iter, &types).unwrap(); assert_eq!(keys_a.1.decoded().unwrap(), 13); assert_eq!(keys_b.1 .0.decoded().unwrap(), 13); diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index d0220508fc..caf038918a 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -16,9 +16,9 @@ use crate::{ use codec::Decode; use derivative::Derivative; use futures::StreamExt; -use scale_info::TypeDef; + use std::{future::Future, marker::PhantomData}; -use subxt_metadata::StorageHasher; + use subxt_metadata::{PalletMetadata, StorageEntryMetadata, StorageEntryType}; /// This is returned from a couple of storage functions. From c5e071d6e57f8752332cd8d6df8a0e24b8acd92c Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Mon, 4 Mar 2024 15:32:38 +0100 Subject: [PATCH 33/39] regenerate polkadot.rs --- subxt/src/storage/storage_key.rs | 29 +++++-------------- .../src/full_client/codegen/polkadot.rs | 4 +-- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index c15ef42690..286a19f8fd 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -12,12 +12,15 @@ use derivative::Derivative; use super::utils::hash_bytes; +// An iterator over all type ids of the key and the respective hashers. pub struct StorageHashersIter { hashers_and_ty_ids: Vec<(StorageHasher, u32)>, idx: usize, } impl StorageHashersIter { + /// Creates a new [`StorageHashersIter`]. Looks at the [`StorageEntryType`] and + /// assigns a hasher to each type id that makes up the key. pub fn new(storage_entry: &StorageEntryType, types: &PortableRegistry) -> Result { let mut hashers_and_ty_ids = vec![]; @@ -116,17 +119,9 @@ pub trait StorageKey { ) -> Result<(), Error>; /// Attempts to decode the StorageKey given some bytes and a set of hashers and type IDs that they are meant to represent. - /// - /// Example: Imagine The `StorageKey` is a tuple `(A,B)` and the hashers are `[Blake2_128Concat, Twox64Concat]`. - /// Then the memory layout of the storage address is: - /// - /// ```txt - /// | 16 byte hash of A | n bytes for SCALE encoded A | 8 byte hash of B | n bytes for SCALE encoded B | - /// ``` - /// - /// Implementations of this must advance the `bytes` and `hashers_and_ty_ids` cursors to consume any that they are using, or - /// return an error if they cannot appropriately do so. When a tuple of such implementations is given, each implementation - /// in the tuple receives the remaining un-consumed bytes and hashers from the previous ones. + /// The bytes passed to `decode` should start with: + /// - 1. some fixed size hash (for all hashers except `Identity`) + /// - 2. the plain key value itself (for `Identity`, `Blake2_128Concat` and `Twox64Concat` hashers) fn decode( bytes: &mut &[u8], hashers: &mut StorageHashersIter, @@ -302,15 +297,7 @@ fn consume_hash_returning_key_bytes<'a>( } } -/// Generates StorageKey implementations for tuples, e.g. -/// ```rs,no_run -/// impl StorageKey for (StorageKey, StorageKey) { -/// fn keys_iter(&self) -> impl ExactSizeIterator { -/// let arr = [&self.0 as &dyn EncodeAsType, &self.1 as &dyn EncodeAsType]; -/// arr.into_iter() -/// } -/// } -/// ``` +/// Generates StorageKey implementations for tuples macro_rules! impl_tuples { ($($ty:ident $n:tt),+) => {{ impl<$($ty: StorageKey),+> StorageKey for ($( $ty ),+) { @@ -444,11 +431,9 @@ mod tests { let keys_a = T4A::decode(&mut &bytes[..], &mut iter, &types).unwrap(); iter.reset(); - let keys_b = T4B::decode(&mut &bytes[..], &mut iter, &types).unwrap(); iter.reset(); - let keys_c = T4C::decode(&mut &bytes[..], &mut iter, &types).unwrap(); assert_eq!(keys_a.1.decoded().unwrap(), 13); diff --git a/testing/integration-tests/src/full_client/codegen/polkadot.rs b/testing/integration-tests/src/full_client/codegen/polkadot.rs index 0366cf830f..43a705fc31 100644 --- a/testing/integration-tests/src/full_client/codegen/polkadot.rs +++ b/testing/integration-tests/src/full_client/codegen/polkadot.rs @@ -4839,7 +4839,7 @@ pub mod api { pub fn inherents_applied( &self, ) -> ::subxt::storage::address::Address< - ::subxt::storage::address::StaticStorageMapKey, + (), types::inherents_applied::InherentsApplied, ::subxt::storage::address::Yes, ::subxt::storage::address::Yes, @@ -4848,7 +4848,7 @@ pub mod api { ::subxt::storage::address::Address::new_static( "System", "InherentsApplied", - vec![], + (), [ 132u8, 249u8, 142u8, 252u8, 8u8, 103u8, 80u8, 120u8, 50u8, 6u8, 188u8, 223u8, 101u8, 55u8, 165u8, 189u8, 172u8, 249u8, 165u8, 230u8, 183u8, From 4a3b936a0f851dddecc2e2b27617518c4f57648a Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Tue, 5 Mar 2024 10:07:22 +0100 Subject: [PATCH 34/39] fix storage key encoding for empty keys --- subxt/src/error/mod.rs | 6 ++--- subxt/src/storage/storage_key.rs | 43 +++++++++++++------------------- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/subxt/src/error/mod.rs b/subxt/src/error/mod.rs index 449c83cb60..4534585efc 100644 --- a/subxt/src/error/mod.rs +++ b/subxt/src/error/mod.rs @@ -189,10 +189,8 @@ pub enum TransactionError { #[non_exhaustive] pub enum StorageAddressError { /// Storage lookup does not have the expected number of keys. - #[error("Storage lookup requires {expected} keys but got {actual} keys")] - WrongNumberOfKeys { - /// The actual number of keys needed, based on the metadata. - actual: usize, + #[error("Storage lookup requires {expected} keys but more keys have been provided.")] + TooManyKeys { /// The number of keys provided in the storage address. expected: usize, }, diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 286a19f8fd..9e48dd4db9 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -12,6 +12,7 @@ use derivative::Derivative; use super::utils::hash_bytes; +#[derive(Debug, Clone)] // An iterator over all type ids of the key and the respective hashers. pub struct StorageHashersIter { hashers_and_ty_ids: Vec<(StorageHasher, u32)>, @@ -61,27 +62,10 @@ impl StorageHashersIter { }) } - pub fn encode_next( - &mut self, - value: &E, - bytes: &mut Vec, - types: &PortableRegistry, - storage_key_fields: usize, - ) -> Result<(), Error> { - let (hasher, ty) = self.next_or_err(storage_key_fields)?; - let input = value.encode_as_type(ty, types)?; - hash_bytes(&input, hasher, bytes); - Ok(()) - } - - pub fn next_or_err( - &mut self, - storage_key_fields: usize, - ) -> Result<(StorageHasher, u32), Error> { + pub fn next_or_err(&mut self) -> Result<(StorageHasher, u32), Error> { self.next().ok_or_else(|| { - StorageAddressError::WrongNumberOfHashers { - hashers: self.hashers_and_ty_ids.len(), - fields: storage_key_fields, + StorageAddressError::TooManyKeys { + expected: self.hashers_and_ty_ids.len(), } .into() }) @@ -138,9 +122,11 @@ impl StorageKey for () { &self, bytes: &mut Vec, hashers: &mut StorageHashersIter, - types: &PortableRegistry, + _types: &PortableRegistry, ) -> Result<(), Error> { - hashers.encode_next(&(), bytes, types, 1) + let (hasher, _ty) = hashers.next_or_err()?; + hash_bytes(&[], hasher, bytes); + Ok(()) } fn decode( @@ -148,7 +134,7 @@ impl StorageKey for () { hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result { - let (hasher, ty_id) = hashers.next_or_err(1)?; + let (hasher, ty_id) = hashers.next_or_err()?; consume_hash_returning_key_bytes(bytes, hasher, ty_id, types)?; Ok(()) } @@ -196,7 +182,10 @@ impl StorageKey for StaticStorageKey { hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result<(), Error> { - hashers.encode_next(&self.bytes, bytes, types, 1) + let (hasher, ty_id) = hashers.next_or_err()?; + let encoded_value = self.bytes.encode_as_type(ty_id, types)?; + hash_bytes(&encoded_value, hasher, bytes); + Ok(()) } fn decode( @@ -207,7 +196,7 @@ impl StorageKey for StaticStorageKey { where Self: Sized + 'static, { - let (hasher, ty_id) = hashers.next_or_err(1)?; + let (hasher, ty_id) = hashers.next_or_err()?; let key_bytes = consume_hash_returning_key_bytes(bytes, hasher, ty_id, types)?; // if the hasher had no key appended, we can't decode it into a `StaticStorageKey`. @@ -232,7 +221,9 @@ impl StorageKey for Vec { types: &PortableRegistry, ) -> Result<(), Error> { for value in self.iter() { - hashers.encode_next(value, bytes, types, self.len())?; + let (hasher, ty_id) = hashers.next_or_err()?; + let encoded_value = value.encode_as_type(ty_id, types)?; + hash_bytes(&encoded_value, hasher, bytes); } Ok(()) } From f7a530c8dd30efe080942858afa20bdd9b31d9c0 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Tue, 5 Mar 2024 17:23:02 +0100 Subject: [PATCH 35/39] rename trait methods for storage keys --- subxt/src/storage/storage_address.rs | 4 ++-- subxt/src/storage/storage_key.rs | 33 +++++++++++++++------------- subxt/src/storage/storage_type.rs | 2 +- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index c4490abafe..e892966aeb 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -165,8 +165,8 @@ where .ok_or_else(|| MetadataError::StorageEntryNotFound(self.entry_name().to_owned()))?; let mut hashers = StorageHashersIter::new(entry.entry_type(), metadata.types())?; - self.keys.encode_to(bytes, &mut hashers, metadata.types())?; - + self.keys + .encode_storage_key(bytes, &mut hashers, metadata.types())?; Ok(()) } diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 9e48dd4db9..d2ddfbe456 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -95,7 +95,7 @@ impl ExactSizeIterator for StorageHashersIter { /// This trait should be implemented by anything that can be used as one or multiple storage keys. pub trait StorageKey { /// Encodes the storage key into some bytes - fn encode_to( + fn encode_storage_key( &self, bytes: &mut Vec, hashers: &mut StorageHashersIter, @@ -106,7 +106,7 @@ pub trait StorageKey { /// The bytes passed to `decode` should start with: /// - 1. some fixed size hash (for all hashers except `Identity`) /// - 2. the plain key value itself (for `Identity`, `Blake2_128Concat` and `Twox64Concat` hashers) - fn decode( + fn decode_storage_key( bytes: &mut &[u8], hashers: &mut StorageHashersIter, types: &PortableRegistry, @@ -118,7 +118,7 @@ pub trait StorageKey { /// Implement `StorageKey` for `()` which can be used for keyless storage entries, /// or to otherwise just ignore some entry. impl StorageKey for () { - fn encode_to( + fn encode_storage_key( &self, bytes: &mut Vec, hashers: &mut StorageHashersIter, @@ -129,7 +129,7 @@ impl StorageKey for () { Ok(()) } - fn decode( + fn decode_storage_key( bytes: &mut &[u8], hashers: &mut StorageHashersIter, types: &PortableRegistry, @@ -176,7 +176,7 @@ impl StaticStorageKey { // Note: The ?Sized bound is necessary to support e.g. `StorageKey<[u8]>`. impl StorageKey for StaticStorageKey { - fn encode_to( + fn encode_storage_key( &self, bytes: &mut Vec, hashers: &mut StorageHashersIter, @@ -188,7 +188,7 @@ impl StorageKey for StaticStorageKey { Ok(()) } - fn decode( + fn decode_storage_key( bytes: &mut &[u8], hashers: &mut StorageHashersIter, types: &PortableRegistry, @@ -214,7 +214,7 @@ impl StorageKey for StaticStorageKey { } impl StorageKey for Vec { - fn encode_to( + fn encode_storage_key( &self, bytes: &mut Vec, hashers: &mut StorageHashersIter, @@ -228,7 +228,7 @@ impl StorageKey for Vec { Ok(()) } - fn decode( + fn decode_storage_key( bytes: &mut &[u8], hashers: &mut StorageHashersIter, types: &PortableRegistry, @@ -292,17 +292,17 @@ fn consume_hash_returning_key_bytes<'a>( macro_rules! impl_tuples { ($($ty:ident $n:tt),+) => {{ impl<$($ty: StorageKey),+> StorageKey for ($( $ty ),+) { - fn encode_to( + fn encode_storage_key( &self, bytes: &mut Vec, hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result<(), Error> { - $( self.$n.encode_to(bytes, hashers, types)?; )+ + $( self.$n.encode_storage_key(bytes, hashers, types)?; )+ Ok(()) } - fn decode( + fn decode_storage_key( bytes: &mut &[u8], hashers: &mut StorageHashersIter, types: &PortableRegistry, @@ -310,7 +310,7 @@ macro_rules! impl_tuples { where Self: Sized + 'static, { - Ok( ( $( $ty::decode(bytes, hashers, types)?, )+ ) ) + Ok( ( $( $ty::decode_storage_key(bytes, hashers, types)?, )+ ) ) } } }}; @@ -419,13 +419,16 @@ mod tests { hashers_and_ty_ids, idx: 0, }; - let keys_a = T4A::decode(&mut &bytes[..], &mut iter, &types).unwrap(); + let keys_a = + T4A::decode_storage_key(&mut &bytes[..], &mut iter, &types).unwrap(); iter.reset(); - let keys_b = T4B::decode(&mut &bytes[..], &mut iter, &types).unwrap(); + let keys_b = + T4B::decode_storage_key(&mut &bytes[..], &mut iter, &types).unwrap(); iter.reset(); - let keys_c = T4C::decode(&mut &bytes[..], &mut iter, &types).unwrap(); + let keys_c = + T4C::decode_storage_key(&mut &bytes[..], &mut iter, &types).unwrap(); assert_eq!(keys_a.1.decoded().unwrap(), 13); assert_eq!(keys_b.1 .0.decoded().unwrap(), 13); diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index caf038918a..0c12bb517d 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -258,7 +258,7 @@ where strip_storage_addess_root_bytes(cursor)?; hashers.reset(); - let keys = ::decode( + let keys = ::decode_storage_key( cursor, &mut hashers, metadata.types(), From 26947b54d5d4e4ae74ffb50a78b2264c673e8072 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Tue, 5 Mar 2024 19:10:10 +0100 Subject: [PATCH 36/39] fix hasher bug... --- subxt/src/storage/storage_key.rs | 27 +++++++++++++------ .../src/full_client/storage/mod.rs | 17 ++++++------ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index d2ddfbe456..552d41390b 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -34,15 +34,22 @@ impl StorageHashersIter { .ok_or(MetadataError::TypeNotFound(*key_ty))?; if let TypeDef::Tuple(tuple) = &ty.type_def { - if tuple.fields.len() != hashers.len() { + if hashers.len() == 1 { + // use the same hasher for all fields, if only 1 hasher present: + let hasher = hashers[0]; + for f in tuple.fields.iter() { + hashers_and_ty_ids.push((hasher, f.id)); + } + } else if hashers.len() < tuple.fields.len() { return Err(StorageAddressError::WrongNumberOfHashers { hashers: hashers.len(), fields: tuple.fields.len(), } .into()); - } - for (i, f) in tuple.fields.iter().enumerate() { - hashers_and_ty_ids.push((hashers[i], f.id)); + } else { + for (i, f) in tuple.fields.iter().enumerate() { + hashers_and_ty_ids.push((hashers[i], f.id)); + } } } else { if hashers.len() != 1 { @@ -120,12 +127,11 @@ pub trait StorageKey { impl StorageKey for () { fn encode_storage_key( &self, - bytes: &mut Vec, + _bytes: &mut Vec, hashers: &mut StorageHashersIter, _types: &PortableRegistry, ) -> Result<(), Error> { - let (hasher, _ty) = hashers.next_or_err()?; - hash_bytes(&[], hasher, bytes); + _ = hashers.next_or_err(); Ok(()) } @@ -134,7 +140,11 @@ impl StorageKey for () { hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result { - let (hasher, ty_id) = hashers.next_or_err()?; + let (hasher, ty_id) = match hashers.next_or_err() { + Ok((hasher, ty_id)) => (hasher, ty_id), + Err(_) if bytes.len() == 0 => return Ok(()), + Err(err) => return Err(err), + }; consume_hash_returning_key_bytes(bytes, hasher, ty_id, types)?; Ok(()) } @@ -182,6 +192,7 @@ impl StorageKey for StaticStorageKey { hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result<(), Error> { + println!("{:?}", hashers); let (hasher, ty_id) = hashers.next_or_err()?; let encoded_value = self.bytes.encode_as_type(ty_id, types)?; hash_bytes(&encoded_value, hasher, bytes); diff --git a/testing/integration-tests/src/full_client/storage/mod.rs b/testing/integration-tests/src/full_client/storage/mod.rs index f281314f45..1d7dcd50d4 100644 --- a/testing/integration-tests/src/full_client/storage/mod.rs +++ b/testing/integration-tests/src/full_client/storage/mod.rs @@ -56,10 +56,6 @@ async fn storage_map_lookup() -> Result<(), subxt::Error> { Ok(()) } -// This fails until the fix in https://github.com/paritytech/subxt/pull/458 is introduced. -// Here we create a key that looks a bit like a StorageNMap key, but should in fact be -// treated as a StorageKey (ie we should hash both values together with one hasher, rather -// than hash both values separately, or ignore the second value). #[tokio::test] async fn storage_n_mapish_key_is_properly_created() -> Result<(), subxt::Error> { use codec::Encode; @@ -73,18 +69,21 @@ async fn storage_n_mapish_key_is_properly_created() -> Result<(), subxt::Error> .session() .key_owner(KeyTypeId([1, 2, 3, 4]), [5u8, 6, 7, 8]); let actual_key_bytes = api.storage().address_bytes(&actual_key)?; - // Let's manually hash to what we assume it should be and compare: let expected_key_bytes = { // Hash the prefix to the storage entry: let mut bytes = sp_core::twox_128("Session".as_bytes()).to_vec(); bytes.extend(&sp_core::twox_128("KeyOwner".as_bytes())[..]); - // twox64_concat a *tuple* of the args expected: - let suffix = (KeyTypeId([1, 2, 3, 4]), vec![5u8, 6, 7, 8]).encode(); - bytes.extend(sp_core::twox_64(&suffix)); - bytes.extend(&suffix); + // Both keys, use twox64_concat hashers: + let key1 = KeyTypeId([1, 2, 3, 4]).encode(); + let key2 = vec![5u8, 6, 7, 8].encode(); + bytes.extend(sp_core::twox_64(&key1)); + bytes.extend(&key1); + bytes.extend(sp_core::twox_64(&key2)); + bytes.extend(&key2); bytes }; + dbg!(&expected_key_bytes); assert_eq!(actual_key_bytes, expected_key_bytes); Ok(()) From 81cd16eba5cc7f3bdaf9b2d7f4157e37ebb8de39 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Wed, 6 Mar 2024 09:11:26 +0100 Subject: [PATCH 37/39] impl nits, add iterator struct seperate from `StorageHashers` --- metadata/src/from_into/v14.rs | 8 +--- subxt/src/storage/storage_address.rs | 6 +-- subxt/src/storage/storage_key.rs | 68 ++++++++++++++++------------ subxt/src/storage/storage_type.rs | 7 ++- 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/metadata/src/from_into/v14.rs b/metadata/src/from_into/v14.rs index b9b13cf681..989542ab56 100644 --- a/metadata/src/from_into/v14.rs +++ b/metadata/src/from_into/v14.rs @@ -316,9 +316,7 @@ fn generate_outer_enums( ) -> Result, TryFromError> { let find_type = |name: &str| { metadata.types.types.iter().find_map(|ty| { - let Some(ident) = ty.ty.path.ident() else { - return None; - }; + let ident = ty.ty.path.ident()?; if ident != name { return None; @@ -368,9 +366,7 @@ fn generate_outer_error_enum_type( .pallets .iter() .filter_map(|pallet| { - let Some(error) = &pallet.error else { - return None; - }; + let error = pallet.error.as_ref()?; // Note: using the `alloc::format!` macro like in `let path = format!("{}Error", pallet.name);` // leads to linker errors about extern function `_Unwind_Resume` not being defined. diff --git a/subxt/src/storage/storage_address.rs b/subxt/src/storage/storage_address.rs index e892966aeb..cb72462eb8 100644 --- a/subxt/src/storage/storage_address.rs +++ b/subxt/src/storage/storage_address.rs @@ -11,7 +11,7 @@ use derivative::Derivative; use std::borrow::Cow; -use super::{storage_key::StorageHashersIter, StorageKey}; +use super::{storage_key::StorageHashers, StorageKey}; /// This represents a storage address. Anything implementing this trait /// can be used to fetch and iterate over storage entries. @@ -164,9 +164,9 @@ where .entry_by_name(self.entry_name()) .ok_or_else(|| MetadataError::StorageEntryNotFound(self.entry_name().to_owned()))?; - let mut hashers = StorageHashersIter::new(entry.entry_type(), metadata.types())?; + let hashers = StorageHashers::new(entry.entry_type(), metadata.types())?; self.keys - .encode_storage_key(bytes, &mut hashers, metadata.types())?; + .encode_storage_key(bytes, &mut hashers.iter(), metadata.types())?; Ok(()) } diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index 552d41390b..d3d3148d7f 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -12,19 +12,18 @@ use derivative::Derivative; use super::utils::hash_bytes; -#[derive(Debug, Clone)] -// An iterator over all type ids of the key and the respective hashers. -pub struct StorageHashersIter { +/// A collection of storage hashers paired with the type ids of the types they should hash. +/// Can be created for each storage entry in the metadata via [`StorageHashers::new()`]. +#[derive(Debug)] +pub(crate) struct StorageHashers { hashers_and_ty_ids: Vec<(StorageHasher, u32)>, - idx: usize, } -impl StorageHashersIter { - /// Creates a new [`StorageHashersIter`]. Looks at the [`StorageEntryType`] and +impl StorageHashers { + /// Creates new [`StorageHashers`] from a storage entry. Looks at the [`StorageEntryType`] and /// assigns a hasher to each type id that makes up the key. pub fn new(storage_entry: &StorageEntryType, types: &PortableRegistry) -> Result { let mut hashers_and_ty_ids = vec![]; - if let StorageEntryType::Map { hashers, key_ty, .. } = storage_entry @@ -63,39 +62,50 @@ impl StorageHashersIter { }; } - Ok(Self { - hashers_and_ty_ids, + Ok(Self { hashers_and_ty_ids }) + } + + /// Creates an iterator over the storage hashers and type ids. + pub fn iter(&self) -> StorageHashersIter<'_> { + StorageHashersIter { + hashers: self, idx: 0, - }) + } } +} + +/// An iterator over all type ids of the key and the respective hashers. +/// See [`StorageHashers::iter()`]. +#[derive(Debug)] +pub struct StorageHashersIter<'a> { + hashers: &'a StorageHashers, + idx: usize, +} - pub fn next_or_err(&mut self) -> Result<(StorageHasher, u32), Error> { +impl<'a> StorageHashersIter<'a> { + fn next_or_err(&mut self) -> Result<(StorageHasher, u32), Error> { self.next().ok_or_else(|| { StorageAddressError::TooManyKeys { - expected: self.hashers_and_ty_ids.len(), + expected: self.hashers.hashers_and_ty_ids.len(), } .into() }) } - - pub fn reset(&mut self) { - self.idx = 0; - } } -impl Iterator for StorageHashersIter { +impl<'a> Iterator for StorageHashersIter<'a> { type Item = (StorageHasher, u32); fn next(&mut self) -> Option { - let item = self.hashers_and_ty_ids.get(self.idx).copied()?; + let item = self.hashers.hashers_and_ty_ids.get(self.idx).copied()?; self.idx += 1; Some(item) } } -impl ExactSizeIterator for StorageHashersIter { +impl<'a> ExactSizeIterator for StorageHashersIter<'a> { fn len(&self) -> usize { - self.hashers_and_ty_ids.len() - self.idx + self.hashers.hashers_and_ty_ids.len() - self.idx } } @@ -142,7 +152,7 @@ impl StorageKey for () { ) -> Result { let (hasher, ty_id) = match hashers.next_or_err() { Ok((hasher, ty_id)) => (hasher, ty_id), - Err(_) if bytes.len() == 0 => return Ok(()), + Err(_) if bytes.is_empty() => return Ok(()), Err(err) => return Err(err), }; consume_hash_returning_key_bytes(bytes, hasher, ty_id, types)?; @@ -426,20 +436,18 @@ mod tests { .add(era, h3) .build(); - let mut iter = super::StorageHashersIter { - hashers_and_ty_ids, - idx: 0, - }; + let mut hashers = super::StorageHashers { hashers_and_ty_ids }; let keys_a = - T4A::decode_storage_key(&mut &bytes[..], &mut iter, &types).unwrap(); + T4A::decode_storage_key(&mut &bytes[..], &mut hashers.iter(), &types) + .unwrap(); - iter.reset(); let keys_b = - T4B::decode_storage_key(&mut &bytes[..], &mut iter, &types).unwrap(); + T4B::decode_storage_key(&mut &bytes[..], &mut hashers.iter(), &types) + .unwrap(); - iter.reset(); let keys_c = - T4C::decode_storage_key(&mut &bytes[..], &mut iter, &types).unwrap(); + T4C::decode_storage_key(&mut &bytes[..], &mut hashers.iter(), &types) + .unwrap(); assert_eq!(keys_a.1.decoded().unwrap(), 13); assert_eq!(keys_b.1 .0.decoded().unwrap(), 13); diff --git a/subxt/src/storage/storage_type.rs b/subxt/src/storage/storage_type.rs index 0c12bb517d..daa0eccf63 100644 --- a/subxt/src/storage/storage_type.rs +++ b/subxt/src/storage/storage_type.rs @@ -3,7 +3,7 @@ // see LICENSE for license details. use super::storage_address::{StorageAddress, Yes}; -use super::storage_key::StorageHashersIter; +use super::storage_key::StorageHashers; use super::StorageKey; use crate::{ @@ -234,7 +234,7 @@ where let entry = entry.entry_type(); let return_type_id = entry.value_ty(); - let mut hashers = StorageHashersIter::new(entry, metadata.types())?; + let hashers = StorageHashers::new(entry, metadata.types())?; // The address bytes of this entry: let address_bytes = super::utils::storage_address_bytes(&address, &metadata)?; @@ -257,10 +257,9 @@ where let cursor = &mut &key_bytes[..]; strip_storage_addess_root_bytes(cursor)?; - hashers.reset(); let keys = ::decode_storage_key( cursor, - &mut hashers, + &mut hashers.iter(), metadata.types(), )?; From 1a42c9e2e9ecd20d2479177e203cd5c04a129c05 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Wed, 6 Mar 2024 09:57:46 +0100 Subject: [PATCH 38/39] clippy fix --- subxt/src/storage/storage_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index d3d3148d7f..b8a8746b84 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -436,7 +436,7 @@ mod tests { .add(era, h3) .build(); - let mut hashers = super::StorageHashers { hashers_and_ty_ids }; + let hashers = super::StorageHashers { hashers_and_ty_ids }; let keys_a = T4A::decode_storage_key(&mut &bytes[..], &mut hashers.iter(), &types) .unwrap(); From 809331e0bae564db5f635adf205efc4207904fee Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Wed, 6 Mar 2024 12:16:45 +0100 Subject: [PATCH 39/39] remove println --- subxt/src/storage/storage_key.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/subxt/src/storage/storage_key.rs b/subxt/src/storage/storage_key.rs index b8a8746b84..a8bffab329 100644 --- a/subxt/src/storage/storage_key.rs +++ b/subxt/src/storage/storage_key.rs @@ -202,7 +202,6 @@ impl StorageKey for StaticStorageKey { hashers: &mut StorageHashersIter, types: &PortableRegistry, ) -> Result<(), Error> { - println!("{:?}", hashers); let (hasher, ty_id) = hashers.next_or_err()?; let encoded_value = self.bytes.encode_as_type(ty_id, types)?; hash_bytes(&encoded_value, hasher, bytes);