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

Recommended strategy for compat with a specific substrate version? #1621

Open
blakebyrnes opened this issue May 30, 2024 · 3 comments
Open

Comments

@blakebyrnes
Copy link

I'd love a recommendation for how to integrate with specific substrate versions. We're currently linked to a branch release on the polkadot-sdk version. The generated api specification creates classes for boundedVec and many other substrate specific structs, but H256, AccountId32, etc all come from subxt::utils, which means we can't create From/Into converters for them against a locally installed version.

@jsdw
Copy link
Collaborator

jsdw commented May 31, 2024

Hey, thanks for the issue!

Firstly, just for my own benefit, I'd be curious to know how you are using Subxt in conjunction with a version of Substrate? (Often I imagine it would be used as a client in projects that didn't otherwise care about importing Substrate).

If you want to use types exposed in Substrate libraries rather than the Subxt versions, then you have a couple of options:

  • From can't be implemented, but you could implement a custom trait or methods to do the conversion.
  • Use a newtype pattern and create some types like struct H256(subxt::utils::H256) which you can impl From etc on.
  • You can use type substitutes to swap the default types with others (though note that the other types need to implement EncodeAsType and DecodeAsType which many substrate builtins do not): https://docs.rs/subxt/latest/subxt/attr.subxt.html#substitute_typepath---with--. This might work well with the above point; newtype pattern to get From/Intoand then impl#[derive(EncodeAsType,DecodeAsType)]` etc on them as needed and substitute them for the originals.

Type substitutions are always a bit more brittle, because the type you swap must have the same generics and must exactly encode/decode to the original one in order for things not to break (and what if the original type changes in newer codegen for instance). Used with the newtype pattern I'd hope that things should Just Work, though!

@blakebyrnes
Copy link
Author

blakebyrnes commented May 31, 2024

Thanks @jsdw. We have a few client modules for the project (an app, a built-in L2, and a wallet that bridges l2/l1), all of which share a common library.

I thought about newtype pattern, but I have a ton of places to replace it, so was hoping for a better way. I also wasn't sure what that would do for things like polkadot-js interface for account ids and the like. Your idea of only using newtype in the client with some conversions is really interesting though!

This corner of the rust world feels like it's missing something (adding derives to external types and replacing dependency dependencies). Keep hoping there's some pattern I haven't found yet :)

@jsdw
Copy link
Collaborator

jsdw commented May 31, 2024

This corner of the rust world feels like it's missing something (adding derives to external types and replacing dependency dependencies). Keep hoping there's some pattern I haven't found yet :)

Yeah; I'd definitely be open to ideas in this area too! Offhand I can't really think of a better way to manage this sort of thing!

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

No branches or pull requests

2 participants