mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 17:01:09 +00:00
default or from implementation for mortality
This commit is contained in:
@@ -167,3 +167,5 @@ where
|
||||
};
|
||||
Ok(account_nonce)
|
||||
}
|
||||
|
||||
pub struct LatestBlockHeader {}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// use crate::{backend::Backend, Config};
|
||||
|
||||
// use super::OfflineClientT;
|
||||
use crate::{Config, Error, OfflineClient, OnlineClient};
|
||||
use core::future::Future;
|
||||
|
||||
use super::OfflineClientT;
|
||||
|
||||
pub type FetchBlockHeader<Header> =
|
||||
Box<dyn Future<Output = Result<Header, Error>> + Send + 'static>;
|
||||
|
||||
/// An object-safe trait abstracting over capabilities of offline and online-clients.
|
||||
///
|
||||
/// Implemented by [`subxt::OfflineClient`], [`subxt::OnlineClient`] and [`subxt::LightClient`] the like.
|
||||
pub trait ClientCapabilities<T: Config> {
|
||||
fn latest_block_header(&self) -> Option<FetchBlockHeader<T::Header>>
|
||||
where
|
||||
T::Header: Clone;
|
||||
}
|
||||
|
||||
impl<T: Config> ClientCapabilities<T> for OfflineClient<T> {
|
||||
fn latest_block_header(&self) -> Option<FetchBlockHeader<T::Header>>
|
||||
where
|
||||
T::Header: Clone,
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> ClientCapabilities<T> for OnlineClient<T> {
|
||||
fn latest_block_header(&self) -> Option<FetchBlockHeader<T::Header>>
|
||||
where
|
||||
T::Header: Clone,
|
||||
{
|
||||
let client = self.clone();
|
||||
Some(Box::new(async move {
|
||||
let block = client.blocks().at_latest().await?;
|
||||
let header: T::Header = block.header().clone();
|
||||
Ok(header)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
crate::macros::cfg_unstable_light_client! {
|
||||
use super::LightClient;
|
||||
|
||||
impl<T: Config> ClientCapabilities<T> for LightClient<T> {
|
||||
fn latest_block_header(&self) -> Option<FetchBlockHeader<T::Header>>
|
||||
where
|
||||
T::Header: Clone,
|
||||
{
|
||||
let client = self.clone();
|
||||
Some(Box::new(async move {
|
||||
let block = client.blocks().at_latest().await?;
|
||||
let header: T::Header = block.header().clone();
|
||||
Ok(header)
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ClientCapabilities;
|
||||
use crate::PolkadotConfig;
|
||||
use core::panic;
|
||||
|
||||
fn is_object_safe(client: Box<dyn ClientCapabilities<PolkadotConfig>>) {
|
||||
_ = client.latest_block_header();
|
||||
unreachable!("Do not call this function, it just needs to compile.")
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
//! require network access. The [`OnlineClient`] requires network
|
||||
//! access.
|
||||
|
||||
mod client_capabilities;
|
||||
mod offline_client;
|
||||
mod online_client;
|
||||
|
||||
|
||||
@@ -79,3 +79,57 @@ pub trait ExtrinsicParamsEncoder: 'static {
|
||||
/// signing it, meaning the client and node must agree on their values.
|
||||
fn encode_additional_to(&self, _v: &mut Vec<u8>) {}
|
||||
}
|
||||
|
||||
/// Like the `From<T>` trait, if value is Some(_), but it lets us circumvent the orphan rule, because we want to implement
|
||||
/// `DefaultOrFrom<Header>` for `()`, such that DefaultOrFrom<Header> is implemented by `((),(),(),CheckMortalityParams)`, if `CheckMortalityParams` implements `DefaultFrom<Header>`
|
||||
pub trait DefaultOrFrom<T> {
|
||||
/// If value
|
||||
fn default_or_from(value: Option<&T>) -> Self;
|
||||
}
|
||||
|
||||
impl<T> DefaultOrFrom<T> for () {
|
||||
fn default_or_from(_value: Option<&T>) -> () {}
|
||||
}
|
||||
|
||||
macro_rules! impl_default_from_tuples {
|
||||
($($ident:ident),+) => {
|
||||
// We do some magic when the tuple is wrapped in AnyOf. We
|
||||
// look at the metadata, and use this to select and make use of only the extensions
|
||||
// that we actually need for the chain we're dealing with.
|
||||
impl <T, $($ident),+> DefaultOrFrom<T> for ($($ident,)+)
|
||||
where
|
||||
$($ident: DefaultOrFrom<T>,)+
|
||||
{
|
||||
fn default_or_from(value: Option<&T>) -> Self {
|
||||
($(
|
||||
(<$ident as DefaultOrFrom<T>>::default_or_from(value)),
|
||||
)+)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
const _: () = {
|
||||
impl_default_from_tuples!(A);
|
||||
impl_default_from_tuples!(A, B);
|
||||
impl_default_from_tuples!(A, B, C);
|
||||
impl_default_from_tuples!(A, B, C, D);
|
||||
impl_default_from_tuples!(A, B, C, D, E);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, U);
|
||||
impl_default_from_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, U, V);
|
||||
};
|
||||
|
||||
@@ -23,7 +23,9 @@ 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 extrinsic_params::{
|
||||
DefaultOrFrom, ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError,
|
||||
};
|
||||
pub use polkadot::{PolkadotConfig, PolkadotExtrinsicParams, PolkadotExtrinsicParamsBuilder};
|
||||
pub use signed_extensions::SignedExtension;
|
||||
pub use substrate::{SubstrateConfig, SubstrateExtrinsicParams, SubstrateExtrinsicParamsBuilder};
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
//! [`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 super::extrinsic_params::{
|
||||
DefaultOrFrom, ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError,
|
||||
};
|
||||
use crate::config::Header;
|
||||
use crate::utils::Era;
|
||||
use crate::{client::OfflineClientT, Config};
|
||||
use codec::{Compact, Encode};
|
||||
@@ -166,6 +169,17 @@ impl<T: Config> Default for CheckMortalityParams<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> DefaultOrFrom<T::Header> for CheckMortalityParams<T> {
|
||||
fn default_or_from(value: Option<&T::Header>) -> Self {
|
||||
if let Some(header) = value {
|
||||
const FOR_N_BLOCKS: u64 = 32;
|
||||
CheckMortalityParams::mortal(FOR_N_BLOCKS, header.number().into(), header.hash())
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> CheckMortalityParams<T> {
|
||||
/// Configure a mortal transaction. The `period` is (roughly) how many
|
||||
/// blocks the transaction will be valid for. The `block_number` and
|
||||
@@ -253,6 +267,12 @@ impl<T: Config> Default for ChargeAssetTxPaymentParams<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> DefaultOrFrom<T::Header> for ChargeAssetTxPaymentParams<T> {
|
||||
fn default_or_from(_value: Option<&T::Header>) -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> ChargeAssetTxPaymentParams<T> {
|
||||
/// Don't provide a tip to the extrinsic author.
|
||||
pub fn no_tip() -> Self {
|
||||
@@ -324,6 +344,12 @@ pub struct ChargeTransactionPaymentParams {
|
||||
tip: u128,
|
||||
}
|
||||
|
||||
impl<T> DefaultOrFrom<T> for ChargeTransactionPaymentParams {
|
||||
fn default_or_from(_value: Option<&T>) -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl ChargeTransactionPaymentParams {
|
||||
/// Don't provide a tip to the extrinsic author.
|
||||
pub fn no_tip() -> Self {
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::borrow::Cow;
|
||||
use crate::{
|
||||
backend::{BackendExt, BlockRef, TransactionStatus},
|
||||
client::{OfflineClientT, OnlineClientT},
|
||||
config::{Config, ExtrinsicParams, ExtrinsicParamsEncoder, Hasher},
|
||||
config::{Config, DefaultOrFrom, ExtrinsicParams, ExtrinsicParamsEncoder, Hasher},
|
||||
error::{Error, MetadataError},
|
||||
tx::{Signer as SignerT, TxPayload, TxProgress},
|
||||
utils::{Encoded, PhantomDataSendSync},
|
||||
@@ -213,9 +213,13 @@ where
|
||||
where
|
||||
Call: TxPayload,
|
||||
Signer: SignerT<T>,
|
||||
<T::ExtrinsicParams as ExtrinsicParams<T>>::OtherParams: Default,
|
||||
<T::ExtrinsicParams as ExtrinsicParams<T>>::OtherParams: DefaultOrFrom<T::Header>,
|
||||
{
|
||||
self.sign_and_submit_then_watch(call, signer, Default::default())
|
||||
let latest_block = self.client.blocks().at_latest().await.ok();
|
||||
let latest_header = latest_block.as_ref().map(|b| b.header());
|
||||
let other_params =
|
||||
<T::ExtrinsicParams as ExtrinsicParams<T>>::OtherParams::default_or_from(latest_header);
|
||||
self.sign_and_submit_then_watch(call, signer, other_params)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -257,9 +261,13 @@ where
|
||||
where
|
||||
Call: TxPayload,
|
||||
Signer: SignerT<T>,
|
||||
<T::ExtrinsicParams as ExtrinsicParams<T>>::OtherParams: Default,
|
||||
<T::ExtrinsicParams as ExtrinsicParams<T>>::OtherParams: DefaultOrFrom<T::Header>,
|
||||
{
|
||||
self.sign_and_submit(call, signer, Default::default()).await
|
||||
let latest_block = self.client.blocks().at_latest().await.ok();
|
||||
let latest_header = latest_block.as_ref().map(|b| b.header());
|
||||
let other_params =
|
||||
<T::ExtrinsicParams as ExtrinsicParams<T>>::OtherParams::default_or_from(latest_header);
|
||||
self.sign_and_submit(call, signer, other_params).await
|
||||
}
|
||||
|
||||
/// Creates and signs an extrinsic and submits to the chain for block inclusion.
|
||||
|
||||
Reference in New Issue
Block a user