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

[E2E alternative backend]: Backend traits #1857

Merged
merged 24 commits into from
Jul 31, 2023

Conversation

pmikolajczyk41
Copy link
Member

@pmikolajczyk41 pmikolajczyk41 commented Jul 26, 2023

The PR introduces abstraction for all available operations within e2e tests. These actions are broken into two categories:

  • general chain utilities (creating endowed account, checking account's balance, etc.)
  • contract specific operations (code upload, instantiation, calling)

Thus there are two corresponding separate traits: ChainBackend and ContractsBackend that are combined further into E2EBackend.

Notes / dilemmas

Mutability in backend methods

While so far, the subxt-based E2E client could work just on &self, we have to make all backend methods to operate on &mut self. This is because drink! client will have to keep the whole runtime (externalities) by itself and thus any action will mutate its state.

While some workaround might have been done (with some RefCells etc), IMHO it's completely not worth the effort and complication (at least at this stage).

Asynchronicity of backend traits

While drink backend is inherently synchronous, subxt-based one cannot be. Unfortunately I don't know any ethic way of keeping common facade for such two alternatives and thus I made all methods asynchronous. As a result:

  • drink! implementation will be artificially asynchronous, but actually the logic will be instant anyway (there will be no breakpoints in the async state machine)
  • the testcase body stays the same, no matter which backend it uses (this is actually one of the goals)

Breaking E2EBackend into two traits

This is just a matter of taste - for me it is just cleaner to separate general-chain logic from the contract-specific (this is how I did it in drink! as well). However, there are 3 immediate downsides:

  • e2e test module must import two traits
  • there's some redundancy between these traits: they share some associated types, which must be declared twice
  • all the trait bounds must be repeated 3 times

I'm not very dedicated to that support, so if any of the reviewers is in favor of having a single trait, I'm on it.

Awful associated types bounds repetition

Since there are actually 3 impl *Backend for Client, there are 3 long blocks of identical lists of trait bounds for the types within E and C (environment and subxt config). Unfortunately, due to: rust-lang/rust#20671 I cannot do much here (unless we want to include unstable feature of trait_alias).

Actor vs ActorId

In the full context (subxt-based client) we usually have to differentiate between user's account and user's keypair: we use the first one to send tokens there or read its state, and the second one for signing transactions, that are sent to a node. However, in drink! backend, there is no need for signing anything, and thus these two concepts can be collapsed to just a user's account.

Dry-running

I am not sure if dry-running should be a part of the backend trait. It seems useful, but it's not that obvious how it should be implemented for drink!... For now I included it and I will see soon what is possible to do about it in drink!.

@pmikolajczyk41
Copy link
Member Author

@ascjones this is now a half-baked PR, but I wanted kindly ask you if you could take a quick look and tell whether the direction is okay with you; if so, then I will continue with ContractsBackend along the same line

@pmikolajczyk41 pmikolajczyk41 changed the title [E2E alternative backend]: Backend traits [WiP] [E2E alternative backend]: Backend traits Jul 26, 2023
@SkymanOne SkymanOne marked this pull request as draft July 26, 2023 18:17
@SkymanOne
Copy link
Contributor

LMK when it is ready for review, I will convert the PR to ready

Copy link
Collaborator

@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.

Looks good so far, carry on!

Not sure about the name Actor, would be interested to know what the equivalent concrete types are for the Drink! backend. That is a minor detail though.

@pmikolajczyk41 pmikolajczyk41 marked this pull request as ready for review July 27, 2023 21:28
@pmikolajczyk41
Copy link
Member Author

pmikolajczyk41 commented Jul 27, 2023

okay, I'm done for the first iteration now - @SkymanOne @ascjones please take a look :) notice that the PR description has been significantly expanded, hopefully giving some help/insights into some of the decisions that I made on spot

@pmikolajczyk41 pmikolajczyk41 changed the title [WiP] [E2E alternative backend]: Backend traits [E2E alternative backend]: Backend traits Jul 27, 2023
Copy link
Collaborator

@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.

In general this all LGTM.

Another possibility for the interface would be to make it synchronous and adapt the subxt client into sync methods. Though that will require lots of changes to existing tests so let's keep it async for now.

Also if Actor is referring to Account, couldn't we just make the types Account and AccountId?

Anyway, nothing from my side to prevent this PR from being merged. Looking forward to the next one!

@pmikolajczyk41
Copy link
Member Author

I have just merged master and added licenses to the files that I recently created.

Regarding Actor vs Account... it's just my hard discomfort when it comes to semantics :P in the subxt case, type Account = Keypair would look confusing imho; however, if this Actor stings the eyes, I can change it :)

@@ -46,14 +46,24 @@ use ink_env::{
},
Copy link
Contributor

Choose a reason for hiding this comment

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

I am personally not a fun of renaming the file into subxt_client.rs. IMO, it is better either to keep the name client.rs or rename it to the impls.rs like it's done in other ink! crates. Since, all the create provides an implementation for the backend traits

Copy link
Member Author

Choose a reason for hiding this comment

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

I was intending to put drink backend into a separate module (like drink_client.rs) to keep clear isolation of the very different code and hence this renaming. Would you suggest putting everything into a signle client.rs/impls.rs module?

Copy link
Contributor

Choose a reason for hiding this comment

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

If you plan to integrate drink backend in the ink! e2e crate directly, then it makes sense to keep subxt_client.rs name

Copy link
Member Author

Choose a reason for hiding this comment

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

that's the plan, so that a developer when writing tests can only specify which backend they need without worrying about dependencies or imports

Copy link
Contributor

Choose a reason for hiding this comment

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

Then it makes sense to keep the name

Copy link
Contributor

@SkymanOne SkymanOne left a comment

Choose a reason for hiding this comment

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

Looks way better now. Happy to get it merged!

@SkymanOne SkymanOne merged commit fdd164d into use-ink:master Jul 31, 2023
22 checks passed
@pmikolajczyk41 pmikolajczyk41 deleted the pmikolajczyk41/backend-trait branch August 2, 2023 07:02
@SkymanOne SkymanOne mentioned this pull request Mar 4, 2024
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.

None yet

3 participants