Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use my own Config type to instantiate an API #391

Closed
jsdw opened this issue Jan 13, 2022 · 1 comment · Fixed by #409
Closed

Cannot use my own Config type to instantiate an API #391

jsdw opened this issue Jan 13, 2022 · 1 comment · Fixed by #409

Comments

@jsdw
Copy link
Collaborator

jsdw commented Jan 13, 2022

I had a go at trying to create a custom type which implements Config to instantiate an API with, like so:

#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct MyConfig;
impl Config for MyConfig {
    type Index = <DefaultConfig as Config>::Index;
    type BlockNumber = <DefaultConfig as Config>::BlockNumber;
    type Hash = <DefaultConfig as Config>::Hash;
    type Hashing = <DefaultConfig as Config>::Hashing;
    type AccountId = <DefaultConfig as Config>::AccountId;
    type Address = <DefaultConfig as Config>::Address;
    type Header = <DefaultConfig as Config>::Header;
    type Signature = <DefaultConfig as Config>::Signature;
    type Extrinsic = <DefaultConfig as Config>::Extrinsic;
}

let api = ClientBuilder::new()
    .build()
    .await?
    .to_runtime_api::<polkadot::RuntimeApi<MyConfig, DefaultExtra<MyConfig>>>();

(I tried this in the examples/transfer_subscribe.rs example).

My custom type uses the same types that DefaultConfig uses, but when I try to compile this example I run into:

error[E0599]: the method `balances` exists for struct `polkadot::TransactionApi<'_, MyConfig, DefaultExtraWithTxPayment<MyConfig, extrinsic::extra::ChargeTransactionPayment<MyConfig>>, system::storage::Account>`, but its trait bounds were not satisfied
  --> examples/transfer_subscribe.rs:70:10
   |
35 | #[subxt::subxt(runtime_metadata_path = "examples/polkadot_metadata.scale")]
   | ---------------------------------------------------------------------------
   | |
   | method `balances` not found for this
   | doesn't satisfy `_: subxt::AccountData<MyConfig>`
...
70 |         .balances()
   |          ^^^^^^^^ method cannot be called on `polkadot::TransactionApi<'_, MyConfig, DefaultExtraWithTxPayment<MyConfig, extrinsic::extra::ChargeTransactionPayment<MyConfig>>, system::storage::Account>` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `system::storage::Account: subxt::AccountData<MyConfig>`

I believe that the error exists because DefaultConfig is still hardcoded into a bit of the codegen:

pub type DefaultAccountData = self::system::storage::Account;

impl ::subxt::AccountData<::subxt::DefaultConfig> for DefaultAccountData {
    fn nonce(result: &<Self as ::subxt::StorageEntry>::Value) -> <::subxt::DefaultConfig as ::subxt::Config>::Index {
        result.nonce
    }
    fn storage_entry(account_id: <::subxt::DefaultConfig as ::subxt::Config>::AccountId) -> Self {
        Self(account_id)
    }
}

This DefaultAccountData type is passed as a type param to TransactionApi as the param A, which expects:

impl<'a, T, E, A> TransactionApi<'a, T, E, A>
    where
        T: ::subxt::Config,
        E: ::subxt::SignedExtra<T>,
        A: ::subxt::AccountData<T>,

But of course, DefaultAccountData does not implement AccountData for generic configs; only for the DefaultConfig, which prevents other configs being inserted in its place I believe.

::subxt::AccountData does however require that the types it knows about align with those generated from system::storage::Account, and so it's not a simple case of making the impl more generic.

I'm not entirely sure what the best course of action is here; perhaps expose the type inside system::storage::Account and bound uses of Config such that the account ID types line up? But if that were the fix, then why have AccountId in the config at all if it's a hard requirement in the generated code? Likely I am not understanding the reasoning behind this code properly yet.

@jsdw
Copy link
Collaborator Author

jsdw commented Jan 13, 2022

When we resolve this, we should make sure to add at least one example/test using a new config, to make sure it continues to work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant