Skip to content

Commit

Permalink
Bugfix ink_metadata: RootLayout must work for PortableForm (#1989)
Browse files Browse the repository at this point in the history
The constructor `RootLayout::new()` needs to be generic to allow projects relying on working with PortableForm exclusively to re-use the ink! metadata.
  • Loading branch information
xermicus authored Nov 13, 2023
1 parent c7e1979 commit 64efc07
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 17 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ You can see a more detailed log of changes below:
- Use `decode_all`` for decoding cross contract call result - [#1810](https://github.com/paritytech/ink/pull/1810)
- E2E: improve call API, remove `build_message` + callback - [#1782](https://github.com/paritytech/ink/pull/1782)

### Fixed
- `RootLayout::new()` is generic again to allow using `ink_metadata` in pure `PortableForm` contexts - [#1782](https://github.com/paritytech/ink/pull/1989)

## 4.3.0

### Fixed
Expand Down
3 changes: 2 additions & 1 deletion crates/ink/codegen/src/generator/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@ impl Metadata<'_> {
quote_spanned!(storage_span=>
// Wrap the layout of the contract into the `RootLayout`, because
// contract storage key is reserved for all packed fields
::ink::metadata::layout::Layout::Root(::ink::metadata::layout::RootLayout::new::<#storage_ident, _>(
::ink::metadata::layout::Layout::Root(::ink::metadata::layout::RootLayout::new(
#layout_key,
<#storage_ident as ::ink::storage::traits::StorageLayout>::layout(
&#key,
),
::ink::scale_info::meta_type::<#storage_ident>(),
))
)
}
Expand Down
27 changes: 13 additions & 14 deletions crates/metadata/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,32 +154,31 @@ impl IntoPortable for RootLayout {
}

impl RootLayout<MetaForm> {
/// Creates a new root layout.
pub fn new<Root, L>(root_key: LayoutKey, layout: L) -> Self
where
Root: TypeInfo + 'static,
L: Into<Layout<MetaForm>>,
{
Self {
root_key,
layout: Box::new(layout.into()),
ty: meta_type::<Root>(),
}
}

/// Creates a new root layout with empty root type.
pub fn new_empty<L>(root_key: LayoutKey, layout: L) -> Self
where
L: Into<Layout<MetaForm>>,
{
Self::new::<(), L>(root_key, layout)
Self::new::<L>(root_key, layout, meta_type::<()>())
}
}

impl<F> RootLayout<F>
where
F: Form,
{
/// Create a new root layout
pub fn new<L>(root_key: LayoutKey, layout: L, ty: <F as Form>::Type) -> Self
where
L: Into<Layout<F>>,
{
Self {
root_key,
layout: Box::new(layout.into()),
ty,
}
}

/// Returns the root key of the sub-tree.
pub fn root_key(&self) -> &LayoutKey {
&self.root_key
Expand Down
9 changes: 9 additions & 0 deletions crates/metadata/src/layout/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,12 @@ fn runtime_storage_layout_works() {
);
assert_eq!(json, expected);
}

#[test]
fn ensure_portable_root_layout_are_supported() {
let root_key = LayoutKey::new(0u32);
let layout = Layout::Struct(StructLayout::new(String::new(), Vec::new()));
let ty = 0.into();

let _: RootLayout<PortableForm> = RootLayout::new(root_key, layout, ty);
}
3 changes: 2 additions & 1 deletion crates/storage/src/lazy/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,10 @@ const _: () = {
KeyType: StorageKey + scale_info::TypeInfo + 'static,
{
fn layout(_: &Key) -> Layout {
Layout::Root(RootLayout::new::<Self, _>(
Layout::Root(RootLayout::new(
LayoutKey::from(&KeyType::KEY),
<V as StorageLayout>::layout(&KeyType::KEY),
scale_info::meta_type::<Self>(),
))
}
}
Expand Down
3 changes: 2 additions & 1 deletion crates/storage/src/lazy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,10 @@ const _: () = {
KeyType: StorageKey + scale_info::TypeInfo + 'static,
{
fn layout(_: &Key) -> Layout {
Layout::Root(RootLayout::new::<Self, _>(
Layout::Root(RootLayout::new(
LayoutKey::from(&KeyType::KEY),
<V as StorageLayout>::layout(&KeyType::KEY),
scale_info::meta_type::<Self>(),
))
}
}
Expand Down

0 comments on commit 64efc07

Please sign in to comment.