diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1c8eb760ee3..b82df5b7b98 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,8 +29,8 @@ variables: # CI_IMAGE is changed to "-:staging" when the CI image gets rebuilt # read more https://github.com/paritytech/scripts/pull/244 CI_IMAGE: "paritytech/ink-ci-linux:production" - PURELY_STD_CRATES: "lang/codegen metadata engine" - ALSO_WASM_CRATES: "env storage storage/derive allocator prelude primitives lang lang/macro lang/ir" + PURELY_STD_CRATES: "lang/codegen storage/traits/codegen metadata engine" + ALSO_WASM_CRATES: "env storage storage/traits storage/traits/derive allocator prelude primitives lang lang/macro lang/ir" ALL_CRATES: "${PURELY_STD_CRATES} ${ALSO_WASM_CRATES}" DELEGATOR_SUBCONTRACTS: "accumulator adder subber" UPGRADEABLE_CONTRACTS: "forward-calls set-code-hash" @@ -286,9 +286,9 @@ docs: - ./crate-docs/ script: - cargo doc --no-deps --all-features - -p scale-info -p ink_metadata - -p ink_env -p ink_storage -p ink_storage_derive - -p ink_primitives -p ink_prelude -p ink_primitives_derive + -p scale-info -p ink_metadata -p ink_env + -p ink_storage -p ink_storage_traits -p ink_storage_codegen -p ink_storage_derive + -p ink_primitives -p ink_prelude -p ink_lang -p ink_lang_macro -p ink_lang_ir -p ink_lang_codegen - mv ${CARGO_TARGET_DIR}/doc ./crate-docs # FIXME: remove me after CI image gets nonroot diff --git a/Cargo.toml b/Cargo.toml index 154fbd1a1ae..c1328bf0f77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,8 @@ members = [ "crates/engine", "crates/env", "crates/storage", - "crates/storage/derive", + "crates/storage/traits", + "crates/storage/traits/derive", ] exclude = [ "examples/", diff --git a/crates/engine/Cargo.toml b/crates/engine/Cargo.toml index 83ae5fcf2fe..58effb5f8bd 100644 --- a/crates/engine/Cargo.toml +++ b/crates/engine/Cargo.toml @@ -15,6 +15,7 @@ categories = ["no-std", "embedded"] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [dependencies] +ink_primitives = { path = "../../crates/primitives", default-features = false } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full"] } derive_more = { version = "0.99", default-features = false, features = ["from", "display"] } diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index 361d98a6cb8..6c49cff2a1a 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -15,10 +15,11 @@ categories = ["no-std", "embedded"] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [dependencies] -ink_metadata = { version = "4.0.0-alpha.1", path = "../metadata/", default-features = false, features = ["derive"], optional = true } -ink_allocator = { version = "4.0.0-alpha.1", path = "../allocator/", default-features = false } -ink_primitives = { version = "4.0.0-alpha.1", path = "../primitives/", default-features = false } -ink_prelude = { version = "4.0.0-alpha.1", path = "../prelude/", default-features = false } +ink_metadata = { version = "4.0.0-alpha.1", path = "../metadata", default-features = false, features = ["derive"], optional = true } +ink_allocator = { version = "4.0.0-alpha.1", path = "../allocator", default-features = false } +ink_storage_traits = { version = "4.0.0-alpha.1", path = "../storage/traits", default-features = false } +ink_prelude = { version = "4.0.0-alpha.1", path = "../prelude", default-features = false } +ink_primitives = { version = "4.0.0-alpha.1", path = "../primitives", default-features = false } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full"] } derive_more = { version = "0.99", default-features = false, features = ["from", "display"] } @@ -56,6 +57,7 @@ std = [ "ink_allocator/std", "ink_prelude/std", "ink_primitives/std", + "ink_storage_traits/std", "ink_engine/std", "scale/std", "scale-info/std", diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index 55be2856775..ad664b9945b 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -39,7 +39,7 @@ use crate::{ Environment, Result, }; -use ink_primitives::traits::Storable; +use ink_storage_traits::Storable; /// Returns the address of the caller of the executed contract. /// diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index 30313bb7879..8b9972104d6 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -27,7 +27,7 @@ use crate::{ Environment, Result, }; -use ink_primitives::traits::Storable; +use ink_storage_traits::Storable; /// The flags to indicate further information about the end of a contract execution. #[derive(Default)] diff --git a/crates/env/src/call/call_builder.rs b/crates/env/src/call/call_builder.rs index f9149fe5ea3..60c051f879d 100644 --- a/crates/env/src/call/call_builder.rs +++ b/crates/env/src/call/call_builder.rs @@ -24,11 +24,11 @@ use crate::{ ExecutionInput, }, types::Gas, - Clear, Environment, Error, }; use core::marker::PhantomData; +use ink_primitives::Clear; use num_traits::Zero; /// The final parameters to the cross-contract call. @@ -222,9 +222,9 @@ where /// # use ::ink_env::{ /// # Environment, /// # DefaultEnvironment, -/// # Clear, /// # call::{build_call, Selector, ExecutionInput, utils::ReturnType, DelegateCall}, /// # }; +/// # use ink_primitives::Clear; /// # type AccountId = ::AccountId; /// let my_return_value: i32 = build_call::() /// .call_type(DelegateCall::new() diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index 8d53540fdc1..6d668ca72b8 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -44,7 +44,7 @@ use ink_engine::{ ext, ext::Engine, }; -use ink_primitives::traits::Storable; +use ink_storage_traits::Storable; /// The capacity of the static buffer. /// This is the same size as the ink! on-chain environment. We chose to use the same size diff --git a/crates/env/src/engine/on_chain/buffer.rs b/crates/env/src/engine/on_chain/buffer.rs index ea5b46d97c6..937c9e9894c 100644 --- a/crates/env/src/engine/on_chain/buffer.rs +++ b/crates/env/src/engine/on_chain/buffer.rs @@ -175,12 +175,12 @@ impl<'a> ScopedBuffer<'a> { #[inline(always)] pub fn take_storable_encoded(&mut self, value: &T) -> &'a mut [u8] where - T: ink_primitives::traits::Storable, + T: ink_storage_traits::Storable, { debug_assert_eq!(self.offset, 0); let buffer = core::mem::take(&mut self.buffer); let mut encode_scope = EncodeScope::from(buffer); - ink_primitives::traits::Storable::encode(value, &mut encode_scope); + ink_storage_traits::Storable::encode(value, &mut encode_scope); let encode_len = encode_scope.len(); let _ = core::mem::replace(&mut self.buffer, encode_scope.into_buffer()); self.take(encode_len) diff --git a/crates/env/src/engine/on_chain/impls.rs b/crates/env/src/engine/on_chain/impls.rs index ee97116f890..85d7c5f5475 100644 --- a/crates/env/src/engine/on_chain/impls.rs +++ b/crates/env/src/engine/on_chain/impls.rs @@ -46,7 +46,7 @@ use crate::{ ReturnFlags, TypedEnvBackend, }; -use ink_primitives::traits::Storable; +use ink_storage_traits::Storable; impl CryptoHash for Blake2x128 { fn hash(input: &[u8], output: &mut ::Type) { diff --git a/crates/env/src/lib.rs b/crates/env/src/lib.rs index 306b6ea774e..f02ca57ca78 100644 --- a/crates/env/src/lib.rs +++ b/crates/env/src/lib.rs @@ -100,15 +100,13 @@ pub use self::{ }, topics::Topics, types::{ - AccountId, - Clear, DefaultEnvironment, Environment, FromLittleEndian, - Hash, NoChainExtension, }, }; +use ink_primitives::Clear; cfg_if::cfg_if! { if #[cfg(any(feature = "ink-debug", feature = "std"))] { diff --git a/crates/env/src/types.rs b/crates/env/src/types.rs index 4168d8fb8fc..a8f60f04bd1 100644 --- a/crates/env/src/types.rs +++ b/crates/env/src/types.rs @@ -32,11 +32,10 @@ //! the trait bounds on the `Environment` trait types. use super::arithmetic::AtLeast32BitUnsigned; -use core::array::TryFromSliceError; -use derive_more::From; -use scale::{ - Decode, - Encode, +use ink_primitives::{ + AccountId, + Clear, + Hash, }; #[cfg(feature = "std")] use scale_info::TypeInfo; @@ -194,138 +193,3 @@ pub type Gas = u64; /// The default block number type. pub type BlockNumber = u32; - -/// The default environment `AccountId` type. -/// -/// # Note -/// -/// This is a mirror of the `AccountId` type used in the default configuration -/// of PALLET contracts. -#[derive( - Debug, - Copy, - Clone, - PartialEq, - Eq, - Ord, - PartialOrd, - Hash, - Encode, - Decode, - From, - Default, -)] -#[cfg_attr(feature = "std", derive(TypeInfo))] -pub struct AccountId([u8; 32]); - -impl AsRef<[u8; 32]> for AccountId { - #[inline] - fn as_ref(&self) -> &[u8; 32] { - &self.0 - } -} - -impl AsMut<[u8; 32]> for AccountId { - #[inline] - fn as_mut(&mut self) -> &mut [u8; 32] { - &mut self.0 - } -} - -impl AsRef<[u8]> for AccountId { - #[inline] - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for AccountId { - #[inline] - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -impl<'a> TryFrom<&'a [u8]> for AccountId { - type Error = TryFromSliceError; - - fn try_from(bytes: &'a [u8]) -> Result { - let address = <[u8; 32]>::try_from(bytes)?; - Ok(Self(address)) - } -} - -/// The default environment `Hash` type. -/// -/// # Note -/// -/// This is a mirror of the `Hash` type used in the default configuration -/// of PALLET contracts. -#[derive( - Debug, - Copy, - Clone, - PartialEq, - Eq, - Ord, - PartialOrd, - Hash, - Encode, - Decode, - From, - Default, -)] -#[cfg_attr(feature = "std", derive(TypeInfo))] -pub struct Hash([u8; 32]); - -impl<'a> TryFrom<&'a [u8]> for Hash { - type Error = TryFromSliceError; - - fn try_from(bytes: &'a [u8]) -> Result { - let address = <[u8; 32]>::try_from(bytes)?; - Ok(Self(address)) - } -} - -impl AsRef<[u8]> for Hash { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } -} - -impl AsMut<[u8]> for Hash { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0[..] - } -} - -/// The equivalent of `Zero` for hashes. -/// -/// A hash that consists only of 0 bits is clear. -pub trait Clear { - /// Returns `true` if the hash is clear. - fn is_clear(&self) -> bool; - - /// Returns a clear hash. - fn clear() -> Self; -} - -impl Clear for [u8; 32] { - fn is_clear(&self) -> bool { - self.as_ref().iter().all(|&byte| byte == 0x00) - } - - fn clear() -> Self { - [0x00; 32] - } -} - -impl Clear for Hash { - fn is_clear(&self) -> bool { - <[u8; 32] as Clear>::is_clear(&self.0) - } - - fn clear() -> Self { - Self(<[u8; 32] as Clear>::clear()) - } -} diff --git a/crates/lang/codegen/src/generator/storage_item.rs b/crates/lang/codegen/src/generator/storage_item.rs index 0a183d69e1a..d7061d2ff36 100644 --- a/crates/lang/codegen/src/generator/storage_item.rs +++ b/crates/lang/codegen/src/generator/storage_item.rs @@ -63,7 +63,7 @@ impl GenerateCode for StorageItem<'_> { #[derive( ::ink_storage::traits::StorableHint, ::ink_storage::traits::StorageKey, - ::ink_primitives::traits::Storable, + ::ink_storage::traits::Storable, )] }; } diff --git a/crates/lang/ir/Cargo.toml b/crates/lang/ir/Cargo.toml index 3e89ad57424..6e71ad7ae23 100644 --- a/crates/lang/ir/Cargo.toml +++ b/crates/lang/ir/Cargo.toml @@ -18,7 +18,7 @@ include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] name = "ink_lang_ir" [dependencies] -ink_storage_codegen = { version = "4.0.0-alpha.1", path = "../../storage/codegen" } +ink_storage_codegen = { version = "4.0.0-alpha.1", path = "../../storage/traits/codegen" } quote = "1" syn = { version = "1.0", features = ["parsing", "full", "visit", "extra-traits"] } proc-macro2 = "1.0" diff --git a/crates/lang/macro/src/lib.rs b/crates/lang/macro/src/lib.rs index 1b588eace2c..bf37a8438fc 100644 --- a/crates/lang/macro/src/lib.rs +++ b/crates/lang/macro/src/lib.rs @@ -704,7 +704,7 @@ pub fn trait_definition(attr: TokenStream, item: TokenStream) -> TokenStream { /// StorageKey, /// StorableHint, /// }; -/// use ink_primitives::traits::Storable; +/// use ink_storage::traits::Storable; /// /// // Deriving `scale::Decode` and `scale::Encode` also derives blanket implementation of all /// // required traits to be storable. @@ -796,7 +796,7 @@ pub fn trait_definition(attr: TokenStream, item: TokenStream) -> TokenStream { /// StorableHint, /// StorageKey, /// }; -/// use ink_primitives::traits::Storable; +/// use ink_storage::traits::Storable; /// /// #[ink_lang::storage_item(derive = false)] /// #[derive(StorableHint, Storable, StorageKey)] diff --git a/crates/lang/src/codegen/dispatch/execution.rs b/crates/lang/src/codegen/dispatch/execution.rs index 915d4a98a3d..f169440b497 100644 --- a/crates/lang/src/codegen/dispatch/execution.rs +++ b/crates/lang/src/codegen/dispatch/execution.rs @@ -24,8 +24,10 @@ use ink_env::{ Environment, ReturnFlags, }; -use ink_primitives::traits::Storable; -use ink_storage::traits::StorageKey; +use ink_storage::traits::{ + Storable, + StorageKey, +}; use scale::Encode; /// Returns `Ok` if the caller did not transfer additional value to the callee. diff --git a/crates/lang/src/env_access.rs b/crates/lang/src/env_access.rs index 84e4cb02963..6927eefe84f 100644 --- a/crates/lang/src/env_access.rs +++ b/crates/lang/src/env_access.rs @@ -565,9 +565,9 @@ where /// # pub mod my_contract { /// use ink_env::{ /// DefaultEnvironment, - /// Clear, /// call::{build_call, DelegateCall, Selector, ExecutionInput, utils::ReturnType} /// }; + /// use ink_primitives::Clear; /// /// # /// # #[ink(storage)] diff --git a/crates/lang/tests/ui/storage_item/fail/collections_only_packed_1.stderr b/crates/lang/tests/ui/storage_item/fail/collections_only_packed_1.stderr index 1b428dcbd0d..97194709e9b 100644 --- a/crates/lang/tests/ui/storage_item/fail/collections_only_packed_1.stderr +++ b/crates/lang/tests/ui/storage_item/fail/collections_only_packed_1.stderr @@ -39,11 +39,11 @@ note: required because it appears within the type `Contract` 10 | struct Contract { | ^^^^^^^^ note: required by a bound in `Storable` - --> $WORKSPACE/crates/primitives/src/traits.rs + --> $WORKSPACE/crates/storage/traits/src/storage.rs | | pub trait Storable: Sized { | ^^^^^ required by this bound in `Storable` - = note: this error originates in the derive macro `::ink_primitives::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `::ink_storage::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `[NonPacked]: Encode` is not satisfied --> tests/ui/storage_item/fail/collections_only_packed_1.rs:9:1 @@ -64,11 +64,11 @@ note: required because it appears within the type `Contract` 10 | struct Contract { | ^^^^^^^^ note: required by a bound in `Storable` - --> $WORKSPACE/crates/primitives/src/traits.rs + --> $WORKSPACE/crates/storage/traits/src/storage.rs | | pub trait Storable: Sized { | ^^^^^ required by this bound in `Storable` - = note: this error originates in the derive macro `::ink_primitives::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `::ink_storage::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `Vec: Decode` is not satisfied --> tests/ui/storage_item/fail/collections_only_packed_1.rs:9:1 @@ -90,7 +90,7 @@ note: required by a bound in `Result` | | pub enum Result { | ^ required by this bound in `Result` - = note: this error originates in the derive macro `::ink_primitives::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `::ink_storage::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `[NonPacked]: Encode` is not satisfied --> tests/ui/storage_item/fail/collections_only_packed_1.rs:9:1 @@ -115,4 +115,4 @@ note: required by a bound in `Result` | | pub enum Result { | ^ required by this bound in `Result` - = note: this error originates in the derive macro `::ink_primitives::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `::ink_storage::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/lang/tests/ui/storage_item/fail/collections_only_packed_2.stderr b/crates/lang/tests/ui/storage_item/fail/collections_only_packed_2.stderr index adad5be766b..cdcae3115d7 100644 --- a/crates/lang/tests/ui/storage_item/fail/collections_only_packed_2.stderr +++ b/crates/lang/tests/ui/storage_item/fail/collections_only_packed_2.stderr @@ -36,11 +36,11 @@ note: required because it appears within the type `Contract` 10 | struct Contract { | ^^^^^^^^ note: required by a bound in `Storable` - --> $WORKSPACE/crates/primitives/src/traits.rs + --> $WORKSPACE/crates/storage/traits/src/storage.rs | | pub trait Storable: Sized { | ^^^^^ required by this bound in `Storable` - = note: this error originates in the derive macro `::ink_primitives::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `::ink_storage::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `BTreeMap: Encode` is not satisfied --> tests/ui/storage_item/fail/collections_only_packed_2.rs:9:1 @@ -58,11 +58,11 @@ note: required because it appears within the type `Contract` 10 | struct Contract { | ^^^^^^^^ note: required by a bound in `Storable` - --> $WORKSPACE/crates/primitives/src/traits.rs + --> $WORKSPACE/crates/storage/traits/src/storage.rs | | pub trait Storable: Sized { | ^^^^^ required by this bound in `Storable` - = note: this error originates in the derive macro `::ink_primitives::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `::ink_storage::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `BTreeMap: Decode` is not satisfied --> tests/ui/storage_item/fail/collections_only_packed_2.rs:9:1 @@ -84,7 +84,7 @@ note: required by a bound in `Result` | | pub enum Result { | ^ required by this bound in `Result` - = note: this error originates in the derive macro `::ink_primitives::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `::ink_storage::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `BTreeMap: Encode` is not satisfied --> tests/ui/storage_item/fail/collections_only_packed_2.rs:9:1 @@ -106,4 +106,4 @@ note: required by a bound in `Result` | | pub enum Result { | ^ required by this bound in `Result` - = note: this error originates in the derive macro `::ink_primitives::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the derive macro `::ink_storage::traits::Storable` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/lang/tests/ui/storage_item/pass/argument_derive_false.rs b/crates/lang/tests/ui/storage_item/pass/argument_derive_false.rs index 2c7aaa4b614..4eeb021a841 100644 --- a/crates/lang/tests/ui/storage_item/pass/argument_derive_false.rs +++ b/crates/lang/tests/ui/storage_item/pass/argument_derive_false.rs @@ -1,4 +1,4 @@ -use ink_primitives::traits::Storable; +use ink_storage::traits::Storable; use ink_storage::traits::{ ManualKey, StorageKey, diff --git a/crates/lang/tests/ui/storage_item/pass/complex_packed_enum.rs b/crates/lang/tests/ui/storage_item/pass/complex_packed_enum.rs index a65bfeb7374..9ddd1f8e17b 100644 --- a/crates/lang/tests/ui/storage_item/pass/complex_packed_enum.rs +++ b/crates/lang/tests/ui/storage_item/pass/complex_packed_enum.rs @@ -5,7 +5,7 @@ use ink_prelude::{ }, vec::Vec, }; -use ink_primitives::traits::Storable; +use ink_storage::traits::Storable; #[derive(Default, PartialEq, Eq, PartialOrd, Ord, scale::Encode, scale::Decode)] #[cfg_attr( diff --git a/crates/lang/tests/ui/storage_item/pass/complex_packed_struct.rs b/crates/lang/tests/ui/storage_item/pass/complex_packed_struct.rs index f868ab3ae1b..fbaba78312e 100644 --- a/crates/lang/tests/ui/storage_item/pass/complex_packed_struct.rs +++ b/crates/lang/tests/ui/storage_item/pass/complex_packed_struct.rs @@ -5,7 +5,7 @@ use ink_prelude::{ }, vec::Vec, }; -use ink_primitives::traits::Storable; +use ink_storage::traits::Storable; #[derive(Default, PartialEq, Eq, PartialOrd, Ord, scale::Encode, scale::Decode)] #[cfg_attr( diff --git a/crates/lang/tests/ui/storage_item/pass/packed_tuple_struct.rs b/crates/lang/tests/ui/storage_item/pass/packed_tuple_struct.rs index eccac53a487..7d265a835fd 100644 --- a/crates/lang/tests/ui/storage_item/pass/packed_tuple_struct.rs +++ b/crates/lang/tests/ui/storage_item/pass/packed_tuple_struct.rs @@ -1,4 +1,4 @@ -use ink_primitives::traits::Storable; +use ink_storage::traits::Storable; #[derive(Default, scale::Encode, scale::Decode)] #[cfg_attr( diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index ba22a5db0a1..143ab280654 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -15,13 +15,12 @@ categories = ["no-std", "embedded"] include = ["/Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"] [dependencies] +derive_more = { version = "0.99", default-features = false, features = ["from", "display"] } ink_prelude = { version = "4.0.0-alpha.1", path = "../prelude/", default-features = false } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full"] } scale-info = { version = "2", default-features = false, features = ["derive"], optional = true } sha2-const = { version = "0.1.2", default-features = false } -ink_primitives_derive = { version = "4.0.0-alpha.1", path = "derive", default-features = false } - [features] default = ["std"] std = [ diff --git a/crates/primitives/derive/src/lib.rs b/crates/primitives/derive/src/lib.rs deleted file mode 100644 index 57ad3981d6c..00000000000 --- a/crates/primitives/derive/src/lib.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Custom derive for `ink_storage` traits. -//! -//! This crate provides helpers to define your very own custom storage data -//! structures that work along the `ink_storage` data structures. - -extern crate proc_macro; - -mod storable; - -#[cfg(test)] -mod tests; - -use self::storable::storable_derive; -synstructure::decl_derive!( - [Storable] => - /// Derives `ink_storage`'s `Storable` trait for the given `struct`, `enum` or `union`. - /// - /// # Examples - /// - /// ``` - /// use ink_primitives::traits::Storable; - /// - /// #[derive(Storable)] - /// struct NamedFields { - /// a: u32, - /// b: [u32; 1], - /// } - /// - /// let value = ::decode(&mut &[123, 123][..]); - /// ``` - storable_derive -); diff --git a/crates/primitives/derive/src/tests/mod.rs b/crates/primitives/derive/src/tests/mod.rs deleted file mode 100644 index a8562ff642f..00000000000 --- a/crates/primitives/derive/src/tests/mod.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -mod storable; - -#[macro_export] -macro_rules! test_derive { - ($name:path { $($i:tt)* } expands to { $($o:tt)* }) => { - { - #[allow(dead_code)] - fn ensure_compiles() { - $($i)* - $($o)* - } - - $crate::test_derive!($name { $($i)* } expands to { $($o)* } no_build); - } - }; - - ($name:path { $($i:tt)* } expands to { $($o:tt)* } no_build) => { - { - let i = stringify!( $($i)* ); - let parsed = ::syn::parse_str::<::syn::DeriveInput>(i) - .expect(concat!( - "Failed to parse input to `#[derive(", - stringify!($name), - ")]`", - )); - - let res = $name(::synstructure::Structure::new(&parsed)); - - let expected = quote::quote!( $($o)* ); - assert_eq!(expected.to_string(), res.to_string()); - } - }; -} diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 53c0f414470..bc9fa2ae37d 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -24,9 +24,16 @@ #![cfg_attr(not(feature = "std"), no_std)] mod key; -pub mod traits; +mod types; -pub use self::key::{ - Key, - KeyComposer, +pub use self::{ + key::{ + Key, + KeyComposer, + }, + types::{ + AccountId, + Clear, + Hash, + }, }; diff --git a/crates/primitives/src/traits.rs b/crates/primitives/src/traits.rs deleted file mode 100644 index 1832c77ed1a..00000000000 --- a/crates/primitives/src/traits.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub use ink_primitives_derive::Storable; - -/// Trait for representing types which can be read and written to storage. -/// -/// This trait is not the same as the `scale::Encode + scale::Decode`. Each type that implements -/// `scale::Encode + scale::Decode` are storable by default and transferable between contracts. -/// But not each storable type is transferable. -pub trait Storable: Sized { - /// Convert self to a slice and append it to the destination. - fn encode(&self, dest: &mut T); - - /// Attempt to deserialize the value from input. - fn decode(input: &mut I) -> Result; -} - -/// Types which implement `scale::Encode` and `scale::Decode` are `Storable` by default because -/// they can be written directly into the storage cell. -impl

Storable for P -where - P: scale::Encode + scale::Decode, -{ - #[inline] - fn encode(&self, dest: &mut T) { - scale::Encode::encode_to(self, dest) - } - - #[inline] - fn decode(input: &mut I) -> Result { - scale::Decode::decode(input) - } -} diff --git a/crates/primitives/src/types.rs b/crates/primitives/src/types.rs new file mode 100644 index 00000000000..e6645ac0f55 --- /dev/null +++ b/crates/primitives/src/types.rs @@ -0,0 +1,157 @@ +// Copyright 2018-2022 Parity Technologies (UK) Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use core::array::TryFromSliceError; +use derive_more::From; +use scale::{ + Decode, + Encode, +}; +#[cfg(feature = "std")] +use scale_info::TypeInfo; + +/// The default environment `AccountId` type. +/// +/// # Note +/// +/// This is a mirror of the `AccountId` type used in the default configuration +/// of PALLET contracts. +#[derive( + Debug, + Copy, + Clone, + PartialEq, + Eq, + Ord, + PartialOrd, + Hash, + Encode, + Decode, + From, + Default, +)] +#[cfg_attr(feature = "std", derive(TypeInfo))] +pub struct AccountId([u8; 32]); + +impl AsRef<[u8; 32]> for AccountId { + #[inline] + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl AsMut<[u8; 32]> for AccountId { + #[inline] + fn as_mut(&mut self) -> &mut [u8; 32] { + &mut self.0 + } +} + +impl AsRef<[u8]> for AccountId { + #[inline] + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for AccountId { + #[inline] + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +impl<'a> TryFrom<&'a [u8]> for AccountId { + type Error = TryFromSliceError; + + fn try_from(bytes: &'a [u8]) -> Result { + let address = <[u8; 32]>::try_from(bytes)?; + Ok(Self(address)) + } +} + +/// The default environment `Hash` type. +/// +/// # Note +/// +/// This is a mirror of the `Hash` type used in the default configuration +/// of PALLET contracts. +#[derive( + Debug, + Copy, + Clone, + PartialEq, + Eq, + Ord, + PartialOrd, + Hash, + Encode, + Decode, + From, + Default, +)] +#[cfg_attr(feature = "std", derive(TypeInfo))] +pub struct Hash([u8; 32]); + +impl<'a> TryFrom<&'a [u8]> for Hash { + type Error = TryFromSliceError; + + fn try_from(bytes: &'a [u8]) -> Result { + let hash = <[u8; 32]>::try_from(bytes)?; + Ok(Self(hash)) + } +} + +impl AsRef<[u8]> for Hash { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl AsMut<[u8]> for Hash { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.0[..] + } +} + +/// The equivalent of `Zero` for hashes. +/// +/// A hash that consists only of 0 bits is clear. +pub trait Clear { + /// Returns `true` if the hash is clear. + fn is_clear(&self) -> bool; + + /// Returns a clear hash. + fn clear() -> Self; +} + +impl Clear for [u8; 32] { + fn is_clear(&self) -> bool { + self.as_ref().iter().all(|&byte| byte == 0x00) + } + + fn clear() -> Self { + [0x00; 32] + } +} + +impl Clear for Hash { + fn is_clear(&self) -> bool { + <[u8; 32] as Clear>::is_clear(&self.0) + } + + fn clear() -> Self { + Self(<[u8; 32] as Clear>::clear()) + } +} diff --git a/crates/storage/Cargo.toml b/crates/storage/Cargo.toml index e50ab8b8d44..8815d157380 100644 --- a/crates/storage/Cargo.toml +++ b/crates/storage/Cargo.toml @@ -18,7 +18,7 @@ include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] ink_env = { version = "4.0.0-alpha.1", path = "../env/", default-features = false } ink_metadata = { version = "4.0.0-alpha.1", path = "../metadata/", default-features = false, features = ["derive"], optional = true } ink_primitives = { version = "4.0.0-alpha.1", path = "../primitives/", default-features = false } -ink_storage_derive = { version = "4.0.0-alpha.1", path = "derive", default-features = false } +ink_storage_traits = { version = "4.0.0-alpha.1", path = "traits", default-features = false } ink_prelude = { version = "4.0.0-alpha.1", path = "../prelude/", default-features = false } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full"] } @@ -31,7 +31,6 @@ array-init = { version = "2.0", default-features = false } quickcheck = "1.0" quickcheck_macros = "1.0" itertools = "0.10" -paste = "1.0" ink_lang = { path = "../lang", default-features = false } @@ -42,6 +41,7 @@ std = [ "ink_env/std", "ink_prelude/std", "ink_primitives/std", + "ink_storage_traits/std", "scale/std", "scale-info/std", ] diff --git a/crates/storage/codegen/LICENSE b/crates/storage/codegen/LICENSE deleted file mode 120000 index 5853aaea53b..00000000000 --- a/crates/storage/codegen/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/crates/storage/codegen/README.md b/crates/storage/codegen/README.md deleted file mode 120000 index 8a33348c7d8..00000000000 --- a/crates/storage/codegen/README.md +++ /dev/null @@ -1 +0,0 @@ -../../../README.md \ No newline at end of file diff --git a/crates/storage/derive/LICENSE b/crates/storage/derive/LICENSE deleted file mode 120000 index 5853aaea53b..00000000000 --- a/crates/storage/derive/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/crates/storage/derive/README.md b/crates/storage/derive/README.md deleted file mode 120000 index 8a33348c7d8..00000000000 --- a/crates/storage/derive/README.md +++ /dev/null @@ -1 +0,0 @@ -../../../README.md \ No newline at end of file diff --git a/crates/storage/src/lazy/mapping.rs b/crates/storage/src/lazy/mapping.rs index 4a933866264..32ed82549b6 100644 --- a/crates/storage/src/lazy/mapping.rs +++ b/crates/storage/src/lazy/mapping.rs @@ -26,10 +26,8 @@ use crate::traits::{ StorageKey, }; use core::marker::PhantomData; -use ink_primitives::{ - traits::Storable, - Key, -}; +use ink_primitives::Key; +use ink_storage_traits::Storable; use scale::{ Encode, Error, diff --git a/crates/storage/src/lazy/mod.rs b/crates/storage/src/lazy/mod.rs index 27c2d480172..0b3451ea90d 100644 --- a/crates/storage/src/lazy/mod.rs +++ b/crates/storage/src/lazy/mod.rs @@ -29,10 +29,8 @@ use crate::traits::{ StorageKey, }; use core::marker::PhantomData; -use ink_primitives::{ - traits::Storable, - Key, -}; +use ink_primitives::Key; +use ink_storage_traits::Storable; use scale::{ Error, Input, diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index b8b6076e74f..ea5a17f0a82 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -43,14 +43,11 @@ unused_extern_crates )] -pub mod traits; +pub use ink_storage_traits as traits; #[allow(dead_code)] pub(crate) mod lazy; -#[cfg(test)] -mod test_utils; - #[doc(inline)] pub use self::lazy::{ Lazy, diff --git a/crates/storage/src/test_utils.rs b/crates/storage/src/test_utils.rs deleted file mode 100644 index f58b6c697cf..00000000000 --- a/crates/storage/src/test_utils.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2018-2022 Parity Technologies (UK) Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Utilities for testing if the storage interaction of an object -//! which is pushed/pulled/cleared to/from storage behaves as it should. - -/// Runs `f` using the off-chain testing environment. -#[cfg(test)] -pub fn run_test(f: F) -where - F: FnOnce(), -{ - ink_env::test::run_test::(|_| { - f(); - Ok(()) - }) - .unwrap() -} - -/// Creates test to verify that the primitive types are packed. -#[macro_export] -macro_rules! storage_hint_works_for_primitive { - ( $ty:ty ) => { - paste::item! { - #[test] - #[allow(non_snake_case)] - fn [<$ty _storage_hint_works>] () { - $crate::test_utils::run_test(|| { - assert_eq!( - ::core::any::TypeId::of::<$ty>(), - ::core::any::TypeId::of::<<$ty as $crate::traits::StorableHint<$crate::traits::ManualKey<123>>>::Type>() - ); - }) - } - } - }; -} diff --git a/crates/primitives/derive/Cargo.toml b/crates/storage/traits/Cargo.toml similarity index 52% rename from crates/primitives/derive/Cargo.toml rename to crates/storage/traits/Cargo.toml index d2d977d32a2..742ad73897b 100644 --- a/crates/primitives/derive/Cargo.toml +++ b/crates/storage/traits/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ink_primitives_derive" +name = "ink_storage_traits" version = "4.0.0-alpha.1" authors = ["Parity Technologies "] edition = "2021" @@ -7,25 +7,32 @@ edition = "2021" license = "Apache-2.0" readme = "../README.md" repository = "https://github.com/paritytech/ink" -documentation = "https://docs.rs/ink_primitives_derive" +documentation = "https://docs.rs/ink_storage_derive" homepage = "https://www.parity.io/" -description = "[ink!] Derive macros for common ink_primitives defined traits." +description = "[ink!] Utils codegen crate related to ink_storage." keywords = ["wasm", "parity", "webassembly", "blockchain", "edsl"] categories = ["no-std", "embedded"] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] -[lib] -proc-macro = true - [dependencies] -quote = "1" +ink_metadata = { version = "4.0.0-alpha.1", path = "../../metadata", default-features = false, features = ["derive"], optional = true } +ink_primitives = { version = "4.0.0-alpha.1", path = "../../primitives", default-features = false } +ink_prelude = { version = "4.0.0-alpha.1", path = "../../prelude", default-features = false } +ink_storage_derive = { version = "4.0.0-alpha.1", path = "derive", default-features = false } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full"] } +scale-info = { version = "2", default-features = false, features = ["derive"], optional = true } syn = { version = "1", features = ["full"] } -proc-macro2 = "1" -synstructure = "0.12.4" [dev-dependencies] -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full"] } +paste = "1.0" ink_env = { version = "4.0.0-alpha.1", path = "../../env" } -ink_primitives = { version = "4.0.0-alpha.1", path = ".." } -ink_metadata = { version = "4.0.0-alpha.1", path = "../../metadata" } -ink_prelude = { version = "4.0.0-alpha.1", path = "../../prelude/" } + +[features] +default = ["std"] +std = [ + "ink_metadata/std", + "ink_primitives/std", + "ink_prelude/std", + "scale/std", + "scale-info/std", +] \ No newline at end of file diff --git a/crates/primitives/derive/LICENSE b/crates/storage/traits/LICENSE similarity index 100% rename from crates/primitives/derive/LICENSE rename to crates/storage/traits/LICENSE diff --git a/crates/primitives/derive/README.md b/crates/storage/traits/README.md similarity index 100% rename from crates/primitives/derive/README.md rename to crates/storage/traits/README.md diff --git a/crates/storage/codegen/Cargo.toml b/crates/storage/traits/codegen/Cargo.toml similarity index 77% rename from crates/storage/codegen/Cargo.toml rename to crates/storage/traits/codegen/Cargo.toml index a7f88bf97ca..51cdb919a44 100644 --- a/crates/storage/codegen/Cargo.toml +++ b/crates/storage/traits/codegen/Cargo.toml @@ -15,5 +15,5 @@ categories = ["no-std", "embedded"] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [dependencies] -ink_primitives = { version = "4.0.0-alpha.1", path = "../../primitives", default-features = false } -syn = { version = "1", features = ["full"] } \ No newline at end of file +ink_primitives = { version = "4.0.0-alpha.1", path = "../../../primitives", default-features = false } +syn = { version = "1", features = ["full", "extra-traits"] } \ No newline at end of file diff --git a/crates/storage/traits/codegen/LICENSE b/crates/storage/traits/codegen/LICENSE new file mode 120000 index 00000000000..14776154326 --- /dev/null +++ b/crates/storage/traits/codegen/LICENSE @@ -0,0 +1 @@ +../../../../LICENSE \ No newline at end of file diff --git a/crates/storage/traits/codegen/README.md b/crates/storage/traits/codegen/README.md new file mode 120000 index 00000000000..ff5c79602cf --- /dev/null +++ b/crates/storage/traits/codegen/README.md @@ -0,0 +1 @@ +../../../../README.md \ No newline at end of file diff --git a/crates/storage/codegen/src/lib.rs b/crates/storage/traits/codegen/src/lib.rs similarity index 100% rename from crates/storage/codegen/src/lib.rs rename to crates/storage/traits/codegen/src/lib.rs diff --git a/crates/storage/derive/Cargo.toml b/crates/storage/traits/derive/Cargo.toml similarity index 81% rename from crates/storage/derive/Cargo.toml rename to crates/storage/traits/derive/Cargo.toml index f738d33e527..cfa70aa15ca 100644 --- a/crates/storage/derive/Cargo.toml +++ b/crates/storage/traits/derive/Cargo.toml @@ -25,9 +25,9 @@ synstructure = "0.12.4" ink_storage_codegen = { version = "4.0.0-alpha.1", path = "../codegen" } [dev-dependencies] -ink_env = { path = "../../env" } -ink_metadata = { path = "../../metadata" } -ink_prelude = { path = "../../prelude" } -ink_primitives = { path = "../../primitives" } -ink_storage = { path = ".." } +ink_env = { path = "../../../env" } +ink_metadata = { path = "../../../metadata" } +ink_prelude = { path = "../../../prelude" } +ink_primitives = { path = "../../../primitives" } +ink_storage = { path = "../.." } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full"] } diff --git a/crates/storage/traits/derive/LICENSE b/crates/storage/traits/derive/LICENSE new file mode 120000 index 00000000000..14776154326 --- /dev/null +++ b/crates/storage/traits/derive/LICENSE @@ -0,0 +1 @@ +../../../../LICENSE \ No newline at end of file diff --git a/crates/storage/traits/derive/README.md b/crates/storage/traits/derive/README.md new file mode 120000 index 00000000000..ff5c79602cf --- /dev/null +++ b/crates/storage/traits/derive/README.md @@ -0,0 +1 @@ +../../../../README.md \ No newline at end of file diff --git a/crates/storage/derive/src/lib.rs b/crates/storage/traits/derive/src/lib.rs similarity index 87% rename from crates/storage/derive/src/lib.rs rename to crates/storage/traits/derive/src/lib.rs index aaaa3129412..e4fea22c29b 100644 --- a/crates/storage/derive/src/lib.rs +++ b/crates/storage/traits/derive/src/lib.rs @@ -19,6 +19,7 @@ extern crate proc_macro; +mod storable; mod storable_hint; mod storage_key; mod storage_layout; @@ -27,10 +28,30 @@ mod storage_layout; mod tests; use self::{ + storable::storable_derive, storable_hint::storable_hint_derive, storage_key::storage_key_derive, storage_layout::storage_layout_derive, }; +synstructure::decl_derive!( + [Storable] => + /// Derives `ink_storage`'s `Storable` trait for the given `struct`, `enum` or `union`. + /// + /// # Examples + /// + /// ``` + /// use ink_storage::traits::Storable; + /// + /// #[derive(Storable)] + /// struct NamedFields { + /// a: u32, + /// b: [u32; 1], + /// } + /// + /// let value = ::decode(&mut &[123, 123][..]); + /// ``` + storable_derive +); synstructure::decl_derive!( [StorableHint] => /// Derives `ink_storage`'s `StorableHint` trait for the given `struct` or `enum`. @@ -48,7 +69,7 @@ synstructure::decl_derive!( /// AutoKey, /// ManualKey, /// }; - /// use ink_primitives::traits::Storable; + /// use ink_storage::traits::Storable; /// /// #[derive(Default, StorableHint, Storable)] /// struct NamedFields { diff --git a/crates/primitives/derive/src/storable.rs b/crates/storage/traits/derive/src/storable.rs similarity index 87% rename from crates/primitives/derive/src/storable.rs rename to crates/storage/traits/derive/src/storable.rs index d214d56ab8e..3811bd90dfc 100644 --- a/crates/primitives/derive/src/storable.rs +++ b/crates/storage/traits/derive/src/storable.rs @@ -27,18 +27,18 @@ fn storable_struct_derive(s: &synstructure::Structure) -> TokenStream2 { let ty = &field.ty; let span = ty.span(); quote_spanned!(span => - <#ty as ::ink_primitives::traits::Storable>::decode(__input)? + <#ty as ::ink_storage::traits::Storable>::decode(__input)? ) }); let encode_body = variant.each(|binding| { let span = binding.ast().ty.span(); quote_spanned!(span => - ::ink_primitives::traits::Storable::encode(#binding, __dest); + ::ink_storage::traits::Storable::encode(#binding, __dest); ) }); s.gen_impl(quote! { - gen impl ::ink_primitives::traits::Storable for @Self { + gen impl ::ink_storage::traits::Storable for @Self { #[inline(always)] #[allow(non_camel_case_types)] fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result { @@ -77,7 +77,7 @@ fn storable_enum_derive(s: &synstructure::Structure) -> TokenStream2 { let ty = &field.ty; let span = ty.span(); quote_spanned!(span => - <#ty as ::ink_primitives::traits::Storable>::decode(__input)? + <#ty as ::ink_storage::traits::Storable>::decode(__input)? ) }) }) @@ -96,12 +96,12 @@ fn storable_enum_derive(s: &synstructure::Structure) -> TokenStream2 { let fields = variant.bindings().iter().map(|field| { let span = field.ast().ty.span(); quote_spanned!(span => - ::ink_primitives::traits::Storable::encode(#field, __dest); + ::ink_storage::traits::Storable::encode(#field, __dest); ) }); quote! { #pat => { - { <::core::primitive::u8 as ::ink_primitives::traits::Storable>::encode(&#index, __dest); } + { <::core::primitive::u8 as ::ink_storage::traits::Storable>::encode(&#index, __dest); } #( { #fields } )* @@ -109,12 +109,12 @@ fn storable_enum_derive(s: &synstructure::Structure) -> TokenStream2 { } }); s.gen_impl(quote! { - gen impl ::ink_primitives::traits::Storable for @Self { + gen impl ::ink_storage::traits::Storable for @Self { #[inline(always)] #[allow(non_camel_case_types)] fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result { ::core::result::Result::Ok( - match <::core::primitive::u8 as ::ink_primitives::traits::Storable>::decode(__input)? { + match <::core::primitive::u8 as ::ink_storage::traits::Storable>::decode(__input)? { #decode_body _ => unreachable!("encountered invalid enum discriminant"), } diff --git a/crates/storage/derive/src/storable_hint.rs b/crates/storage/traits/derive/src/storable_hint.rs similarity index 100% rename from crates/storage/derive/src/storable_hint.rs rename to crates/storage/traits/derive/src/storable_hint.rs diff --git a/crates/storage/derive/src/storage_key.rs b/crates/storage/traits/derive/src/storage_key.rs similarity index 100% rename from crates/storage/derive/src/storage_key.rs rename to crates/storage/traits/derive/src/storage_key.rs diff --git a/crates/storage/derive/src/storage_layout.rs b/crates/storage/traits/derive/src/storage_layout.rs similarity index 100% rename from crates/storage/derive/src/storage_layout.rs rename to crates/storage/traits/derive/src/storage_layout.rs diff --git a/crates/storage/derive/src/tests/mod.rs b/crates/storage/traits/derive/src/tests/mod.rs similarity index 99% rename from crates/storage/derive/src/tests/mod.rs rename to crates/storage/traits/derive/src/tests/mod.rs index fbd927946cd..1c3e0143ea3 100644 --- a/crates/storage/derive/src/tests/mod.rs +++ b/crates/storage/traits/derive/src/tests/mod.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod storable; mod storable_hint; mod storage_key; mod storage_layout; diff --git a/crates/primitives/derive/src/tests/storable.rs b/crates/storage/traits/derive/src/tests/storable.rs similarity index 80% rename from crates/primitives/derive/src/tests/storable.rs rename to crates/storage/traits/derive/src/tests/storable.rs index 175b99fc522..41de200d8b6 100644 --- a/crates/primitives/derive/src/tests/storable.rs +++ b/crates/storage/traits/derive/src/tests/storable.rs @@ -30,7 +30,7 @@ fn unit_struct_works() { } expands to { const _: () = { - impl ::ink_primitives::traits::Storable for UnitStruct { + impl ::ink_storage::traits::Storable for UnitStruct { #[inline(always)] #[allow(non_camel_case_types)] fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result { @@ -62,15 +62,15 @@ fn struct_works() { } expands to { const _: () = { - impl ::ink_primitives::traits::Storable for NamedFields { + impl ::ink_storage::traits::Storable for NamedFields { #[inline(always)] #[allow(non_camel_case_types)] fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result { ::core::result::Result::Ok( NamedFields { - a : ::decode(__input)?, - b : <[u8; 32] as ::ink_primitives::traits::Storable>::decode(__input)?, - d : as ::ink_primitives::traits::Storable>::decode(__input)?, + a : ::decode(__input)?, + b : <[u8; 32] as ::ink_storage::traits::Storable>::decode(__input)?, + d : as ::ink_storage::traits::Storable>::decode(__input)?, } ) } @@ -86,19 +86,19 @@ fn struct_works() { d: __binding_2, } => { { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_0, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_1, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_2, __dest ); @@ -122,12 +122,12 @@ fn one_variant_enum_works() { } expands to { const _: () = { - impl ::ink_primitives::traits::Storable for OneVariantEnum { + impl ::ink_storage::traits::Storable for OneVariantEnum { #[inline(always)] #[allow(non_camel_case_types)] fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result { ::core::result::Result::Ok( - match <::core::primitive::u8 as ::ink_primitives::traits::Storable>::decode(__input)? + match <::core::primitive::u8 as ::ink_storage::traits::Storable>::decode(__input)? { 0u8 => OneVariantEnum::A, _ => unreachable!("encountered invalid enum discriminant"), @@ -141,7 +141,7 @@ fn one_variant_enum_works() { match self { OneVariantEnum::A => { { - <::core::primitive::u8 as ::ink_primitives::traits::Storable>::encode( + <::core::primitive::u8 as ::ink_storage::traits::Storable>::encode( &0u8, __dest ); @@ -167,21 +167,21 @@ fn enum_works() { } expands to { const _: () = { - impl ::ink_primitives::traits::Storable for MixedEnum { + impl ::ink_storage::traits::Storable for MixedEnum { #[inline(always)] #[allow(non_camel_case_types)] fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result { ::core::result::Result::Ok( - match <::core::primitive::u8 as ::ink_primitives::traits::Storable>::decode(__input)? + match <::core::primitive::u8 as ::ink_storage::traits::Storable>::decode(__input)? { 0u8 => MixedEnum::A, 1u8 => MixedEnum::B( - ::decode(__input)?, - <[u8; 32] as ::ink_primitives::traits::Storable>::decode(__input)?, + ::decode(__input)?, + <[u8; 32] as ::ink_storage::traits::Storable>::decode(__input)?, ), 2u8 => MixedEnum::C { - a: < i32 as ::ink_primitives::traits::Storable>::decode(__input)?, - b: <(bool, i32) as ::ink_primitives::traits::Storable>::decode(__input)?, + a: < i32 as ::ink_storage::traits::Storable>::decode(__input)?, + b: <(bool, i32) as ::ink_storage::traits::Storable>::decode(__input)?, }, _ => unreachable!("encountered invalid enum discriminant"), } @@ -194,7 +194,7 @@ fn enum_works() { match self { MixedEnum::A => { { - <::core::primitive::u8 as ::ink_primitives::traits::Storable>::encode( + <::core::primitive::u8 as ::ink_storage::traits::Storable>::encode( &0u8, __dest ); @@ -202,19 +202,19 @@ fn enum_works() { } MixedEnum::B(__binding_0, __binding_1,) => { { - <::core::primitive::u8 as ::ink_primitives::traits::Storable>::encode( + <::core::primitive::u8 as ::ink_storage::traits::Storable>::encode( &1u8, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_0, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_1, __dest ); @@ -225,18 +225,18 @@ fn enum_works() { b: __binding_1, } => { { - <::core::primitive::u8 as ::ink_primitives::traits::Storable>::encode( + <::core::primitive::u8 as ::ink_storage::traits::Storable>::encode( &2u8, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_0, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_1, __dest ); @@ -265,22 +265,22 @@ fn generic_struct_works() { } expands to { const _: () = { - impl ::ink_primitives::traits::Storable for GenericStruct + impl ::ink_storage::traits::Storable for GenericStruct where T1: ::scale::Decode, T2: ::scale::Encode, - T1: ::ink_primitives::traits::Storable, - (T1 , T2): ::ink_primitives::traits::Storable + T1: ::ink_storage::traits::Storable, + (T1 , T2): ::ink_storage::traits::Storable { #[inline(always)] #[allow(non_camel_case_types)] fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result { ::core::result::Result::Ok( GenericStruct { - a: ::decode( + a: ::decode( __input )?, - b: <(T1, T2) as ::ink_primitives::traits::Storable>::decode( + b: <(T1, T2) as ::ink_storage::traits::Storable>::decode( __input )?, } @@ -296,13 +296,13 @@ fn generic_struct_works() { b: __binding_1, } => { { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_0, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_1, __dest ); @@ -327,24 +327,24 @@ fn generic_enum_works() { } expands to { const _: () = { - impl ::ink_primitives::traits::Storable for GenericEnum + impl ::ink_storage::traits::Storable for GenericEnum where - T1: ::ink_primitives::traits::Storable, - T2: ::ink_primitives::traits::Storable + T1: ::ink_storage::traits::Storable, + T2: ::ink_storage::traits::Storable { #[inline(always)] #[allow(non_camel_case_types)] fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result { ::core::result::Result::Ok( - match <::core::primitive::u8 as ::ink_primitives::traits::Storable>::decode(__input)? + match <::core::primitive::u8 as ::ink_storage::traits::Storable>::decode(__input)? { 0u8 => GenericEnum::Tuple( - ::decode(__input)?, - ::decode(__input)?, + ::decode(__input)?, + ::decode(__input)?, ), 1u8 => GenericEnum::Named { - a: ::decode(__input)?, - b: ::decode(__input)?, + a: ::decode(__input)?, + b: ::decode(__input)?, }, _ => unreachable!("encountered invalid enum discriminant"), } @@ -357,16 +357,16 @@ fn generic_enum_works() { match self { GenericEnum::Tuple(__binding_0, __binding_1,) => { { - <::core::primitive::u8 as ::ink_primitives::traits::Storable>::encode(&0u8, __dest); + <::core::primitive::u8 as ::ink_storage::traits::Storable>::encode(&0u8, __dest); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_0, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_1, __dest ); @@ -377,16 +377,16 @@ fn generic_enum_works() { b: __binding_1, } => { { - <::core::primitive::u8 as ::ink_primitives::traits::Storable>::encode(&1u8, __dest); + <::core::primitive::u8 as ::ink_storage::traits::Storable>::encode(&1u8, __dest); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_0, __dest ); } { - ::ink_primitives::traits::Storable::encode( + ::ink_storage::traits::Storable::encode( __binding_1, __dest ); diff --git a/crates/storage/derive/src/tests/storable_hint.rs b/crates/storage/traits/derive/src/tests/storable_hint.rs similarity index 100% rename from crates/storage/derive/src/tests/storable_hint.rs rename to crates/storage/traits/derive/src/tests/storable_hint.rs diff --git a/crates/storage/derive/src/tests/storage_key.rs b/crates/storage/traits/derive/src/tests/storage_key.rs similarity index 100% rename from crates/storage/derive/src/tests/storage_key.rs rename to crates/storage/traits/derive/src/tests/storage_key.rs diff --git a/crates/storage/derive/src/tests/storage_layout.rs b/crates/storage/traits/derive/src/tests/storage_layout.rs similarity index 100% rename from crates/storage/derive/src/tests/storage_layout.rs rename to crates/storage/traits/derive/src/tests/storage_layout.rs diff --git a/crates/storage/src/traits/impls/mod.rs b/crates/storage/traits/src/impls/mod.rs similarity index 86% rename from crates/storage/src/traits/impls/mod.rs rename to crates/storage/traits/src/impls/mod.rs index a717f12e07e..a7eaa567650 100644 --- a/crates/storage/src/traits/impls/mod.rs +++ b/crates/storage/traits/src/impls/mod.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::traits::{ +use crate::{ AutoStorableHint, Packed, StorableHint, @@ -111,6 +111,26 @@ where #[cfg(test)] mod tests { + /// Creates test to verify that the primitive types are packed. + #[macro_export] + macro_rules! storage_hint_works_for_primitive { + ( $ty:ty ) => { + paste::item! { + #[test] + #[allow(non_snake_case)] + fn [<$ty _storage_hint_works>] () { + ink_env::test::run_test::(|_| { + assert_eq!( + ::core::any::TypeId::of::<$ty>(), + ::core::any::TypeId::of::<<$ty as $crate::StorableHint<$crate::ManualKey<123>>>::Type>() + ); + Ok(()) + }) + .unwrap() + } + } + }; + } mod arrays { use crate::storage_hint_works_for_primitive; @@ -123,7 +143,7 @@ mod tests { mod prims { use crate::storage_hint_works_for_primitive; - use ink_env::AccountId; + use ink_primitives::AccountId; storage_hint_works_for_primitive!(bool); storage_hint_works_for_primitive!(String); diff --git a/crates/storage/src/traits/layout/impls.rs b/crates/storage/traits/src/layout/impls.rs similarity index 98% rename from crates/storage/src/traits/layout/impls.rs rename to crates/storage/traits/src/layout/impls.rs index 7a8367647ee..bc2d2f71b4f 100644 --- a/crates/storage/src/traits/layout/impls.rs +++ b/crates/storage/traits/src/layout/impls.rs @@ -12,14 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::traits::{ +use crate::{ Packed, StorageLayout, }; -use ink_env::{ - AccountId, - Hash, -}; use ink_metadata::layout::{ ArrayLayout, Discriminant, @@ -40,7 +36,11 @@ use ink_prelude::{ string::String, vec::Vec, }; -use ink_primitives::Key; +use ink_primitives::{ + AccountId, + Hash, + Key, +}; use scale_info::TypeInfo; macro_rules! impl_storage_layout_for_primitives { @@ -56,7 +56,7 @@ macro_rules! impl_storage_layout_for_primitives { } #[rustfmt::skip] impl_storage_layout_for_primitives!( - Hash, AccountId, String, + AccountId, Hash, String, bool, char, (), u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, diff --git a/crates/storage/src/traits/layout/mod.rs b/crates/storage/traits/src/layout/mod.rs similarity index 57% rename from crates/storage/src/traits/layout/mod.rs rename to crates/storage/traits/src/layout/mod.rs index 1c4793ce148..97b0235e3ad 100644 --- a/crates/storage/src/traits/layout/mod.rs +++ b/crates/storage/traits/src/layout/mod.rs @@ -14,15 +14,7 @@ mod impls; -use ink_env::hash::{ - Blake2x256, - Keccak256, - Sha2x256, -}; -use ink_metadata::layout::{ - CryptoHasher, - Layout, -}; +use ink_metadata::layout::Layout; use ink_primitives::Key; /// Implemented by types that have a storage layout. @@ -33,27 +25,3 @@ pub trait StorageLayout { /// the contract storage regions. fn layout(key: &Key) -> Layout; } - -/// Types implementing this trait are supported layouting crypto hashers. -pub trait LayoutCryptoHasher { - /// Returns the layout crypto hasher for `Self`. - fn crypto_hasher() -> CryptoHasher; -} - -impl LayoutCryptoHasher for Blake2x256 { - fn crypto_hasher() -> CryptoHasher { - CryptoHasher::Blake2x256 - } -} - -impl LayoutCryptoHasher for Sha2x256 { - fn crypto_hasher() -> CryptoHasher { - CryptoHasher::Sha2x256 - } -} - -impl LayoutCryptoHasher for Keccak256 { - fn crypto_hasher() -> CryptoHasher { - CryptoHasher::Keccak256 - } -} diff --git a/crates/storage/src/traits/mod.rs b/crates/storage/traits/src/lib.rs similarity index 89% rename from crates/storage/src/traits/mod.rs rename to crates/storage/traits/src/lib.rs index 4295c353eda..5be16919b3c 100644 --- a/crates/storage/src/traits/mod.rs +++ b/crates/storage/traits/src/lib.rs @@ -15,7 +15,7 @@ //! Traits and interfaces to operate with storage entities. //! //! Generally a type is said to be a storage entity if it implements the -//! [`ink_primitives::traits::Storable`] trait. This defines certain constants and routines in order +//! [`Storable`] trait. This defines certain constants and routines in order //! to tell a smart contract how to load and store instances of this type //! from and to the contract's storage. //! @@ -25,6 +25,8 @@ //! If at least one of the type's fields occupies its own separate storage cell, it is a //! non-[`Packed`] type because it occupies more than one storage cell. +#![cfg_attr(not(feature = "std"), no_std)] + mod impls; mod storage; @@ -32,10 +34,7 @@ mod storage; mod layout; #[cfg(feature = "std")] -pub use self::layout::{ - LayoutCryptoHasher, - StorageLayout, -}; +pub use self::layout::StorageLayout; pub use self::{ impls::{ AutoKey, @@ -45,11 +44,13 @@ pub use self::{ storage::{ AutoStorableHint, Packed, + Storable, StorableHint, StorageKey, }, }; pub use ink_storage_derive::{ + Storable, StorableHint, StorageKey, StorageLayout, diff --git a/crates/storage/src/traits/storage.rs b/crates/storage/traits/src/storage.rs similarity index 62% rename from crates/storage/src/traits/storage.rs rename to crates/storage/traits/src/storage.rs index 6b95ca5f86c..9db6320ff86 100644 --- a/crates/storage/src/traits/storage.rs +++ b/crates/storage/traits/src/storage.rs @@ -12,10 +12,37 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ink_primitives::{ - traits::Storable, - Key, -}; +use ink_primitives::Key; + +/// Trait for representing types which can be read and written to storage. +/// +/// This trait is not the same as the `scale::Encode + scale::Decode`. Each type that implements +/// `scale::Encode + scale::Decode` are storable by default and transferable between contracts. +/// But not each storable type is transferable. +pub trait Storable: Sized { + /// Convert self to a slice and append it to the destination. + fn encode(&self, dest: &mut T); + + /// Attempt to deserialize the value from input. + fn decode(input: &mut I) -> Result; +} + +/// Types which implement `scale::Encode` and `scale::Decode` are `Storable` by default because +/// they can be written directly into the storage cell. +impl

Storable for P +where + P: scale::Encode + scale::Decode, +{ + #[inline] + fn encode(&self, dest: &mut T) { + scale::Encode::encode_to(self, dest) + } + + #[inline] + fn decode(input: &mut I) -> Result { + scale::Decode::decode(input) + } +} pub(crate) mod private { /// Seals the implementation of `Packed`. @@ -38,7 +65,7 @@ pub trait Packed: Storable + scale::Decode + scale::Encode + private::Sealed {} /// /// # Note /// -/// The trait is automatically implemented for [`Packed`](crate::traits::Packed) types +/// The trait is automatically implemented for [`Packed`] types /// via blanket implementation. pub trait StorageKey { /// Storage key of the type. @@ -54,7 +81,7 @@ pub trait StorageKey { /// /// # Note /// -/// The trait is automatically implemented for [`Packed`](crate::traits::Packed) types +/// The trait is automatically implemented for [`Packed`] types /// via blanket implementation. pub trait StorableHint { /// Storable type with storage key inside. diff --git a/examples/erc1155/lib.rs b/examples/erc1155/lib.rs index f15981fc871..625c0ac1d31 100644 --- a/examples/erc1155/lib.rs +++ b/examples/erc1155/lib.rs @@ -1,8 +1,8 @@ #![cfg_attr(not(feature = "std"), no_std)] -use ink_env::AccountId; use ink_lang as ink; use ink_prelude::vec::Vec; +use ink_primitives::AccountId; // This is the return value that we expect if a smart contract supports receiving ERC-1155 // tokens. diff --git a/examples/erc20/lib.rs b/examples/erc20/lib.rs index fc411ad57e3..2ec53433745 100644 --- a/examples/erc20/lib.rs +++ b/examples/erc20/lib.rs @@ -219,8 +219,8 @@ mod erc20 { mod tests { use super::*; - use ink_env::Clear; use ink_lang as ink; + use ink_primitives::Clear; type Event = ::Type; @@ -507,13 +507,10 @@ mod erc20 { where T: scale::Encode, { - use ink_env::{ - hash::{ - Blake2x256, - CryptoHash, - HashOutput, - }, - Clear, + use ink_env::hash::{ + Blake2x256, + CryptoHash, + HashOutput, }; let mut result = Hash::clear(); let len_result = result.as_ref().len(); diff --git a/examples/trait-erc20/lib.rs b/examples/trait-erc20/lib.rs index eaf9250e956..1f770e44024 100644 --- a/examples/trait-erc20/lib.rs +++ b/examples/trait-erc20/lib.rs @@ -262,15 +262,13 @@ mod erc20 { mod tests { /// Imports all the definitions from the outer scope so we can use them here. use super::*; - use ink_env::{ - hash::{ - Blake2x256, - CryptoHash, - HashOutput, - }, - Clear, + use ink_env::hash::{ + Blake2x256, + CryptoHash, + HashOutput, }; use ink_lang as ink; + use ink_primitives::Clear; type Event = ::Type;