From 84e447cfd2eb1f42bd5fb5b69953c6988e1dab72 Mon Sep 17 00:00:00 2001 From: green Date: Tue, 21 Feb 2023 18:48:05 +0000 Subject: [PATCH 1/4] Previously the `ManualKey<0>` acted as an `AutoKey` without the possibility of really using the zero storage key. This fix allows using the zero manual key that overrides the auto-generated key. --- crates/storage/traits/src/impls/mod.rs | 59 ++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/crates/storage/traits/src/impls/mod.rs b/crates/storage/traits/src/impls/mod.rs index e44d1e9f6d..36df4b9083 100644 --- a/crates/storage/traits/src/impls/mod.rs +++ b/crates/storage/traits/src/impls/mod.rs @@ -27,6 +27,11 @@ use ink_primitives::{ KeyComposer, }; +/// The private trait helping identify the [`AutoKey`] key type. +trait KeyType { + const IS_AUTO_KEY: bool; +} + /// Auto key type means that the storage key should be calculated automatically. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] @@ -36,6 +41,10 @@ impl StorageKey for AutoKey { const KEY: Key = 0; } +impl KeyType for AutoKey { + const IS_AUTO_KEY: bool = true; +} + impl Debug for AutoKey { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.debug_struct("AutoKey") @@ -55,6 +64,10 @@ impl StorageKey for ManualKey KeyType for ManualKey { + const IS_AUTO_KEY: bool = false; +} + impl Debug for ManualKey { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.debug_struct("ManualKey") @@ -67,11 +80,26 @@ impl Debug for ManualKey /// If the `L` type is `AutoKey` it returns auto-generated `R` else `L`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Debug)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub struct ResolverKey(PhantomData (L, R)>); +pub struct ResolverKey(PhantomData (L, R)>); -impl StorageKey for ResolverKey { - /// `KEY` of the `AutoKey` is zero. If left key is zero, then use right manual key. - const KEY: Key = if L::KEY == 0 { R::KEY } else { L::KEY }; +impl StorageKey for ResolverKey +where + L: StorageKey + KeyType, + R: StorageKey + KeyType, +{ + /// If the left key is [`AutoKey`], then use the right auto-generated storage key. + /// Otherwise use the left [`ManualKey`]. + const KEY: Key = if L::IS_AUTO_KEY { R::KEY } else { L::KEY }; +} + +impl KeyType for ResolverKey +where + L: KeyType, + R: KeyType, +{ + /// The right key is always an auto-generated key, the user can specify only the left key. + /// So the left key defines the [`KeyType::IS_AUTO_KEY`] of the [`ResolverKey`]. + const IS_AUTO_KEY: bool = L::IS_AUTO_KEY; } type FinalKey = @@ -84,6 +112,7 @@ type FinalKey = impl AutoStorableHint> for T where T: StorableHint, + >::PreferredKey: KeyType, T: StorableHint>, ParentKey: StorageKey, { @@ -111,6 +140,8 @@ where #[cfg(test)] mod tests { + use super::*; + /// Creates test to verify that the primitive types are packed. #[macro_export] macro_rules! storage_hint_works_for_primitive { @@ -174,4 +205,24 @@ mod tests { type TupleSix = (i32, u32, String, u8, bool, Box>); storage_hint_works_for_primitive!(TupleSix); } + + #[test] + fn storage_key_types_works() { + assert_eq!(::KEY, 0); + assert_eq!( as StorageKey>::KEY, 123); + assert_eq!( as StorageKey>::KEY, 0); + assert_eq!( as StorageKey>::KEY, 0); + assert_eq!( + > as StorageKey>::KEY, + 123 + ); + assert_eq!( + , ManualKey<123>> as StorageKey>::KEY, + 456 + ); + assert_eq!( + , ManualKey<123>> as StorageKey>::KEY, + 0 + ); + } } From 277e4efb62b6400cfe6b7fbddaea0df1ae42c528 Mon Sep 17 00:00:00 2001 From: green Date: Tue, 21 Feb 2023 18:52:08 +0000 Subject: [PATCH 2/4] Added a comment for `KeyType::IS_AUTO_KEY` --- crates/storage/traits/src/impls/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/storage/traits/src/impls/mod.rs b/crates/storage/traits/src/impls/mod.rs index 36df4b9083..3fa4a20e80 100644 --- a/crates/storage/traits/src/impls/mod.rs +++ b/crates/storage/traits/src/impls/mod.rs @@ -29,6 +29,9 @@ use ink_primitives::{ /// The private trait helping identify the [`AutoKey`] key type. trait KeyType { + /// It is `true` for [`AutoKey`] and `false` for [`ManualKey`]. + /// It helps the [`ResolverKey`] select between the user-specified(left key) + /// and the auto-generated(right key) keys. const IS_AUTO_KEY: bool; } From cbcafa9ccd5e070b69c0d2fc5ec24aee9fe1e296 Mon Sep 17 00:00:00 2001 From: green Date: Wed, 22 Feb 2023 09:56:09 +0000 Subject: [PATCH 3/4] Added "Unreleased" section into changelog. Mentioned the https://github.com/paritytech/ink/pull/1670 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 996043d380..569af46974 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed +- Fixing `ManualKey<0>` to act properly - [#1670](https://github.com/paritytech/ink/pull/1670) + ## Version 4.0.0 The latest stable release of ink! is here 🥳 From 63c846d8c0e274cc3ff483818ad6c8dcbf7e6c41 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 23 Feb 2023 13:42:36 -0800 Subject: [PATCH 4/4] Fix some spacing in comments --- crates/storage/traits/src/impls/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/storage/traits/src/impls/mod.rs b/crates/storage/traits/src/impls/mod.rs index 3fa4a20e80..bf19eb9736 100644 --- a/crates/storage/traits/src/impls/mod.rs +++ b/crates/storage/traits/src/impls/mod.rs @@ -30,8 +30,8 @@ use ink_primitives::{ /// The private trait helping identify the [`AutoKey`] key type. trait KeyType { /// It is `true` for [`AutoKey`] and `false` for [`ManualKey`]. - /// It helps the [`ResolverKey`] select between the user-specified(left key) - /// and the auto-generated(right key) keys. + /// It helps the [`ResolverKey`] select between the user-specified (left key) + /// and the auto-generated (right key) keys. const IS_AUTO_KEY: bool; }