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

Allow specifying payable constructors #1065

Merged
merged 20 commits into from
Jan 18, 2022
Merged

Conversation

HCastano
Copy link
Contributor

@HCastano HCastano commented Dec 2, 2021

Before this change ink! constructors were payable by default. This was because all
contracts were required to place an endowment in order to stay alive.

However, with the changes introduced in paritytech/substrate#10082 this is no
longer necessary. Instead we can allow users to specify whether or not they want their
constructors to be payable.

We'll need to wait for the Substrate PR to get merged before merging this one. This is
because if we deploy a contract without also initializing it with some value we get a
NewContractNotFunded error.

Closes #1027.

P.S, we'll also want to change endowment to value to be consistent with
pallet-contracts, but that can be done in a follow-up PR.

@HCastano HCastano requested a review from athei December 2, 2021 16:41
@codecov-commenter
Copy link

codecov-commenter commented Dec 2, 2021

Codecov Report

Merging #1065 (aebeb39) into master (d9c17b6) will decrease coverage by 0.17%.
The diff coverage is 58.13%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1065      +/-   ##
==========================================
- Coverage   78.99%   78.82%   -0.18%     
==========================================
  Files         248      251       +3     
  Lines        9346     9384      +38     
==========================================
+ Hits         7383     7397      +14     
- Misses       1963     1987      +24     
Impacted Files Coverage Δ
crates/lang/src/codegen/dispatch/execution.rs 0.00% <0.00%> (ø)
crates/lang/src/reflect/dispatch.rs 0.00% <ø> (ø)
.../tests/ui/contract/pass/constructor-non-payable.rs 28.57% <28.57%> (ø)
...lang/tests/ui/contract/pass/constructor-payable.rs 28.57% <28.57%> (ø)
...s/ui/contract/pass/constructor-payable-multiple.rs 33.33% <33.33%> (ø)
crates/lang/codegen/src/generator/dispatch.rs 94.61% <100.00%> (+0.33%) ⬆️
crates/lang/ir/src/ir/item_impl/constructor.rs 93.84% <100.00%> (+1.53%) ⬆️
...ates/storage/src/collections/hashmap/fuzz_tests.rs 94.68% <0.00%> (-5.32%) ⬇️
crates/lang/ir/src/ir/attrs.rs 82.27% <0.00%> (-0.56%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d9c17b6...aebeb39. Read the comment docs.

athei
athei previously approved these changes Dec 6, 2021
@HCastano
Copy link
Contributor Author

HCastano commented Jan 6, 2022

So UI support for this isn't quite there since polkadot-js/apps#6645 hasn't been tackled, but really the only "gotcha" here for users is that if they specify a value if deploying a contract with a non-payable constructor they get a ContractTrapped error. If we're okay with dealing with that for now I say we merge this.

@athei
Copy link
Contributor

athei commented Jan 7, 2022

Does this PR also includes this information into the metadata? Currently, constructors don't have a payable field.

@ascjones
Copy link
Collaborator

ascjones commented Jan 7, 2022

It doesn't look like it has the extra metadata field, as Jaco says in that issue there should be a V3 metadata for this including the addition of this field.

It would go in this: https://github.com/paritytech/ink/blob/master/crates/metadata/src/specs.rs#L223

@athei athei dismissed their stale review January 7, 2022 10:31

Some changes needed.

@athei
Copy link
Contributor

athei commented Jan 7, 2022

So in this PR we need to:

  • Add the payable field to metadata
  • Bump the metadata version

@HCastano
Copy link
Contributor Author

HCastano commented Jan 7, 2022

It doesn't look like it has the extra metadata field, as Jaco says in that issue there should be a V3 metadata for this including the addition of this field.

It would go in this: https://github.com/paritytech/ink/blob/master/crates/metadata/src/specs.rs#L223

Ah, okay I didn't realize Jaco was referring to the metadata on our end. Sure I can add this

///
/// If no ink! constructor within the same ink! smart contract
/// is payable then this flag will be `true` since the check
/// then is moved before the constructor dispatch as an optimization.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, not happy about this. This possibility of payable being set to true despite no payable constructor seems to be destined for a bug. How about we reflect this information e.g. with an enum here as a wrapper around the bool?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think there was already a small bug here actually. If there were indeed no payable messages for example, we'd never hit this check. Although to be fair, payment would have been denied in call() (maybe this was the optimization alluded to in the comment?).

Either way, this was confusing and I think it's unnecessary so I removed it.

It looks like this was meant to be part of an optimization, however it
doesn't look like this is necessary anymore. If no constructor or
message is payable we already do early deny payment checks in `deploy()`
and `call()` respectively.
@HCastano HCastano requested a review from cmichi January 17, 2022 02:03
@cmichi
Copy link
Collaborator

cmichi commented Jan 17, 2022

Can you create a follow-up issue for ink-docs?

@@ -706,7 +732,6 @@ impl Dispatch<'_> {
);
let accepts_payment = quote_spanned!(message_span=>
false ||
!#any_message_accept_payment ||
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we have a UI test for this: Multiple constructors which are all not payable?

@HCastano
Copy link
Contributor Author

Can you create a follow-up issue for ink-docs?

Done: use-ink/ink-docs#41

@HCastano HCastano merged commit e646ddd into master Jan 18, 2022
@HCastano HCastano deleted the hc-make-constructors-non-payable branch January 18, 2022 03:39
xgreenx pushed a commit to Supercolony-net/ink that referenced this pull request Feb 8, 2022
* Add `payable` constructor support to IR

* Add payable associated type to `DispatchableConstructorInfo`

* Allow constructors to be payable in dispatcher codegen

* Add UI tests

* Remove test related to constructors being implicitly payable

* Add some failing UI tests

* Deny payments on `deploy` if there are no payable constructors

* Appease Clippy

* Deny payments when executing constructors

* `s/message/constructor/g`

* RustFmt

* Address `unnecessary_to_owned` lint

Reference: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned

* Address `needless_borrow` lint

Reference: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

* Make a note about this PR in the RELEASES doc

* Allow `clippy::nonminimal_bool` for `deploy()`

* Remove `any_payable_*` checks from individual Config creation

It looks like this was meant to be part of an optimization, however it
doesn't look like this is necessary anymore. If no constructor or
message is payable we already do early deny payment checks in `deploy()`
and `call()` respectively.

* Add UI test for multiple non-payable constructors
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.

Make constructors (non)payable
5 participants