Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage rework #1217

Closed
wants to merge 63 commits into from
Closed
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
b7a2e81
Added and implemented all primitives of a new storage. Implemented `s…
xgreenx Apr 11, 2022
2c06fcc
Simplified storage straits, moved check for atomic to separate trait.
xgreenx Apr 12, 2022
992706e
Refactored StorageLayout.
xgreenx Apr 15, 2022
17b433a
Updated key to be more readble
xgreenx Apr 15, 2022
09fb544
BE looks better than LE=)
xgreenx Apr 15, 2022
184c550
Fix comment
xgreenx Apr 15, 2022
58c21ac
Removed all storage collections
xgreenx May 6, 2022
2a1dea4
Merge branch 'master' into features/storage-rework
xgreenx May 6, 2022
5644402
Merged with master. Added tests that `StorageValue` and `StorageMappi…
xgreenx May 6, 2022
7e4b56d
Removed `SpreadLayout` and all related stuff and traits.
xgreenx May 9, 2022
4ab1b5f
Updated all examples to use the latest changes.
xgreenx May 11, 2022
76c50ee
Removed `StorageType2`. `StorageType` is used everywhere now.
xgreenx May 12, 2022
750bce2
Merge branch 'master' into features/storage-rework
xgreenx May 12, 2022
e8bf915
Make clippy happy
xgreenx May 12, 2022
6f868fb
Make clippy happy.
xgreenx May 12, 2022
b74b9fd
Update comment
xgreenx May 12, 2022
02f478f
Unified metadata and storage key generation. The metadata contains al…
xgreenx May 17, 2022
414d0c0
Merge branch 'master' into features/storage-rework
xgreenx May 17, 2022
b8e74bd
Update metadata to version 4
xgreenx May 17, 2022
da38d41
Fixed tests
xgreenx May 17, 2022
145850f
Merge branch 'master' into features/storage-rework
xgreenx May 17, 2022
f107ca1
Implement `TypeInfo` and `StorageLayout` in `storage_item` macro by d…
xgreenx May 17, 2022
078a04a
Fix tests
xgreenx May 17, 2022
f719a74
Merge branch 'master' into features/storage-rework
xgreenx May 18, 2022
6fe995c
Merge with new release
xgreenx May 18, 2022
ca8a270
Temporary use version 3 for metadata
xgreenx May 18, 2022
294ffc3
Fix ink-waterfall
xgreenx May 18, 2022
9ff2b0c
Size improvements
xgreenx May 18, 2022
52d4070
Merge branch 'master' into features/storage-rework
xgreenx May 18, 2022
44ec9e7
Merge mother
xgreenx May 18, 2022
58c969f
More inline)
xgreenx May 18, 2022
8c93461
Revert back optimization with encode. Better to do it in follow up
xgreenx May 18, 2022
099442b
More size improvements
xgreenx May 19, 2022
377a26d
Revert back panic on pull)
xgreenx May 19, 2022
97fa7b3
One more optimization. When it will be end???=)
xgreenx May 19, 2022
07d3619
Merge branch 'master' into features/storage-rework
xgreenx May 19, 2022
3db8e6d
Added comments why we don't need `extract_from_slice`
xgreenx May 19, 2022
e88d535
Removed `V4` of metadata. It will be updated in follow-up PR.
xgreenx May 19, 2022
c34e67c
We need to pass len...)
xgreenx May 19, 2022
0e136cf
Make clippy happy
xgreenx May 19, 2022
358c00d
Removed `Key`. Prepared the api for transparent hashing.
xgreenx May 20, 2022
2aeb623
Remove bench
xgreenx May 20, 2022
2d34b1d
Improve of dns example by adding one ref=DDDDDD
xgreenx May 20, 2022
88977bc
Merge branch 'master' into features/storage-rework
xgreenx May 21, 2022
45390a6
Merge branch 'master' into features/storage-rework
xgreenx May 25, 2022
9502e34
Renamed everything. Introduces `Storable`
xgreenx May 26, 2022
6441dfc
Make clippy happy
xgreenx May 27, 2022
7fa8cd0
Fixed storable tests
xgreenx Jun 3, 2022
334160c
Fixed storable tests and clippy
xgreenx Jun 3, 2022
d6bfac6
Fix spellcheck
xgreenx Jun 3, 2022
5f05846
Merge branch 'master' into features/storage-rework
xgreenx Jul 11, 2022
e1fe78e
Merge branch 'master' into features/storage-rework
xgreenx Jul 12, 2022
11c86dd
Use unstable functions(with transparent hashing) to work with storage.
xgreenx Jul 12, 2022
345ca79
Fix clippy
xgreenx Jul 12, 2022
b8e46bd
Fix readme
xgreenx Jul 12, 2022
eae9152
Apply suggestions from code review
xgreenx Jul 13, 2022
2b35bd5
Update crates/lang/ir/src/ir/storage_item/config.rs
xgreenx Jul 13, 2022
1873108
Added suggested panic on unwrap
xgreenx Jul 13, 2022
9436889
Merge branch 'master' into features/storage-rework
xgreenx Jul 20, 2022
188d46d
Update to 4.0.0
xgreenx Jul 20, 2022
e6f77d8
Merge branch 'master' into features/storage-rework
xgreenx Jul 20, 2022
9b022f3
Updated errors.
xgreenx Jul 20, 2022
07698e0
Fixed strerr text
xgreenx Jul 20, 2022
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
40 changes: 39 additions & 1 deletion crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ use crate::{
Environment,
Result,
};
use ink_primitives::Key;
use ink_primitives::{
Key,
StorageKey,
};

/// Returns the address of the caller of the executed contract.
///
Expand Down Expand Up @@ -229,6 +232,41 @@ pub fn clear_contract_storage(key: &Key) {
})
}

/// Writes the value to the contract storage under the given key.
///
/// # Panics
///
/// - If the encode length of value exceeds the configured maximum value length of a storage entry.
pub fn set_storage_value<V>(key: &StorageKey, value: &V) -> Option<u32>
where
V: scale::Encode,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
EnvBackend::set_storage_value::<V>(instance, key, value)
})
}

/// Returns the value stored under the given key in the contract's storage if any.
///
/// # Errors
///
/// - If the decoding of the typed value failed (`KeyNotFound`)
pub fn get_storage_value<R>(key: &StorageKey) -> Result<Option<R>>
where
R: scale::Decode,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
EnvBackend::get_storage_value::<R>(instance, key)
})
}

/// Clears the contract's storage key entry.
pub fn clear_storage_value(key: &StorageKey) {
<EnvInstance as OnInstance>::on_instance(|instance| {
EnvBackend::clear_storage_value(instance, key)
})
}

/// Invokes a contract message and returns its result.
///
/// # Note
Expand Down
15 changes: 14 additions & 1 deletion crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ use crate::{
Environment,
Result,
};
use ink_primitives::Key;
use ink_primitives::{
Key,
StorageKey,
};

/// The flags to indicate further information about the end of a contract execution.
#[derive(Default)]
Expand Down Expand Up @@ -183,6 +186,16 @@ pub trait EnvBackend {
/// Clears the contract's storage key entry.
fn clear_contract_storage(&mut self, key: &Key);

fn set_storage_value<V>(&mut self, key: &StorageKey, value: &V) -> Option<u32>
where
V: scale::Encode;

fn get_storage_value<R>(&mut self, key: &StorageKey) -> Result<Option<R>>
where
R: scale::Decode;

fn clear_storage_value(&mut self, key: &StorageKey);
athei marked this conversation as resolved.
Show resolved Hide resolved

/// Returns the execution input to the executed contract and decodes it as `T`.
///
/// # Note
Expand Down
24 changes: 23 additions & 1 deletion crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ use ink_engine::{
ext,
ext::Engine,
};
use ink_primitives::Key;
use ink_primitives::{
Key,
StorageKey,
StorageKeyComposer,
};

/// The capacity of the static buffer.
/// This is the same size as the ink! on-chain environment. We chose to use the same size
Expand Down Expand Up @@ -214,6 +218,24 @@ impl EnvBackend for EnvInstance {
self.engine.clear_storage(key.as_ref())
}

fn set_storage_value<V>(&mut self, key: &StorageKey, value: &V) -> Option<u32>
where
V: scale::Encode,
{
self.set_contract_storage(&StorageKeyComposer::old_key(key), value)
}

fn get_storage_value<R>(&mut self, key: &StorageKey) -> Result<Option<R>>
where
R: scale::Decode,
{
self.get_contract_storage(&StorageKeyComposer::old_key(key))
}

fn clear_storage_value(&mut self, key: &StorageKey) {
self.clear_contract_storage(&StorageKeyComposer::old_key(key))
}

fn decode_input<T>(&mut self) -> Result<T>
where
T: scale::Decode,
Expand Down
4 changes: 3 additions & 1 deletion crates/env/src/engine/on_chain/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl core::ops::IndexMut<core::ops::RangeFull> for StaticBuffer {
/// Utility to allow for non-heap allocating encoding into a static buffer.
///
/// Required by `ScopedBuffer` internals.
struct EncodeScope<'a> {
pub struct EncodeScope<'a> {
buffer: &'a mut [u8],
len: usize,
}
Expand Down Expand Up @@ -154,6 +154,7 @@ impl<'a> ScopedBuffer<'a> {

/// Encode the given value into the scoped buffer and return the sub slice
/// containing all the encoded bytes.
#[inline(always)]
pub fn take_encoded<T>(&mut self, value: &T) -> &'a mut [u8]
where
T: scale::Encode,
Expand All @@ -172,6 +173,7 @@ impl<'a> ScopedBuffer<'a> {
/// Does not return the buffer immediately so that other values can be appended
/// afterwards. The [`take_appended`] method shall be used to return the buffer
/// that includes all appended encodings as a single buffer.
#[inline(always)]
pub fn append_encoded<T>(&mut self, value: &T)
where
T: scale::Encode,
Expand Down
13 changes: 12 additions & 1 deletion crates/env/src/engine/on_chain/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,14 @@ mod sys {
}
}

#[inline(always)]
fn extract_from_slice(output: &mut &mut [u8], new_len: usize) {
debug_assert!(new_len <= output.len());
let tmp = core::mem::take(output);
*output = &mut tmp[..new_len];
}

#[inline(always)]
pub fn instantiate(
code_hash: &[u8],
gas_limit: u64,
Expand Down Expand Up @@ -425,6 +427,7 @@ pub fn instantiate(
ret_code.into()
}

#[inline(always)]
pub fn call(
flags: u32,
callee: &[u8],
Expand Down Expand Up @@ -452,6 +455,7 @@ pub fn call(
ret_code.into()
}

#[inline(always)]
pub fn delegate_call(
flags: u32,
code_hash: &[u8],
Expand Down Expand Up @@ -513,6 +517,7 @@ pub fn clear_storage(key: &[u8]) {
unsafe { sys::seal_clear_storage(Ptr32::from_slice(key)) }
}

#[inline(always)]
pub fn get_storage(key: &[u8], output: &mut &mut [u8]) -> Result {
let mut output_len = output.len() as u32;
let ret_code = {
Expand All @@ -537,6 +542,7 @@ pub fn terminate(beneficiary: &[u8]) -> ! {
unsafe { sys::seal_terminate(Ptr32::from_slice(beneficiary)) }
}

#[inline(always)]
pub fn call_chain_extension(func_id: u32, input: &[u8], output: &mut &mut [u8]) -> u32 {
let mut output_len = output.len() as u32;
let ret_code = {
Expand All @@ -554,6 +560,7 @@ pub fn call_chain_extension(func_id: u32, input: &[u8], output: &mut &mut [u8])
ret_code.into_u32()
}

#[inline(always)]
pub fn input(output: &mut &mut [u8]) {
let mut output_len = output.len() as u32;
{
Expand All @@ -580,6 +587,7 @@ pub fn return_value(flags: ReturnFlags, return_value: &[u8]) -> ! {
macro_rules! impl_seal_wrapper_for {
( $( ($name:ident => $seal_name:ident), )* ) => {
$(
#[inline(always)]
pub fn $name(output: &mut &mut [u8]) {
let mut output_len = output.len() as u32;
{
Expand All @@ -590,7 +598,8 @@ macro_rules! impl_seal_wrapper_for {
)
};
}
extract_from_slice(output, output_len as usize);
// We don't need `extract_from_slice` here because it is stored in the own array
// in `get_property_little_endian` and `get_property_inplace`
}
)*
}
Expand All @@ -606,6 +615,7 @@ impl_seal_wrapper_for! {
(minimum_balance => seal_minimum_balance),
}

#[inline(always)]
pub fn weight_to_fee(gas: u64, output: &mut &mut [u8]) {
let mut output_len = output.len() as u32;
{
Expand All @@ -620,6 +630,7 @@ pub fn weight_to_fee(gas: u64, output: &mut &mut [u8]) {
extract_from_slice(output, output_len as usize);
}

#[inline(always)]
pub fn random(subject: &[u8], output: &mut &mut [u8]) {
let mut output_len = output.len() as u32;
{
Expand Down
36 changes: 32 additions & 4 deletions crates/env/src/engine/on_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use super::{
ext,
EncodeScope,
EnvInstance,
Error as ExtError,
ScopedBuffer,
Expand Down Expand Up @@ -46,7 +47,11 @@ use crate::{
ReturnFlags,
TypedEnvBackend,
};
use ink_primitives::Key;
use ink_primitives::{
Key,
StorageKey,
StorageKeyComposer,
};

impl CryptoHash for Blake2x128 {
fn hash(input: &[u8], output: &mut <Self as HashOutput>::Type) {
Expand Down Expand Up @@ -174,6 +179,7 @@ where
}

impl EnvInstance {
#[inline(always)]
/// Returns a new scoped buffer for the entire scope of the static 16 kB buffer.
fn scoped_buffer(&mut self) -> ScopedBuffer {
ScopedBuffer::from(&mut self.buffer[..])
Expand All @@ -184,6 +190,7 @@ impl EnvInstance {
/// # Note
///
/// This skips the potentially costly decoding step that is often equivalent to a `memcpy`.
#[inline(always)]
fn get_property_inplace<T>(&mut self, ext_fn: fn(output: &mut &mut [u8])) -> T
where
T: Default + AsMut<[u8]>,
Expand All @@ -198,6 +205,7 @@ impl EnvInstance {
/// # Note
///
/// This skips the potentially costly decoding step that is often equivalent to a `memcpy`.
#[inline(always)]
fn get_property_little_endian<T>(&mut self, ext_fn: fn(output: &mut &mut [u8])) -> T
where
T: FromLittleEndian,
Expand All @@ -208,6 +216,7 @@ impl EnvInstance {
}

/// Returns the contract property value.
#[inline(always)]
fn get_property<T>(&mut self, ext_fn: fn(output: &mut &mut [u8])) -> Result<T>
where
T: scale::Decode,
Expand Down Expand Up @@ -249,6 +258,24 @@ impl EnvBackend for EnvInstance {
ext::clear_storage(key.as_ref())
}

fn set_storage_value<V>(&mut self, key: &StorageKey, value: &V) -> Option<u32>
where
V: scale::Encode,
{
self.set_contract_storage(&StorageKeyComposer::old_key(key), value)
}

fn get_storage_value<R>(&mut self, key: &StorageKey) -> Result<Option<R>>
where
R: scale::Decode,
{
self.get_contract_storage(&StorageKeyComposer::old_key(key))
}

fn clear_storage_value(&mut self, key: &StorageKey) {
self.clear_contract_storage(&StorageKeyComposer::old_key(key))
}

fn decode_input<T>(&mut self) -> Result<T>
where
T: scale::Decode,
Expand All @@ -260,9 +287,10 @@ impl EnvBackend for EnvInstance {
where
R: scale::Encode,
{
let mut scope = self.scoped_buffer();
let enc_return_value = scope.take_encoded(return_value);
ext::return_value(flags, enc_return_value);
let mut scope = EncodeScope::from(&mut self.buffer[..]);
return_value.encode_to(&mut scope);
let len = scope.len();
ext::return_value(flags, &self.buffer[..][..len]);
xgreenx marked this conversation as resolved.
Show resolved Hide resolved
}

fn debug_message(&mut self, content: &str) {
Expand Down
1 change: 1 addition & 0 deletions crates/env/src/engine/on_chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod impls;

use self::{
buffer::{
EncodeScope,
ScopedBuffer,
StaticBuffer,
},
Expand Down
1 change: 1 addition & 0 deletions crates/lang/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"]
name = "ink_lang_codegen"

[dependencies]
ink_primitives = { version = "3.1.0", path = "../../primitives" }
ir = { version = "3.1.0", package = "ink_lang_ir", path = "../ir", default-features = false }
quote = "1"
syn = { version = "1.0", features = ["parsing", "full", "extra-traits"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,9 @@ impl CallBuilder<'_> {
/// Implements the underlying on-chain calling of the ink! smart contract
/// messages and trait implementations in a type safe way.
#[repr(transparent)]
#[cfg_attr(feature = "std", derive(
::scale_info::TypeInfo,
::ink_storage::traits::StorageLayout,
))]
#[::ink_lang::storage_item]
#[derive(
::core::fmt::Debug,
::ink_storage::traits::SpreadLayout,
::ink_storage::traits::PackedLayout,
::scale::Encode,
::scale::Decode,
::core::hash::Hash,
::core::cmp::PartialEq,
::core::cmp::Eq,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,9 @@ impl ContractRef<'_> {
let storage_ident = self.contract.module().storage().ident();
let ref_ident = self.generate_contract_ref_ident();
quote_spanned!(span=>
#[cfg_attr(feature = "std", derive(
::scale_info::TypeInfo,
::ink_storage::traits::StorageLayout,
))]
#[::ink_lang::storage_item]
#[derive(
::core::fmt::Debug,
::ink_storage::traits::SpreadLayout,
::ink_storage::traits::PackedLayout,
::scale::Encode,
::scale::Decode,
::core::hash::Hash,
::core::cmp::PartialEq,
::core::cmp::Eq,
Expand Down
Loading