Skip to content

Commit

Permalink
Remove Index type from Config trait (#1074)
Browse files Browse the repository at this point in the history
* 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 <james@jsdw.me>

* remove the unnecessary intos

---------

Co-authored-by: James Wilson <james@jsdw.me>
  • Loading branch information
tadeohepperle and jsdw authored Jul 20, 2023
1 parent 475a141 commit c2875de
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 35 deletions.
2 changes: 0 additions & 2 deletions subxt/examples/setup_client_custom_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <SubstrateConfig as Config>::Hash;
type Hasher = <SubstrateConfig as Config>::Hasher;
Expand Down
2 changes: 1 addition & 1 deletion subxt/src/book/usage/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
//! )?;
//!
Expand Down
12 changes: 6 additions & 6 deletions subxt/src/config/extrinsic_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Index, Hash>: Debug + 'static {
pub trait ExtrinsicParams<Hash>: 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.
Expand All @@ -27,7 +27,7 @@ pub trait ExtrinsicParams<Index, Hash>: Debug + 'static {
fn new(
spec_version: u32,
tx_version: u32,
nonce: Index,
nonce: u64,
genesis_hash: Hash,
other_params: Self::OtherParams,
) -> Self;
Expand Down Expand Up @@ -58,7 +58,7 @@ pub trait ExtrinsicParams<Index, Hash>: Debug + 'static {
#[derivative(Debug(bound = "Tip: Debug"))]
pub struct BaseExtrinsicParams<T: Config, Tip: Debug> {
era: Era,
nonce: T::Index,
nonce: u64,
tip: Tip,
spec_version: u32,
transaction_version: u32,
Expand Down Expand Up @@ -122,7 +122,7 @@ impl<T: Config, Tip: Default> Default for BaseExtrinsicParamsBuilder<T, Tip> {
}
}

impl<T: Config, Tip: Debug + Encode + 'static> ExtrinsicParams<T::Index, T::Hash>
impl<T: Config, Tip: Debug + Encode + 'static> ExtrinsicParams<T::Hash>
for BaseExtrinsicParams<T, Tip>
{
type OtherParams = BaseExtrinsicParamsBuilder<T, Tip>;
Expand All @@ -131,7 +131,7 @@ impl<T: Config, Tip: Debug + Encode + 'static> ExtrinsicParams<T::Index, T::Hash
// Provided from subxt client:
spec_version: u32,
transaction_version: u32,
nonce: T::Index,
nonce: u64,
genesis_hash: T::Hash,
// Provided externally:
other_params: Self::OtherParams,
Expand All @@ -149,7 +149,7 @@ impl<T: Config, Tip: Debug + Encode + 'static> ExtrinsicParams<T::Index, T::Hash
}

fn encode_extra_to(&self, v: &mut Vec<u8>) {
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);
}
Expand Down
11 changes: 3 additions & 8 deletions subxt/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u64>;

/// The output of the `Hasher` function.
type Hash: Debug
+ Copy
Expand Down Expand Up @@ -57,7 +53,7 @@ pub trait Config: 'static {
type Header: Debug + Header<Hasher = Self::Hasher> + Sync + Send + DeserializeOwned;

/// This type defines the extrinsic extra and additional parameters.
type ExtrinsicParams: extrinsic_params::ExtrinsicParams<Self::Index, Self::Hash>;
type ExtrinsicParams: extrinsic_params::ExtrinsicParams<Self::Hash>;
}

/// This represents the hasher used by a node to hash things like block headers
Expand Down Expand Up @@ -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<T: Config, E: extrinsic_params::ExtrinsicParams<T::Index, T::Hash>> {
pub struct WithExtrinsicParams<T: Config, E: extrinsic_params::ExtrinsicParams<T::Hash>> {
_marker: std::marker::PhantomData<(T, E)>,
}

impl<T: Config, E: extrinsic_params::ExtrinsicParams<T::Index, T::Hash>> Config
impl<T: Config, E: extrinsic_params::ExtrinsicParams<T::Hash>> Config
for WithExtrinsicParams<T, E>
{
type Index = T::Index;
type Hash = T::Hash;
type AccountId = T::AccountId;
type Address = T::Address;
Expand Down
1 change: 0 additions & 1 deletion subxt/src/config/polkadot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub use primitive_types::{H256, U256};
pub enum PolkadotConfig {}

impl Config for PolkadotConfig {
type Index = <SubstrateConfig as Config>::Index;
type Hash = <SubstrateConfig as Config>::Hash;
type AccountId = <SubstrateConfig as Config>::AccountId;
type Address = MultiAddress<Self::AccountId, ()>;
Expand Down
1 change: 0 additions & 1 deletion subxt/src/config/substrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self::AccountId, u32>;
Expand Down
44 changes: 28 additions & 16 deletions subxt/src/tx/tx_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -109,8 +110,8 @@ impl<T: Config, C: OfflineClientT<T>> TxClient<T, C> {
pub fn create_partial_signed_with_nonce<Call>(
&self,
call: &Call,
account_nonce: T::Index,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::OtherParams,
account_nonce: u64,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::OtherParams,
) -> Result<PartialExtrinsic<T, C>, Error>
where
Call: TxPayload,
Expand All @@ -126,7 +127,7 @@ impl<T: Config, C: OfflineClientT<T>> TxClient<T, C> {
let additional_and_extra_params = {
// Obtain spec version and transaction version from the runtime version of the client.
let runtime = self.client.runtime_version();
<T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::new(
<T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::new(
runtime.spec_version,
runtime.transaction_version,
account_nonce,
Expand All @@ -148,8 +149,8 @@ impl<T: Config, C: OfflineClientT<T>> TxClient<T, C> {
&self,
call: &Call,
signer: &Signer,
account_nonce: T::Index,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::OtherParams,
account_nonce: u64,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::OtherParams,
) -> Result<SubmittableExtrinsic<T, C>, Error>
where
Call: TxPayload,
Expand All @@ -175,23 +176,34 @@ where
C: OnlineClientT<T>,
{
/// Get the account nonce for a given account ID.
pub async fn account_nonce(&self, account_id: &T::AccountId) -> Result<T::Index, Error> {
self.client
pub async fn account_nonce(&self, account_id: &T::AccountId) -> Result<u64, Error> {
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.
pub async fn create_partial_signed<Call>(
&self,
call: &Call,
account_id: &T::AccountId,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::OtherParams,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::OtherParams,
) -> Result<PartialExtrinsic<T, C>, Error>
where
Call: TxPayload,
Expand All @@ -205,7 +217,7 @@ where
&self,
call: &Call,
signer: &Signer,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::OtherParams,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::OtherParams,
) -> Result<SubmittableExtrinsic<T, C>, Error>
where
Call: TxPayload,
Expand All @@ -228,7 +240,7 @@ where
where
Call: TxPayload,
Signer: SignerT<T>,
<T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::OtherParams: Default,
<T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::OtherParams: Default,
{
self.sign_and_submit_then_watch(call, signer, Default::default())
.await
Expand All @@ -242,7 +254,7 @@ where
&self,
call: &Call,
signer: &Signer,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::OtherParams,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::OtherParams,
) -> Result<TxProgress<T, C>, Error>
where
Call: TxPayload,
Expand Down Expand Up @@ -272,7 +284,7 @@ where
where
Call: TxPayload,
Signer: SignerT<T>,
<T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::OtherParams: Default,
<T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::OtherParams: Default,
{
self.sign_and_submit(call, signer, Default::default()).await
}
Expand All @@ -289,7 +301,7 @@ where
&self,
call: &Call,
signer: &Signer,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Index, T::Hash>>::OtherParams,
other_params: <T::ExtrinsicParams as ExtrinsicParams<T::Hash>>::OtherParams,
) -> Result<T::Hash, Error>
where
Call: TxPayload,
Expand Down

0 comments on commit c2875de

Please sign in to comment.