Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions crates/env/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ use crate::engine::off_chain::OffChainError;
pub enum Error {
/// Error upon decoding an encoded value.
Decode(scale::Error),
/// The static buffer used during ABI encoding or ABI decoding is too small.
BufferTooSmall,
/// An error that can only occur in the off-chain environment.
#[cfg(any(feature = "std", test, doc))]
OffChain(OffChainError),
Expand Down
37 changes: 37 additions & 0 deletions crates/ink/macro/src/storage/storable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ fn storable_struct_derive(s: &synstructure::Structure) -> TokenStream2 {
::ink::storage::traits::Storable::encode(#binding, __dest);
)
});
let encoded_size_body =
variant.fold(quote!(::core::primitive::usize::MIN), |acc, binding| {
let span = binding.ast().ty.span();
quote_spanned!(span =>
#acc.saturating_add(::ink::storage::traits::Storable::encoded_size(#binding))
)
});

s.gen_impl(quote! {
gen impl ::ink::storage::traits::Storable for @Self {
Expand All @@ -50,6 +57,12 @@ fn storable_struct_derive(s: &synstructure::Structure) -> TokenStream2 {
fn encode<__ink_O: ::ink::scale::Output + ?::core::marker::Sized>(&self, __dest: &mut __ink_O) {
match self { #encode_body }
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn encoded_size(&self) -> ::core::primitive::usize {
match self { #encoded_size_body }
}
}
})
}
Expand Down Expand Up @@ -108,6 +121,20 @@ fn storable_enum_derive(s: &synstructure::Structure) -> TokenStream2 {
}
}
});

let encoded_size_body = s.variants().iter().map(|variant| {
let pat = variant.pat();
let field = variant.bindings().iter().fold(quote!(1usize), |acc, field| {
let span = field.ast().ty.span();
quote_spanned!(span =>
#acc.saturating_add(::ink::storage::traits::Storable::encoded_size(#field))
)
});
quote! {
#pat => { #field }
}
});

s.gen_impl(quote! {
gen impl ::ink::storage::traits::Storable for @Self {
#[inline(always)]
Expand All @@ -130,6 +157,16 @@ fn storable_enum_derive(s: &synstructure::Structure) -> TokenStream2 {
)*
}
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn encoded_size(&self) -> ::core::primitive::usize {
match self {
#(
#encoded_size_body
)*
}
}
}
})
}
Expand Down
76 changes: 76 additions & 0 deletions crates/ink/macro/src/tests/storable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ fn unit_struct_works() {
UnitStruct => { }
}
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn encoded_size(&self) -> ::core::primitive::usize {
match self {
UnitStruct => { ::core::primitive::usize::MIN }
}
}
}
};
}
Expand Down Expand Up @@ -106,6 +114,19 @@ fn struct_works() {
}
}
}

#[inline (always)]
#[allow (non_camel_case_types)]
fn encoded_size(&self) -> ::core::primitive::usize {
match self {
NamedFields { a : __binding_0 , b : __binding_1 , d : __binding_2 , } => {
::core::primitive::usize::MIN
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_0))
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_1))
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_2))
}
}
}
}
};
}
Expand Down Expand Up @@ -149,6 +170,14 @@ fn one_variant_enum_works() {
}
}
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn encoded_size (&self) -> ::core::primitive::usize {
match self {
OneVariantEnum::A => { 1usize }
}
}
}
};
}
Expand Down Expand Up @@ -244,6 +273,24 @@ fn enum_works() {
}
}
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn encoded_size (&self) -> ::core::primitive::usize{
match self {
MixedEnum::A => { 1usize }
MixedEnum::B(__binding_0, __binding_1,) => {
1usize
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_0))
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_1))
}
MixedEnum::C { a: __binding_0, b: __binding_1, } => {
1usize
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_0))
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_1))
}
}
}
}
};
}
Expand Down Expand Up @@ -310,6 +357,18 @@ fn generic_struct_works() {
}
}
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn encoded_size(&self) -> ::core::primitive::usize {
match self {
GenericStruct { a : __binding_0 , b : __binding_1 , } => {
::core::primitive::usize::MIN
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_0))
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_1))
}
}
}
}
};
}
Expand Down Expand Up @@ -394,6 +453,23 @@ fn generic_enum_works() {
}
}
}

#[inline(always)]
#[allow(non_camel_case_types)]
fn encoded_size(&self) -> ::core::primitive::usize {
match self {
GenericEnum::Tuple (__binding_0, __binding_1,) => {
1usize
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_0))
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_1))
}
GenericEnum::Named { a: __binding_0, b: __binding_1,} => {
1usize
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_0))
.saturating_add(::ink::storage::traits::Storable::encoded_size(__binding_1))
}
}
}
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ impl<KEY: StorageKey> Storable for Contract<KEY> {
c: Default::default(),
})
}

fn encoded_size(&self) -> usize {
2 + 8 + 16
}
}

fn main() {
Expand Down
Loading