-
Notifications
You must be signed in to change notification settings - Fork 482
Implement new trait definition codegen 🚀 #665
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
Conversation
|
Does the scope of this PR include the "As Storage Entity" functionality from #631? |
Is this a very much needed feature? Actually I would like to try to keep the scope of the initial MVP small. |
That's alright, I was sincerely asking if it's part of it or not, not requesting it to be included. |
The part should open up possibility to add this feature at a later point in time. However, there are still some open questions as to how the storage-related parts should syntactically look like. There are some ways, non of them obviously the best. |
|
Do you have ETA for this cool change?(= |
The latest commit no longer produces compile errors in the new codegen. So the new codegen basically works now. However, plenty of stuff still needs to be implemented. This whole thing is much more than just the new trait system as it will feature quite a bit other stuff, too. Will write about this more soon. The following smart contract works with the latest commit: use ink_lang as ink;
/// Allows to increment and get the current value.
#[ink::trait_definition]
pub trait Increment {
/// Increments the current value of the implementer by 1.
#[ink(message)]
fn inc(&mut self);
/// Returns the current value of the implementer.
#[ink(message)]
fn get(&self) -> u64;
}
/// Allows to reset the current value.
#[ink::trait_definition]
pub trait Reset {
/// Increments the current value of the implementer by 1.
#[ink(message)]
fn reset(&mut self);
}
#[ink::contract]
pub mod incrementer {
use super::{Increment, Reset};
#[ink(storage)]
pub struct Incrementer {
value: u64,
}
impl Incrementer {
/// Creates a new incrementer smart contract initialized with `0`.
#[ink(constructor)]
pub fn new() -> Self {
Self { value: Default::default() }
}
/// Increases the value of the incrementer by the given delta.
#[ink(message)]
pub fn inc_by(&mut self, delta: u64) {
self.value += delta;
}
}
impl Increment for Incrementer {
#[ink(message)]
fn inc(&mut self) {
self.inc_by(1)
}
#[ink(message)]
fn get(&self) -> u64 {
self.value
}
}
impl Reset for Incrementer {
#[ink(message)]
fn reset(&mut self) {
self.value = 0;
}
}
} |
|
Could you describe a little bit how static dependency will work, please? |
Best described by this delegator example: The gist examples already compile on this branch. |
Codecov Report
@@ Coverage Diff @@
## master #665 +/- ##
==========================================
- Coverage 82.75% 79.14% -3.62%
==========================================
Files 191 243 +52
Lines 8239 9128 +889
==========================================
+ Hits 6818 7224 +406
- Misses 1421 1904 +483
Continue to review full report at Codecov.
|
…n-calls # Conflicts: # crates/lang/Cargo.toml # crates/lang/codegen/src/generator/metadata.rs # crates/lang/macro/Cargo.toml # crates/lang/src/env_access.rs # crates/storage/derive/Cargo.toml
Done. However, I just saw that some of the things that have been implemented as side-PRs have not been included properly into the |
ascjones
left a comment
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.
394 / 406
Implements #631.
Implementation TODOs:
TraitUniqueIdand its associated unique ID calculation.TraitCallForwarderForand others.BalanceorAccounIdby themselves.#[ink::contract]#[ink::trait_definition](follow-up Add more UI tests for ink! chain extensions #951)#[ink::chain_extension]ink_langdefinitions into publicreflectand private/hiddencodegenmodules.reflectmodule and definitions can be used by ink! smart contract authors to reflect upon their own smart contract code to a certain extend.codegenmodule is hidden from users and only serves as purpose to provide definitions that can be used by the ink! codegen to enforce some Rust compiler type system based checks on the ink! smart contract code.scale::Decode + 'static.scale::Encode + 'static.Result::Err(_).ink_lang::TraitImplementer<const ID: u32>trait implementations and super traits.payablefor them.payable.<Contract>Refand its API.Overall ink! design:
Remove(Moved to a follow-up PR)ink-as-dependencycrate feature for ink! smart contracts.Add(Moved to a follow-up PR)ink-as-rootcrate feature for ink! smart contracts.MyContract:MyContractwill still be the storage struct. However, it can now additionally be used as static dependency in other smart contracts. Static dependencies can be envisioned as being directly embedded into a smart contract.MyContractRefis pretty much the same of what we had gotten with the oldink-as-dependency. It is a typed thin-wrapper around anAccountIdthat is mirroring the ink! smart contract's API and implemented traits.ink! IR module:
payable:boolmodifier for ink! trait messages.namespace:strmodifier for ink! trait definitions.ink! trait definitions:
#[ink::trait_definition(..)]#[ink(constructor)]definitions in ink! trait definitions.This allows us to later introduce abstractions such as dynamic trait calling. (Not implemented in this PR.)
#[ink::trait_definition(namespace: str)].#[ink(selector: u32)]modifier.ink! trait implementation blocks:
impl MyTrait for MyContract { ... }#[ink(namespace: str)]modifier on ink! trait implementation blocks.namespacemodifier would destroy trait calling invariants.#[ink(selector: u32)]modifier.selectorin trait impl blocks would destroy trait calling invariants.selectorproperty on ink! trait messages in order to guard against the ink! trait definition silently changing theselectorproperty from the respective ink! message. This cannot be used to alter theselectorof an ink! message in an ink! implementation block. If used the selector must match the selector given via the ink! trait definition of the ink! trait message.#[ink(payable: bool)]modifier.payableproperty on ink! trait messages in order to guard against the ink! trait definition silently removing thepayableproperty from the respective ink! message. Applyingpayableon ink! trait message in implementation blocks won't alter the payability of the ink! message.Tests for the implementation:
Miscellaneous changes:
ink_storagetraits.#[ink::contract(..)]macro.#[ink::trait_definition(..)]macro.Drawback of the Implementation
Follow-Ups:
#[ink(payable: bool)]modifier.#[ink(payable = flag:bool)]instead of just#[ink(payable)].value: boolink! attributes work the same to unify user experience.ink-as-dependencyoptional crate feature of ink! smart contracts withink-as-rootcrate feature.ink-as-rootcrate feature just states the opposite.However, it should be totally fine and maybe even useful to have ink! trait definitions as supertraits of other ink! trait definitions.
Oursourced Work
ink! modifiers:
#[ink(..)]#[ink(selector: u32)]to enableu32parseable inputs#[ink(selector = 1)]#[ink(selector = 0x01)]#[ink(selector = "0x00000001)]#[ink(selector: str)].#[ink(selector = "0xC0DECAFE")]is no longer accepted.Use
#[ink(selector = 0xC0DECAFE)]instead.New utility proc. macros
blake2x256,selector_id!andselector_bytes!function-like proc. macros.[u8; 32](blake2x256)[u8; 4](selector_bytes)u32(selector_id)Minor simplifications and code dupe reductions in codegen #938
Improve macro hygiene in message and constructor selector namespace types #936
Misc cleanups in ink! codegen #935
Move ink_lang_macro UI tests into macro-specific folders #934
Refactor and modernize dispatch codegen #933
Add trait-incrementer example smart contract #932
Check namespace argument is identifier #931
Unrestrict parity-scale-codec crate version #930
Expand selectors as hex-encoded literals in metadata #927
Improve SpreadLayout and StorageLayout derive macro hygiene #926