subxt_core/config/
extrinsic_params.rs

1// Copyright 2019-2024 Parity Technologies (UK) Ltd.
2// This file is dual-licensed as Apache-2.0 or GPL-3.0.
3// see LICENSE for license details.
4
5//! This module contains a trait which controls the parameters that must
6//! be provided in order to successfully construct an extrinsic.
7//! [`crate::config::DefaultExtrinsicParams`] provides a general-purpose
8//! implementation of this that will work in many cases.
9
10use crate::{
11    client::ClientState,
12    config::{Config, HashFor},
13    error::ExtrinsicParamsError,
14};
15use alloc::vec::Vec;
16use core::any::Any;
17
18/// This trait allows you to configure the "signed extra" and
19/// "additional" parameters that are a part of the transaction payload
20/// or the signer payload respectively.
21pub trait ExtrinsicParams<T: Config>: ExtrinsicParamsEncoder + Sized + Send + 'static {
22    /// These parameters can be provided to the constructor along with
23    /// some default parameters that `subxt` understands, in order to
24    /// help construct your [`ExtrinsicParams`] object.
25    type Params: Params<T>;
26
27    /// Construct a new instance of our [`ExtrinsicParams`].
28    fn new(client: &ClientState<T>, params: Self::Params) -> Result<Self, ExtrinsicParamsError>;
29}
30
31/// This trait is expected to be implemented for any [`ExtrinsicParams`], and
32/// defines how to encode the "additional" and "extra" params. Both functions
33/// are optional and will encode nothing by default.
34pub trait ExtrinsicParamsEncoder: 'static {
35    /// This is expected to SCALE encode the transaction extension data to some
36    /// buffer that has been provided. This data is attached to the transaction
37    /// and also (by default) attached to the signer payload which is signed to
38    /// provide a signature for the transaction.
39    ///
40    /// If [`ExtrinsicParamsEncoder::encode_signer_payload_value_to`] is implemented,
41    /// then that will be used instead when generating a signer payload. Useful for
42    /// eg the `VerifySignature` extension, which is send with the transaction but
43    /// is not a part of the signer payload.
44    fn encode_value_to(&self, _v: &mut Vec<u8>) {}
45
46    /// See [`ExtrinsicParamsEncoder::encode_value_to`]. This defaults to calling that
47    /// method, but if implemented will dictate what is encoded to the signer payload.
48    fn encode_signer_payload_value_to(&self, v: &mut Vec<u8>) {
49        self.encode_value_to(v);
50    }
51
52    /// This is expected to SCALE encode the "implicit" (formally "additional")
53    /// parameters to some buffer that has been provided. These parameters are
54    /// _not_ sent along with the transaction, but are taken into account when
55    /// signing it, meaning the client and node must agree on their values.
56    fn encode_implicit_to(&self, _v: &mut Vec<u8>) {}
57
58    /// Set the signature. This happens after we have constructed the extrinsic params,
59    /// and so is defined here rather than on the params, below. We need to use `&dyn Any`
60    /// to keep this trait object safe, but can downcast in the impls.
61    ///
62    /// # Panics
63    ///
64    /// Implementations of this will likely try to downcast the provided `account_id`
65    /// and `signature` into `T::AccountId` and `T::Signature` (where `T: Config`), and are
66    /// free to panic if this downcasting does not succeed.
67    ///
68    /// In typical usage, this is not a problem, since this method is only called internally
69    /// and provided values which line up with the relevant `Config`. In theory though, this
70    /// method can be called manually with any types, hence this warning.
71    fn inject_signature(&mut self, _account_id: &dyn Any, _signature: &dyn Any) {}
72}
73
74/// The parameters (ie [`ExtrinsicParams::Params`]) can also have data injected into them,
75/// allowing Subxt to retrieve data from the chain and amend the parameters with it when
76/// online.
77pub trait Params<T: Config> {
78    /// Set the account nonce.
79    fn inject_account_nonce(&mut self, _nonce: u64) {}
80    /// Set the current block.
81    fn inject_block(&mut self, _number: u64, _hash: HashFor<T>) {}
82}
83
84impl<T: Config> Params<T> for () {}
85
86macro_rules! impl_tuples {
87    ($($ident:ident $index:tt),+) => {
88        impl <Conf: Config, $($ident : Params<Conf>),+> Params<Conf> for ($($ident,)+){
89            fn inject_account_nonce(&mut self, nonce: u64) {
90                $(self.$index.inject_account_nonce(nonce);)+
91            }
92
93            fn inject_block(&mut self, number: u64, hash: HashFor<Conf>) {
94                $(self.$index.inject_block(number, hash);)+
95            }
96        }
97    }
98}
99
100#[rustfmt::skip]
101const _: () = {
102    impl_tuples!(A 0);
103    impl_tuples!(A 0, B 1);
104    impl_tuples!(A 0, B 1, C 2);
105    impl_tuples!(A 0, B 1, C 2, D 3);
106    impl_tuples!(A 0, B 1, C 2, D 3, E 4);
107    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5);
108    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6);
109    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7);
110    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8);
111    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9);
112    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10);
113    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11);
114    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12);
115    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13);
116    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14);
117    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15);
118    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16);
119    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17);
120    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18);
121    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19);
122    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20);
123    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21);
124    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21, W 22);
125    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21, W 22, X 23);
126    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21, W 22, X 23, Y 24);
127    impl_tuples!(A 0, B 1, C 2, D 3, E 4, F 5, G 6, H 7, I 8, J 9, K 10, L 11, M 12, N 13, O 14, P 15, Q 16, R 17, S 18, T 19, U 20, V 21, W 22, X 23, Y 24, Z 25);
128};