From c2875de172412c4e5e663c04f1911dcc4d02c3ae Mon Sep 17 00:00:00 2001 From: Tadeo Hepperle <62739623+tadeohepperle@users.noreply.github.com> Date: Thu, 20 Jul 2023 15:13:55 +0200 Subject: [PATCH] Remove `Index` type from Config trait (#1074) * remove config, doc tests are expected to fail (book not adjusted yet) * make doc tests pass * Prevent bug when reusing type ids in hashing (#1075) * practice TDD * implement a hashmap 2-phases approach * use nicer types * add test for cache filling * adjust test --------- Co-authored-by: James Wilson * remove the unnecessary intos --------- Co-authored-by: James Wilson --- subxt/examples/setup_client_custom_config.rs | 2 - subxt/src/book/usage/transactions.rs | 2 +- subxt/src/config/extrinsic_params.rs | 12 +++--- subxt/src/config/mod.rs | 11 ++--- subxt/src/config/polkadot.rs | 1 - subxt/src/config/substrate.rs | 1 - subxt/src/tx/tx_client.rs | 44 +++++++++++++------- 7 files changed, 38 insertions(+), 35 deletions(-) diff --git a/subxt/examples/setup_client_custom_config.rs b/subxt/examples/setup_client_custom_config.rs index 0acf71ae4a..7ee30ba0a7 100644 --- a/subxt/examples/setup_client_custom_config.rs +++ b/subxt/examples/setup_client_custom_config.rs @@ -7,8 +7,6 @@ use subxt::{ /// more information about each type): enum MyConfig {} impl Config for MyConfig { - // This is different from the default `u32`: - type Index = u64; // We can point to the default types if we don't need to change things: type Hash = ::Hash; type Hasher = ::Hasher; diff --git a/subxt/src/book/usage/transactions.rs b/subxt/src/book/usage/transactions.rs index d4b3ce75d4..a4abbeaad9 100644 --- a/subxt/src/book/usage/transactions.rs +++ b/subxt/src/book/usage/transactions.rs @@ -138,7 +138,7 @@ //! // here, or can use `create_partial_signed` to fetch the correct nonce. //! let partial_tx = client.tx().create_partial_signed_with_nonce( //! &payload, -//! 0, +//! 0u64, //! Default::default() //! )?; //! diff --git a/subxt/src/config/extrinsic_params.rs b/subxt/src/config/extrinsic_params.rs index 6fa9a508f9..7b6bc1b1ea 100644 --- a/subxt/src/config/extrinsic_params.rs +++ b/subxt/src/config/extrinsic_params.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; /// "additional" parameters that are signed and used in transactions. /// see [`BaseExtrinsicParams`] for an implementation that is compatible with /// a Polkadot node. -pub trait ExtrinsicParams: Debug + 'static { +pub trait ExtrinsicParams: Debug + '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. @@ -27,7 +27,7 @@ pub trait ExtrinsicParams: Debug + 'static { fn new( spec_version: u32, tx_version: u32, - nonce: Index, + nonce: u64, genesis_hash: Hash, other_params: Self::OtherParams, ) -> Self; @@ -58,7 +58,7 @@ pub trait ExtrinsicParams: Debug + 'static { #[derivative(Debug(bound = "Tip: Debug"))] pub struct BaseExtrinsicParams { era: Era, - nonce: T::Index, + nonce: u64, tip: Tip, spec_version: u32, transaction_version: u32, @@ -122,7 +122,7 @@ impl Default for BaseExtrinsicParamsBuilder { } } -impl ExtrinsicParams +impl ExtrinsicParams for BaseExtrinsicParams { type OtherParams = BaseExtrinsicParamsBuilder; @@ -131,7 +131,7 @@ impl ExtrinsicParams ExtrinsicParams) { - let nonce: u64 = self.nonce.into(); + let nonce: u64 = self.nonce; let tip = Encoded(self.tip.encode()); (self.era, Compact(nonce), tip).encode_to(v); } diff --git a/subxt/src/config/mod.rs b/subxt/src/config/mod.rs index d94f04810d..d0f2ca1c7a 100644 --- a/subxt/src/config/mod.rs +++ b/subxt/src/config/mod.rs @@ -25,10 +25,6 @@ pub use substrate::SubstrateConfig; // automatically applies a 'static bound to all generic types (including this one), // and so until that is resolved, we'll keep the (easy to satisfy) constraint here. pub trait Config: 'static { - /// Account index (aka nonce) type. This stores the number of previous - /// transactions associated with a sender account. - type Index: Debug + Copy + Decode + Into; - /// The output of the `Hasher` function. type Hash: Debug + Copy @@ -57,7 +53,7 @@ pub trait Config: 'static { type Header: Debug + Header + Sync + Send + DeserializeOwned; /// This type defines the extrinsic extra and additional parameters. - type ExtrinsicParams: extrinsic_params::ExtrinsicParams; + type ExtrinsicParams: extrinsic_params::ExtrinsicParams; } /// This represents the hasher used by a node to hash things like block headers @@ -95,14 +91,13 @@ pub trait Header: Sized + Encode { /// Take a type implementing [`Config`] (eg [`SubstrateConfig`]), and some type which describes the /// additional and extra parameters to pass to an extrinsic (see [`ExtrinsicParams`]), /// and returns a type implementing [`Config`] with those new [`ExtrinsicParams`]. -pub struct WithExtrinsicParams> { +pub struct WithExtrinsicParams> { _marker: std::marker::PhantomData<(T, E)>, } -impl> Config +impl> Config for WithExtrinsicParams { - type Index = T::Index; type Hash = T::Hash; type AccountId = T::AccountId; type Address = T::Address; diff --git a/subxt/src/config/polkadot.rs b/subxt/src/config/polkadot.rs index de46f05b44..ba33dc8ac6 100644 --- a/subxt/src/config/polkadot.rs +++ b/subxt/src/config/polkadot.rs @@ -18,7 +18,6 @@ pub use primitive_types::{H256, U256}; pub enum PolkadotConfig {} impl Config for PolkadotConfig { - type Index = ::Index; type Hash = ::Hash; type AccountId = ::AccountId; type Address = MultiAddress; diff --git a/subxt/src/config/substrate.rs b/subxt/src/config/substrate.rs index 3bf97b52db..83b780ac3c 100644 --- a/subxt/src/config/substrate.rs +++ b/subxt/src/config/substrate.rs @@ -20,7 +20,6 @@ pub use primitive_types::{H256, U256}; pub enum SubstrateConfig {} impl Config for SubstrateConfig { - type Index = u32; type Hash = H256; type AccountId = AccountId32; type Address = MultiAddress; diff --git a/subxt/src/tx/tx_client.rs b/subxt/src/tx/tx_client.rs index d2202f8188..91c3e40b0d 100644 --- a/subxt/src/tx/tx_client.rs +++ b/subxt/src/tx/tx_client.rs @@ -4,10 +4,11 @@ use std::borrow::Cow; -use codec::{Compact, Encode}; +use codec::{Compact, Decode, Encode}; use derivative::Derivative; use sp_core_hashing::blake2_256; +use crate::error::DecodeError; use crate::{ client::{OfflineClientT, OnlineClientT}, config::{Config, ExtrinsicParams, Hasher}, @@ -109,8 +110,8 @@ impl> TxClient { pub fn create_partial_signed_with_nonce( &self, call: &Call, - account_nonce: T::Index, - other_params: >::OtherParams, + account_nonce: u64, + other_params: >::OtherParams, ) -> Result, Error> where Call: TxPayload, @@ -126,7 +127,7 @@ impl> TxClient { let additional_and_extra_params = { // Obtain spec version and transaction version from the runtime version of the client. let runtime = self.client.runtime_version(); - >::new( + >::new( runtime.spec_version, runtime.transaction_version, account_nonce, @@ -148,8 +149,8 @@ impl> TxClient { &self, call: &Call, signer: &Signer, - account_nonce: T::Index, - other_params: >::OtherParams, + account_nonce: u64, + other_params: >::OtherParams, ) -> Result, Error> where Call: TxPayload, @@ -175,15 +176,26 @@ where C: OnlineClientT, { /// Get the account nonce for a given account ID. - pub async fn account_nonce(&self, account_id: &T::AccountId) -> Result { - self.client + pub async fn account_nonce(&self, account_id: &T::AccountId) -> Result { + let account_nonce_bytes = self + .client .rpc() - .state_call( + .state_call_raw( "AccountNonceApi_account_nonce", Some(&account_id.encode()), None, ) - .await + .await?; + + // custom decoding from a u16/u32/u64 into a u64, based on the number of bytes we got back. + 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(format!("state call AccountNonceApi_account_nonce returned an unexpected number of bytes: {} (expected 2, 4 or 8)", account_nonce_bytes.len())))) + }; + Ok(account_nonce) } /// Creates a partial signed extrinsic, without submitting it. @@ -191,7 +203,7 @@ where &self, call: &Call, account_id: &T::AccountId, - other_params: >::OtherParams, + other_params: >::OtherParams, ) -> Result, Error> where Call: TxPayload, @@ -205,7 +217,7 @@ where &self, call: &Call, signer: &Signer, - other_params: >::OtherParams, + other_params: >::OtherParams, ) -> Result, Error> where Call: TxPayload, @@ -228,7 +240,7 @@ where where Call: TxPayload, Signer: SignerT, - >::OtherParams: Default, + >::OtherParams: Default, { self.sign_and_submit_then_watch(call, signer, Default::default()) .await @@ -242,7 +254,7 @@ where &self, call: &Call, signer: &Signer, - other_params: >::OtherParams, + other_params: >::OtherParams, ) -> Result, Error> where Call: TxPayload, @@ -272,7 +284,7 @@ where where Call: TxPayload, Signer: SignerT, - >::OtherParams: Default, + >::OtherParams: Default, { self.sign_and_submit(call, signer, Default::default()).await } @@ -289,7 +301,7 @@ where &self, call: &Call, signer: &Signer, - other_params: >::OtherParams, + other_params: >::OtherParams, ) -> Result where Call: TxPayload,