-
Notifications
You must be signed in to change notification settings - Fork 432
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
Basic support for dyn Trait
to allow cross-contract calls only with trait
#1673
Conversation
…nd the trait defined via `#[ink::trait_definition]`. Added `From<AccountId>` for the contract builder and forwarder to simplify the usage. Added `AsRev<AccountId>` and `AsMut<AccountId>` for builder, forwarder, and contract_ref to provide the way modify the wrapper.
@@ -132,6 +132,18 @@ impl CallBuilder<'_> { | |||
<AccountId as ::core::clone::Clone>::clone(&self.account_id) | |||
} | |||
} | |||
|
|||
impl ::core::convert::AsRef<AccountId> for #cb_ident { |
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.
<3 such a small change and so much less code on my side :)
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.
Very nice.
Just the question mark of whether we need the $env
arg on the contract_ref!
macro.
@@ -0,0 +1,106 @@ | |||
#![cfg_attr(not(feature = "std"), no_std)] | |||
|
|||
/// We can't run E2E test without the contract. So add `Dummy` contract. |
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.
Is this the same issue as #1672
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.
No, it is another reason. During running of the cargo test --features e2e-tests
ink! tries to build the crate as a contract via cargo-contract
. But if it is not a contract, it will fail because it doesn't have ___ink_generate_metadata
function=)
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.
That seems like a bug, we shouldn't need the metadata anymore for ink_e2e
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.
Anyway we should attempt to make this more ergonomic for structuring e2e
tests in this way
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 prompted me to open #1683 which means it doesn't need to generate the metadata anymore.
Not sure it will make this structure work without the dummy contract, but at least it is an immprovement.
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.
See #1691 for a possible solution
…tract`. Added more examples into documentation
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
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, less code that I would've expected to get something working 💪
I still want to look through the E2E tests a bit more, so I'll do that tomorrow
integration-tests/trait-dyn-cross-contract-calls/traits/Cargo.toml
Outdated
Show resolved
Hide resolved
integration-tests/trait-dyn-cross-contract-calls/contracts/incrementer/Cargo.toml
Show resolved
Hide resolved
integration-tests/trait-dyn-cross-contract-calls/contracts/incrementer-caller/Cargo.toml
Outdated
Show resolved
Hide resolved
crates/env/src/types.rs
Outdated
/// | ||
/// If someone wants to use another type than [`AccountId`] in the [`Environment::AccountId`], | ||
/// he should implement this trait for the corresponding 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.
Why should this be an option? Doesn't that circumvent the whole point of the trait?
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.
We can add the trait AccountIdGuard
as a constraint for the Environment::AccountId
, but in this case, it will be breaking change=) But we will force users to implement it
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.
That doesn't really answer my question though. Why would a user want to implement this for a type other an AccountId
?
If we don't want this, but don't want to introduce a breaking change, then we shouldn't be highlighting the fact that they can implement this trait on other 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.
The user wants to implement it if he uses another type for the Environment::AccountId
than ink::types::AccountId
.
We want this, because it will give the From<AccountId>
implementation to the user. If it is not a problem to add constrain for Environment::AccountId
, I prefer to add it.
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.
Okay I see what you mean now. I'm gonna update the comment to make this more clear
integration-tests/trait-dyn-cross-contract-calls/contracts/incrementer-caller/lib.rs
Outdated
Show resolved
Hide resolved
integration-tests/trait-dyn-cross-contract-calls/contracts/incrementer-caller/lib.rs
Outdated
Show resolved
Hide resolved
integration-tests/trait-dyn-cross-contract-calls/contracts/incrementer-caller/lib.rs
Outdated
Show resolved
Hide resolved
Co-authored-by: Hernando Castano <[email protected]>
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.
Couples questions around the integration tests
integration-tests/trait-dyn-cross-contract-calls/contracts/incrementer/lib.rs
Outdated
Show resolved
Hide resolved
integration-tests/trait-dyn-cross-contract-calls/contracts/incrementer-caller/lib.rs
Outdated
Show resolved
Hide resolved
crates/env/src/types.rs
Outdated
/// | ||
/// If someone wants to use another type than [`AccountId`] in the [`Environment::AccountId`], | ||
/// he should implement this trait for the corresponding 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.
That doesn't really answer my question though. Why would a user want to implement this for a type other an AccountId
?
If we don't want this, but don't want to introduce a breaking change, then we shouldn't be highlighting the fact that they can implement this trait on other types
Co-authored-by: Hernando Castano <[email protected]>
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.
Cool, thanks 💪
@cmichi wants to take a look at this as well, so let's not ape this in just yet |
Please don't merge just yet, I'll take a look this morning as well. |
Normally, when working with Rust, |
With dynamic dispatching, the compiler is unable to optimize the code, and at runtime, it requires additional steps to find the function to execute.
The program will work as usual. Only that can affect the size of the final contract. It may be more or less than without dynamic dispatching(It is based on several factors). BTW, the current solution doesn't use dynamic dispatching=) it is called |
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.
Thank you, Green! Just some doc nitpicks.
Co-authored-by: Michael Müller <[email protected]>
Oh and Green, |
… trait (#1673) * Added `contract_ref!` macro rule that allows to create a wrapper around the trait defined via `#[ink::trait_definition]`. Added `From<AccountId>` for the contract builder and forwarder to simplify the usage. Added `AsRev<AccountId>` and `AsMut<AccountId>` for builder, forwarder, and contract_ref to provide the way modify the wrapper. * Added comments for the method in the example of the `contract_ref!` * Make clippy happy * Make CI happy * Changed the default behaviour to use alias generated by the `ink::contract`. Added more examples into documentation * Apply suggestions from code review Co-authored-by: Hernando Castano <[email protected]> * Apply comments from the PR * Missed the comment * Remove error from the example * Apply suggestions from code review Co-authored-by: Hernando Castano <[email protected]> * Fixed comments from PR * Update comments around `AccountIdGuard` * Apply suggestions from code review Co-authored-by: Michael Müller <[email protected]> * Mentioned the PR in the `Unreleased` section --------- Co-authored-by: Hernando Castano <[email protected]> Co-authored-by: Hernando Castano <[email protected]> Co-authored-by: Michael Müller <[email protected]>
The change uses the ideas from the issue. But instead of
#[ink(dyn)]
proc macro, it uses thecontract_ref!
macro rule.The difference between those approaches is that with
contract_ref!
, we cover all possible use cases of the usage but don't have the highlighting and hinting in the IDEs. While with#[ink(dyn)]
, we would have basic highlighting for methods from the trait in the IDEs, the usage will be specific and limited by the number of supported syntax constructions.The
contract_ref!
doesn't block us from adding#[ink(dyn)]
in the future. We can have both because they use the exact mechanism under the hood.contract_ref!
macro rule that allows creating a wrapper around the trait defined via#[ink::trait_definition]
.From<AccountId>
for the contract builder and forwarder to simplify the usage.AsRef<AccountId>
andAsMut<AccountId>
for builder, forwarder, and contract_ref to provide the way modify the wrapper.