Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/e2e/macro/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl TryFrom<ast::AttributeArgs> for E2EConfig {
return Err(format_err_spanned!(
arg,
"expected a string literal for `additional_contracts` ink! E2E test configuration argument",
))
));
}
} else if arg.name.is_ident("environment") {
if let Some((_, ast)) = environment {
Expand All @@ -75,7 +75,7 @@ impl TryFrom<ast::AttributeArgs> for E2EConfig {
return Err(format_err_spanned!(
arg,
"expected a path for `environment` ink! E2E test configuration argument",
))
));
}
} else {
return Err(format_err_spanned!(
Expand Down
2 changes: 1 addition & 1 deletion crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ where
///
/// - If the encode length of value exceeds the configured maximum value length of a
/// storage entry.
pub fn set_contract_storage<K, V>(key: &K, value: &V) -> Option<u32>
pub fn set_contract_storage<K, V>(key: &K, value: &V) -> Result<Option<u32>>
where
K: scale::Encode,
V: Storable,
Expand Down
2 changes: 1 addition & 1 deletion crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ pub trait EnvBackend {
/// Writes the value to the contract storage under the given storage key.
///
/// Returns the size of the pre-existing value at the specified key if any.
fn set_contract_storage<K, V>(&mut self, key: &K, value: &V) -> Option<u32>
fn set_contract_storage<K, V>(&mut self, key: &K, value: &V) -> Result<Option<u32>>
where
K: scale::Encode,
V: Storable;
Expand Down
7 changes: 5 additions & 2 deletions crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,17 @@ impl EnvInstance {
}

impl EnvBackend for EnvInstance {
fn set_contract_storage<K, V>(&mut self, key: &K, value: &V) -> Option<u32>
fn set_contract_storage<K, V>(&mut self, key: &K, value: &V) -> Result<Option<u32>>
where
K: scale::Encode,
V: Storable,
{
let mut v = vec![];
if value.size_hint() > 9600 {
return Err(Error::Unknown)
}
Storable::encode(value, &mut v);
self.engine.set_storage(&key.encode(), &v[..])
Ok(self.engine.set_storage(&key.encode(), &v[..]))
}

fn get_contract_storage<K, R>(&mut self, key: &K) -> Result<Option<R>>
Expand Down
5 changes: 5 additions & 0 deletions crates/env/src/engine/on_chain/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,9 @@ impl<'a> ScopedBuffer<'a> {
debug_assert!(!self.buffer.is_empty());
self.buffer
}

/// Return the length of the internal buffer.
pub fn len(&self) -> usize {
self.buffer.len()
}
}
7 changes: 5 additions & 2 deletions crates/env/src/engine/on_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,18 @@ impl EnvInstance {
}

impl EnvBackend for EnvInstance {
fn set_contract_storage<K, V>(&mut self, key: &K, value: &V) -> Option<u32>
fn set_contract_storage<K, V>(&mut self, key: &K, value: &V) -> Result<Option<u32>>
where
K: scale::Encode,
V: Storable,
{
let mut buffer = self.scoped_buffer();
let key = buffer.take_encoded(key);
if value.size_hint() > buffer.len() {
return Err(Error::Unknown)
}
let value = buffer.take_storable_encoded(value);
ext::set_storage(key, value)
Ok(ext::set_storage(key, value))
}

fn get_contract_storage<K, R>(&mut self, key: &K) -> Result<Option<R>>
Expand Down
4 changes: 2 additions & 2 deletions crates/ink/codegen/src/generator/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ impl Dispatch<'_> {
::ink::env::set_contract_storage::<::ink::primitives::Key, #storage_ident>(
&<#storage_ident as ::ink::storage::traits::StorageKey>::KEY,
contract,
);
).unwrap(); // TODO (unwrapping here should roughly be the same as is)
}

::ink::env::return_value::<
Expand Down Expand Up @@ -838,7 +838,7 @@ impl Dispatch<'_> {
::ink::env::set_contract_storage::<::ink::primitives::Key, #storage_ident>(
&<#storage_ident as ::ink::storage::traits::StorageKey>::KEY,
&contract,
);
).unwrap(); // TODO (unwrapping here should roughly be the same as is)
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/ink/ir/src/ir/item_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ impl ItemMod {
.into_combine(format_err!(
overlap.span(),
"first ink! message with overlapping wildcard selector here",
)))
)));
}
}
}
Expand All @@ -283,7 +283,7 @@ impl ItemMod {
.into_combine(format_err!(
overlap.span(),
"first ink! constructor with overlapping wildcard selector here",
)))
)));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/ink/ir/src/ir/trait_def/item/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ impl InkItemTrait {
).into_combine(format_err_spanned!(
duplicate_selector,
"first ink! trait constructor or message with same selector found here",
)))
)));
}
assert!(
duplicate_ident.is_none(),
Expand Down
55 changes: 50 additions & 5 deletions crates/ink/macro/src/storage/storable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@
// limitations under the License.

use proc_macro2::TokenStream as TokenStream2;
use quote::{
quote,
quote_spanned,
};
use quote::{quote, quote_spanned};
use syn::spanned::Spanned;

/// `Storable` derive implementation for `struct` types.
Expand All @@ -36,9 +33,24 @@ fn storable_struct_derive(s: &synstructure::Structure) -> TokenStream2 {
::ink::storage::traits::Storable::encode(#binding, __dest);
)
});
let size_hint_body = variant.each(|binding| {
let span = binding.ast().ty.span();
quote_spanned!(span =>
size_hint += ::ink::storage::traits::Storable::size_hint(#binding);
)
});

s.gen_impl(quote! {
gen impl ::ink::storage::traits::Storable for @Self {
#[inline(always)]
#[allow(non_camel_case_types)]
#[allow(unused_mut)]
fn size_hint(&self) -> ::core::primitive::usize {
let mut size_hint = 0;
match self { #size_hint_body }
size_hint
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result<Self, ::scale::Error> {
Expand Down Expand Up @@ -66,7 +78,7 @@ fn storable_enum_derive(s: &synstructure::Structure) -> TokenStream2 {
s.ast().span(),
"Currently only enums with at most 256 variants are supported.",
)
.to_compile_error()
.to_compile_error();
}

let decode_body = s
Expand Down Expand Up @@ -108,8 +120,41 @@ fn storable_enum_derive(s: &synstructure::Structure) -> TokenStream2 {
}
}
});

let size_hint_body = s.variants().iter().enumerate().map(|(index, variant)| {
let pat = variant.pat();
let index = index as u8;
let fields = variant.bindings().iter().map(|field| {
let span = field.ast().ty.span();
quote_spanned!(span =>
size_hint += ::ink::storage::traits::Storable::size_hint(#field);
)
});
quote! {
#pat => {
{ size_hint += <::core::primitive::u8 as ::ink::storage::traits::Storable>::size_hint(&#index); }
#(
{ #fields }
)*
}
}
});

s.gen_impl(quote! {
gen impl ::ink::storage::traits::Storable for @Self {
#[inline(always)]
#[allow(non_camel_case_types)]
#[allow(unused_mut)]
fn size_hint(&self) -> ::core::primitive::usize {
let mut size_hint = 0;
match self {
#(
#size_hint_body
)*
}
size_hint
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result<Self, ::scale::Error> {
Expand Down
132 changes: 132 additions & 0 deletions crates/ink/macro/src/storage/tests/storable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ fn unit_struct_works() {
expands to {
const _: () = {
impl ::ink::storage::traits::Storable for UnitStruct {
#[inline(always)]
#[allow(non_camel_case_types)]
#[allow(unused_mut)]
fn size_hint(&self) -> ::core::primitive::usize {
let mut size_hint = 0;
match self {
UnitStruct => {}
}
size_hint
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result<Self, ::scale::Error> {
Expand Down Expand Up @@ -63,6 +74,27 @@ fn struct_works() {
expands to {
const _: () = {
impl ::ink::storage::traits::Storable for NamedFields {
#[inline (always)]
#[allow (non_camel_case_types)]
#[allow(unused_mut)]
fn size_hint(&self) -> ::core::primitive::usize {
let mut size_hint = 0;
match self {
NamedFields { a : __binding_0 , b : __binding_1 , d : __binding_2 , } => {
{
size_hint += ::ink::storage:: traits:: Storable:: size_hint(__binding_0);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_1);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_2);
}
}
}
size_hint
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result<Self, ::scale::Error> {
Expand Down Expand Up @@ -123,6 +155,20 @@ fn one_variant_enum_works() {
expands to {
const _: () = {
impl ::ink::storage::traits::Storable for OneVariantEnum {
#[inline(always)]
#[allow(non_camel_case_types)]
#[allow(unused_mut)]
fn size_hint (&self) -> ::core::primitive::usize {
let mut size_hint = 0;
match self {
OneVariantEnum::A => {
{
size_hint += <::core::primitive::u8 as ::ink::storage::traits::Storable>::size_hint(&0u8);
}
}
}
size_hint
}
#[inline(always)]
#[allow(non_camel_case_types)]
fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result<Self, ::scale::Error> {
Expand Down Expand Up @@ -168,6 +214,43 @@ fn enum_works() {
expands to {
const _: () = {
impl ::ink::storage::traits::Storable for MixedEnum {
#[inline(always)]
#[allow(non_camel_case_types)]
#[allow(unused_mut)]
fn size_hint (&self) -> ::core::primitive::usize{
let mut size_hint = 0;
match self {
MixedEnum::A => {
{
size_hint += <::core::primitive::u8 as ::ink::storage::traits::Storable>::size_hint(&0u8);
}
}
MixedEnum::B(__binding_0, __binding_1,) => {
{
size_hint += <::core::primitive::u8 as ::ink::storage::traits::Storable>::size_hint(&1u8);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_0);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_1);
}
}
MixedEnum::C { a: __binding_0, b: __binding_1, } => {
{
size_hint += <::core::primitive::u8 as ::ink::storage::traits::Storable>::size_hint(&2u8);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_0);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_1);
}
}
}
size_hint
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result<Self, ::scale::Error> {
Expand Down Expand Up @@ -272,6 +355,23 @@ fn generic_struct_works() {
T1: ::ink::storage::traits::Storable,
(T1 , T2): ::ink::storage::traits::Storable
{
#[inline(always)]
#[allow(non_camel_case_types)]
#[allow(unused_mut)]
fn size_hint(&self) -> ::core::primitive::usize {
let mut size_hint = 0;
match self {
GenericStruct { a : __binding_0 , b : __binding_1 , } => {
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_0);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_1);
}
}
}
size_hint
}
#[inline(always)]
#[allow(non_camel_case_types)]
fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result<Self, ::scale::Error> {
Expand Down Expand Up @@ -332,6 +432,38 @@ fn generic_enum_works() {
T1: ::ink::storage::traits::Storable,
T2: ::ink::storage::traits::Storable
{
#[inline(always)]
#[allow(non_camel_case_types)]
#[allow(unused_mut)]
fn size_hint(&self) -> ::core::primitive::usize {
let mut size_hint = 0;
match self {
GenericEnum::Tuple (__binding_0, __binding_1,) => {
{
size_hint += <::core::primitive:: u8 as::ink::storage::traits::Storable>::size_hint(&0u8);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_0);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_1);
}
}
GenericEnum::Named { a: __binding_0, b: __binding_1,} => {
{
size_hint += <::core::primitive::u8 as::ink::storage::traits::Storable>::size_hint(&1u8);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_0);
}
{
size_hint += ::ink::storage::traits::Storable::size_hint(__binding_1);
}
}
}
size_hint
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn decode<__ink_I: ::scale::Input>(__input: &mut __ink_I) -> ::core::result::Result<Self, ::scale::Error> {
Expand Down
Loading