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

Unify fallible and non fallible instantiate methods #1591

Merged
merged 58 commits into from
Jan 24, 2023

Conversation

ascjones
Copy link
Collaborator

@ascjones ascjones commented Jan 14, 2023

Context: #1512 (comment)

Since #1512 CreateBuilder has 4 different instantiate methods:

instantiate
instantiate_fallible
try_instantiate
try_instantiate_faillble

The use case for this is when we have a "fallible" constructor which returns a Result e.g.

#[ink(constructor)]
pub fn new() -> Result<Self, Error> {
    Ok(Self {})
}

In order to invoke this from another contract, the following is required:

ContractRef::new()
            .code_hash(ink_primitives::Clear::CLEAR_HASH)
            .gas_limit(4000)
            .endowment(25)
            .salt_bytes([0xDE, 0xAD, 0xBE, 0xEF])
            .instantiate_fallible() // must call this because it returns a result.
            .unwrap()

Some issues with this approach:

  1. Requires the user to know which variant of instantiate to call based on the return type of the constructor. Granted it should not compile with the wrong one, but still will cause some friction.
  2. Code duplication all the way down, two versions of each instantiate method.

This PR unifies the instantaite and instantiate_fallible versions of each method call, such that the user only needs to call instantiate or instantiate_fallible, and the CreateBuilder method will return either Result<ContranctRef> or plain ContractRef, depending on the actual return type of the constructor.

See this UI test for the variations of constructor return types.

Copy link
Contributor

@HCastano HCastano left a comment

Choose a reason for hiding this comment

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

Looks interesting 👀

>
where
E: Environment,
Args: scale::Encode,
Salt: AsRef<[u8]>,
ContractError: scale::Decode,
R: InstantiateResult<R>,
ContractRef: FromAccountId<E>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use the E::AccountId type directly?

Copy link
Collaborator Author

@ascjones ascjones Jan 16, 2023

Choose a reason for hiding this comment

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

I did start with that, but would have had to implement some map capability that does id e.g. AccountId -> AccountId and AccountId -> Result<(), AccountId> and it was slightly tricky. Maybe possible but thought it was easier just to call FromAccountId in place to get the thing working.

let contract_err = <<R as InstantiateResult<ContractStorage>>::Error
as scale::Decode>::decode(out_return_value)?;
let err = <R as InstantiateResult<ContractStorage>>::err(contract_err);
Ok(Ok(err))
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I'd use the typedefs here to make it more clear as to which Result is which

Suggested change
Ok(Ok(err))
EnvResult::Ok(ConstructorResult::Ok(err))

1 => {
let contract_err = <<R as InstantiateResult<ContractStorage>>::Error
as scale::Decode>::decode(out_return_value)?;
let err = <R as InstantiateResult<ContractStorage>>::err(contract_err);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let err = <R as InstantiateResult<ContractStorage>>::err(contract_err);
let contract_err = <R as InstantiateResult<ContractStorage>>::err(contract_err);

@HCastano
Copy link
Contributor

@ascjones merging master into this messed up the commit history since #1512 hasn't been updated yet

@codecov-commenter
Copy link

codecov-commenter commented Jan 18, 2023

Codecov Report

Merging #1591 (8c3f65c) into hc-get-lang-error-from-create-builder (1e323f4) will decrease coverage by 0.41%.
The diff coverage is 43.33%.

❗ Current head 8c3f65c differs from pull request most recent head ccf61eb. Consider uploading reports for the commit ccf61eb to get more accurate results

@@                            Coverage Diff                            @@
##           hc-get-lang-error-from-create-builder    #1591      +/-   ##
=========================================================================
- Coverage                                  65.86%   65.45%   -0.41%     
=========================================================================
  Files                                        205      205              
  Lines                                       6330     6285      -45     
=========================================================================
- Hits                                        4169     4114      -55     
- Misses                                      2161     2171      +10     
Impacted Files Coverage Δ
crates/e2e/macro/src/codegen.rs 0.00% <0.00%> (ø)
crates/e2e/src/client.rs 36.36% <0.00%> (-3.64%) ⬇️
crates/e2e/src/lib.rs 25.00% <0.00%> (-8.34%) ⬇️
crates/e2e/src/xts.rs 0.00% <ø> (ø)
crates/env/src/call/call_builder.rs 0.00% <ø> (ø)
crates/env/src/engine/off_chain/test_api.rs 64.70% <ø> (ø)
crates/ink/ir/src/ir/storage_item/mod.rs 0.00% <0.00%> (ø)
crates/ink/macro/src/lib.rs 100.00% <ø> (ø)
crates/ink/src/env_access.rs 9.09% <ø> (ø)
...i/contract/pass/constructor-return-result-alias.rs 50.00% <ø> (-43.88%) ⬇️
... and 21 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@ascjones
Copy link
Collaborator Author

@ascjones merging master into this messed up the commit history since #1512 hasn't been updated yet

Sorry I will fix it.

@ascjones ascjones force-pushed the aj/get-lang-error-from-create-builder branch from ccf61eb to a7a2f7a Compare January 18, 2023 09:53
@ascjones ascjones marked this pull request as ready for review January 20, 2023 16:37
@ascjones ascjones requested a review from cmichi as a code owner January 20, 2023 16:37
@ascjones ascjones changed the title Attempt to unify fallible and non fallible instantiate methods Unify fallible and non fallible instantiate methods Jan 20, 2023
///
/// fn main() {}
/// ```
pub trait ContractEnv {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

These traits have just been copied from ink::reflect so we can use them here in ink_env

Copy link
Contributor

@HCastano HCastano left a comment

Choose a reason for hiding this comment

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

There's still a couple things I want to review, but in general it's looking good 👍

@@ -34,7 +34,7 @@ pub mod constructors_return_value {
}
}

/// A constructor which reverts and fills the output buffer with an erronenously encoded
/// A constructor which reverts and fills the output buffer with an erroneously encoded
Copy link
Contributor

Choose a reason for hiding this comment

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

Lol, awkward that this was spelt erroneously 😅

crates/env/src/call/create_builder.rs Outdated Show resolved Hide resolved
crates/env/src/call/create_builder.rs Outdated Show resolved Hide resolved
crates/env/src/call/create_builder.rs Outdated Show resolved Hide resolved
crates/env/src/call/create_builder.rs Outdated Show resolved Hide resolved
crates/env/src/call/create_builder.rs Outdated Show resolved Hide resolved
crates/env/src/call/create_builder.rs Outdated Show resolved Hide resolved
crates/env/src/call/create_builder.rs Outdated Show resolved Hide resolved
///
/// fn main() {}
/// ```
pub trait ContractEnv {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not related to this PR, but I don't really understand why we don't use the Environment trait directly. E.g why not have T: Environment instead of going through this extra wrapper?

Base automatically changed from hc-get-lang-error-from-create-builder to master January 23, 2023 22:02
@HCastano HCastano force-pushed the aj/get-lang-error-from-create-builder branch from 4dd4a3f to a9c0223 Compare January 24, 2023 01:47
Copy link
Contributor

@HCastano HCastano left a comment

Choose a reason for hiding this comment

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

Thanks for cleaning up the API, looks much better now!

:shipit:

@ascjones ascjones merged commit 59bbd36 into master Jan 24, 2023
@ascjones ascjones deleted the aj/get-lang-error-from-create-builder branch January 24, 2023 19:24
@HCastano HCastano mentioned this pull request Jan 24, 2023
@ascjones ascjones mentioned this pull request Feb 15, 2023
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.

3 participants