-
Notifications
You must be signed in to change notification settings - Fork 254
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
Make sp_core and sp_runtime dependencies optional, and bump to latest #760
Conversation
… (for decoding later)
Ok so there is a feature flag, "substrate-compat", which when enabled will bring in The default Removing Substrate deps seems to shrink the total deps quite a lot: Using a command like Deps with no default features: ~237 A future piece of work could be to provide our own Substrate/Polkadot compatible Signer implementation, so that people could more permanently opt-out of the substrate crates. |
subxt/src/tx/signer.rs
Outdated
impl<T, Pair> PairSigner<T, Pair> | ||
where | ||
T: Config, | ||
T::AccountId: From<SpAccountId32>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You create a PairSigner by passing a Pair implementation whose signature type can provide an sp_runtime::MultiSignature
, where that has a Signer type that can provide back an sp_runtime::AccountId32
. You must be able to convert sp_runtime::AccountId32
into our configured account type, T::AccountId
.
Below you can see that you also need to be able to convert a Pair::Signature
into an sp_runtime::MultiSignature
, and take that into our configured T::Signature
type.
In other words, we use the substrate types as a go-between. I'm hoping that this won't limit the use cases for this type, but I'm not sure offhand so would love to hear any feedback or thoughts here!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll see how hard it is to impl the substrate signer stuff on MultiSignature etc and then maybe we can avoid any intermediate types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up simplifying them a bit and adding a couple of extra From
impls to hopefully make the different signature types in Substrate "just work".
I don't understand this comment, you bumped the substrate dependencies so |
@@ -34,7 +35,6 @@ pub trait Config: 'static { | |||
+ Member | |||
+ serde::de::DeserializeOwned | |||
+ Default | |||
+ AtLeast32Bit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why removed? I guess that trait comes from substrate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah; I basically removed various bits that we didn't actually make use of or care about on the Subxt side. Like, if somebody configures the type wrong (whether it's because it's not 32bit or simply just not what the chain is configured with) it won't work either way, so I didn't see the point of the extra check anyway
subxt/src/rpc/rpc.rs
Outdated
#[derive(Clone, PartialEq, Eq, Debug)] | ||
pub enum DryRunError { | ||
/// The extrinsic will not be included in the block | ||
TransactionValidityError, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a bummer not to get back the reason why the transaction was rejected... but perhaps a PITA to get
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree; what I wasn't sure about when I did this was whether anybody is currently using the full details. The reason I didn't include them all right here was just because it involved bringing a load more types over, including DispatchError, which we already have to handle when submitting transactions and we have special logic to decode it from the metadata, so having a "hard copy" felt wrong.
But maybe we do need more details to be returned here?
subxt/src/utils/multi_address.rs
Outdated
}; | ||
|
||
/// A multi-format address wrapper for on-chain accounts. This is a simplified version ob Substrate's | ||
/// `sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps explain than #[cfg(feature = "substrate-compat")]
is required for converting it sp_runtime::MultiAddress
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I wrote this I was assuming that people could manually convert it if they wanted (because it has the same structure so is easy to see how), and then I added some From things behind substrate-compat
becasue I needed them in the PairSigner impl to keep things simple!
Def worth mentioning substrate-compat here now though yup :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice work, I think this is a fair trade-off but a bit concerned that we have maintain these duplicated types but it should all right.
When it comes to WASM substrate deps is a no-go which is bummer but for WASM it might be possible to use a third-party signer or something.
Unless you are planning to support the signer stuff for WASM as well.
Ah yeah; I just meant that in the past we had issues like |
I think it would be nice to be able to provide some sort of built-in Substrate/Polkadot signing facility without needing the "substrate-compat" feature, if anything just so that all of our exampels and tests can work without said feature/deps, but also just to round things off so that those deps truly are optional and not necessary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Would be nice to have some basic regression tests for the duplicated types so we can catch any changes as early as possible.
@@ -4,7 +4,10 @@ | |||
|
|||
//! Miscellaneous utility helpers. | |||
|
|||
pub mod account_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a big fan of these being grouped together in a module called utils
, I think a more precise name would be better to indicate that these are primitive types from sp
(substrate primitives) crates. Could just be primitives
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was considering where to put them too. Really, they are sortof just "optional types that you can use in Config if you like for easy Substrate/Polkadot compat", so they aren't explicitly a part of any API interface etc.
Perhaps they should be exposed in config::substrate
for that reason?
For now I put them in utils I guess because codegen makes use of "utils" things in general, and they are just helpers to configure a substrate/polkkadot like config. I'm still a bit torn about the above idea also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's tricky, I think it's okay for misc stuff to go in helpers
/utils
namespace but in this case there is a clear category. Maybe config::types
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it helps, they are actually already exposed as config::substrate::AccountId32
etc since they are used for substrate config, so they could also just be exposed from both places? And since they are used in codegen (in a way that I suppose isn't so directly related to the config?), maybe it's justifiable having them exposed in utils also?
But yeah if you prefer them living entirely in config::types or similar I'm happy with that too! I'm just sortof picturing people needing to import them sometimes for transactions, and importing form config
for a type used in a transaction feels a bit weirder maybe
RuntimeEnvironmentUpdated = 8u32, | ||
} | ||
impl Encode for DigestItem { | ||
fn encode(&self) -> Vec<u8> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could add some tests which perform encoding roundtrips of locally defined types with the substrate equivalents (as dev-dependencies). That way we will catch breaking changes to the custom encoding of these types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was actually just mulling over adding such tests now, so yup I'm def on board with this!
// This isn't strictly needed, but to give our AccountId32 a little more usefulness, we also | ||
// implement the logic needed to decode an AccountId32 from an SS58 encoded string. This is exposed | ||
// via a `FromStr` impl. | ||
fn from_ss58check(s: &str) -> Result<Self, FromSs58Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could do with at least one basic unit test to check it works.
subxt/src/config/extrinsic_params.rs
Outdated
@@ -2,19 +2,26 @@ | |||
// This file is dual-licensed as Apache-2.0 or GPL-3.0. | |||
// see LICENSE for license details. | |||
|
|||
//! This module contains a trait which controls the parameters that can must |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//! This module contains a trait which controls the parameters that can must | |
//! This module contains a trait which controls the parameters that must |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @ascjones that grouping sp-*
related things under a dedicated module rather than utils would be great and it'd be also great to have regression tests using Substrate crates as part of dev-dependencies.
Otherwise, looks good - great job!
I've added some tests to cover types (but haven't covered everything; there were various existing types that I was reluctant to pull in more substrate crates to write such tests for, though ultimately that may be exactly what we want to do here! AccountId/MultiAddress/MultiSignature still live in utils, but are exported from I originally thought of keepign all of the "sp" types together, but decided that it would be better to group them not according to whether they are defined in substrate crates, but according to how they are used in subxt (ie some types are duplicated because they are part of the RPC API, some types duplicated because they have some useful functionality that we use internally, some types because they are used in config etc. Ultimately we are aiming for "interface compatibility" anyway, and it just happens that duplicating some types helps us achieve that! Anyway, I hope that for now this is a good place to start! The next step is to look into adding a "native" signer API so we don't need substrate crates at all for basic transaction submitting workflows. Even if such an API exists just as code to show others how to go about signing things, I'd be happy I think. I'll write an issue for this. |
This PR makes
sp_core
andsp_runtime
dependencies optional (opted-in by default). The reasons for doing this are:At the time of writing, the signer stuff still lives in Substrate and so we still depend on sp_core and sp_runtime to provide a
PairSigner
which allows transactions to be signed (which won't be available for now in the WASM builds as a result). This isn't ideal, but porting that logic over seemed more involved offhand and so I opted to avoid it in this first pass. Providing a simple set of signing primitives feels like a good next step though, and would allow us to completely shed our dependencies on sp_core and sp_runtime (and everything that they bring in).