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

integration with jsonrpsee v2 #214

Merged
merged 17 commits into from
Mar 8, 2021
Merged

integration with jsonrpsee v2 #214

merged 17 commits into from
Mar 8, 2021

Conversation

niklasad1
Copy link
Member

@niklasad1 niklasad1 commented Jan 8, 2021

Integration to update jsonrpsee to v2

The way the proc-macros are designed in substrate-subxt made it not possible to add another trait bound on the client to do:

ClientBuilder<T: Runtime, R: jsonrpsee_types::traits::Client> { ... }

Then the trait is not object safe and doesn't work as a trait object, thus I introduced enum wrapper for Http and WebSocket instead. Another annoyance is that the HTTP client must be spawned on tokio 0.2 or tokio 1 which may be confusing for some users. So one option is to just support WebSocket transport because it's most likely the best option for most users

Kudos to @gregdhill for fixing the embedded substrate to work with jsonrpsee v2

@ascjones
Copy link
Contributor

Nice! My intention is to remove the embedded client and do integration testing via a precompiled substrate node. Ultimately I want this repo as minimially coupled to substrate as possible.

@dvdplm
Copy link
Contributor

dvdplm commented Jan 12, 2021

Nice indeed. Would be good to get this into the hands of users to collect early feedback.

@gregdhill
Copy link
Contributor

We would quite like to still be able to use our embedded node for integration tests FWIW.

@ascjones
Copy link
Contributor

We would quite like to still be able to use our embedded node for integration tests FWIW.

If we do choose to remove it (not decided yet), it will be moved to its own repository.

@gregdhill
Copy link
Contributor

Any progress on this? We're running into a number of issues with jsonrpsee v1 and it would be great to upgrade subxt soon!

@niklasad1
Copy link
Member Author

We could upgrade soon if we could remove the substrate embedded node integration tests because we decided against having an abstract client in jsonrpsee for now

src/rpc.rs Outdated Show resolved Hide resolved
@niklasad1 niklasad1 changed the title hacky integration with jsonrpsee v2 integration with jsonrpsee v2 Mar 3, 2021
@gregdhill
Copy link
Contributor

How would you expect to test parachain integration though? If we were able to leverage full code-generation from the runtime itself I would see this as less of an issue, but in my opinion testing is essential for subxt (and downstream projects) since types are re-declared. I guess the only option would be to spawn a full-node from inside the tests which could make concurrent testing difficult.

page_size: None,
event_type_registry: EventTypeRegistry::new(),
skip_type_sizes_check: false,
}
}

/// Sets the jsonrpsee client.
pub fn set_client<P: Into<jsonrpsee::Client>>(mut self, client: P) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to split this into set_http_client and set_ws_client or so. We currently set the client this way since we require access for custom rpc calls.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally I see no reason why we couldn't pass a mock client that implements these traits, or am I missing something?

Copy link
Member Author

@niklasad1 niklasad1 Mar 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, "you could" but the problem is how the proc macros for frame/Call/Storage is generated I wrote a few lines about it in the PR description.

Basically you would need to change to:

struct ClientBuilder<T: Runtime, Rpc: jsonrpsee::traits::Client> {
 client: Option<Rpc>,
 ....
} 

This type param is then leaked into lower layers and it would require major refactoring which I prefer not do in this PR. Another option is to use traits object Box<dyn jsonrpsee::traits::Client> and that won't work because the trait itself is not object safe.

Thoughts? :)

Copy link
Contributor

@gregdhill gregdhill Mar 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niklasad1 perhaps we can adopt the following approach: #236 (untested)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think? I would be happy to finalize the update if you think it is a viable workaround.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented in the PR but I don't think it will work "out-of-the-box", I will try it out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replied and followed up, took me most day but the embedded client should now work...

@niklasad1
Copy link
Member Author

I guess the only option would be to spawn a full-node from inside the tests which could make concurrent testing difficult.

Yeah, that was my intention but that's a good observation w.r.t to concurrent testing and state on the substrate node

An option might be to mock a substrate node instead but let's hear what @ascjones thinks :)

niklasad1 and others added 5 commits March 4, 2021 11:20
* workaround for embedded subxt client

Signed-off-by: Gregory Hill <gregorydhill@outlook.com>

* increase default channel size on subxt client

Signed-off-by: Gregory Hill <gregorydhill@outlook.com>

* remove client tests due to inference problem on From

Signed-off-by: Gregory Hill <gregorydhill@outlook.com>
@@ -311,108 +489,3 @@ impl<C: ChainSpec + 'static> SubxtClientConfig<C> {
service_config
}
}

#[cfg(test)]
mod tests {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed these tests because of #236 (comment)

src/rpc.rs Outdated Show resolved Hide resolved
@niklasad1 niklasad1 marked this pull request as ready for review March 7, 2021 20:27
Some(c) => c,
None => {
return Some(Err(
RpcError::Custom("RPC subscription dropped".into()).into()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is called from fn submit_and_watch_extrinsic so should return an error there and be fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niklasad1 niklasad1 requested a review from ascjones March 7, 2021 20:36
@@ -434,7 +527,7 @@ impl<T: Runtime> Rpc<T> {
let events_sub = self.subscribe_events().await?;
let mut xt_sub = self.watch_extrinsic(extrinsic).await?;

while let status = xt_sub.next().await {
while let Some(status) = xt_sub.next().await {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might run into paritytech/jsonrpsee#220 when the subscription is dropped, should be fixed soon I have pending PR opened.

@ascjones
Copy link
Contributor

ascjones commented Mar 8, 2021

I guess the only option would be to spawn a full-node from inside the tests which could make concurrent testing difficult.

Yeah, that was my intention but that's a good observation w.r.t to concurrent testing and state on the substrate node

An option might be to mock a substrate node instead but let's hear what @ascjones thinks :)

I had in mind spawning the substrate node, as I have done here: https://github.com/paritytech/cargo-contract/pull/79/files#diff-a0262fea108af44a98cc49e5eb72641963dd816513f2d0a22eb738fcfed55ebeR45.

Then for concurrent testing just generate and fund an account per test, so they can run in parallel, as I have done here: https://github.com/paritytech/substrate-subxt/blob/master/src/frame/contracts.rs#L157

@gregdhill
Copy link
Contributor

I guess the only option would be to spawn a full-node from inside the tests which could make concurrent testing difficult.

Yeah, that was my intention but that's a good observation w.r.t to concurrent testing and state on the substrate node
An option might be to mock a substrate node instead but let's hear what @ascjones thinks :)

I had in mind spawning the substrate node, as I have done here: https://github.com/paritytech/cargo-contract/pull/79/files#diff-a0262fea108af44a98cc49e5eb72641963dd816513f2d0a22eb738fcfed55ebeR45.

Then for concurrent testing just generate and fund an account per test, so they can run in parallel, as I have done here: https://github.com/paritytech/substrate-subxt/blob/master/src/frame/contracts.rs#L157

Account balance isn't the only state I would care about though.

@gregdhill
Copy link
Contributor

@ascjones is this good to merge?

@ascjones
Copy link
Contributor

ascjones commented Mar 8, 2021

Account balance isn't the only state I would care about though.

Would have to spawn a fresh node per test in that case. That would be true for an embedded node too as well as a separate process. Of course you would need to deal with port numbers but that should be straightforward enough. Or just run tests seqentially.

Copy link
Contributor

@ascjones ascjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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 this pull request may close these issues.

4 participants