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 55 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
1 change: 1 addition & 0 deletions .config/cargo_spellcheck.dic
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ defragmentation
deploy
dereferencing
deserialize/S
deserialization
dispatchable/S
encodable
evaluable
Expand Down
12 changes: 7 additions & 5 deletions crates/engine/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl Engine {

/// Writes the encoded value into the storage at the given key.
/// Returns the size of the previously stored value at the key if any.
pub fn set_storage(&mut self, key: &[u8; 32], encoded_value: &[u8]) -> Option<u32> {
pub fn set_storage(&mut self, key: &[u8], encoded_value: &[u8]) -> Option<u32> {
let callee = self.get_callee();
let account_id = AccountId::from_bytes(&callee[..]);

Expand All @@ -243,7 +243,7 @@ impl Engine {
}

/// Returns the decoded contract storage at the key if any.
pub fn get_storage(&mut self, key: &[u8; 32], output: &mut &mut [u8]) -> Result {
pub fn get_storage(&mut self, key: &[u8], output: &mut &mut [u8]) -> Result {
let callee = self.get_callee();
let account_id = AccountId::from_bytes(&callee[..]);

Expand All @@ -258,7 +258,7 @@ impl Engine {
}

/// Returns the size of the value stored in the contract storage at the key if any.
pub fn contains_storage(&mut self, key: &[u8; 32]) -> Option<u32> {
pub fn contains_storage(&mut self, key: &[u8]) -> Option<u32> {
let callee = self.get_callee();
let account_id = AccountId::from_bytes(&callee[..]);

Expand All @@ -269,14 +269,16 @@ impl Engine {
}

/// Removes the storage entries at the given key.
pub fn clear_storage(&mut self, key: &[u8; 32]) {
pub fn clear_storage(&mut self, key: &[u8]) -> Option<u32> {
let callee = self.get_callee();
let account_id = AccountId::from_bytes(&callee[..]);
self.debug_info.inc_writes(account_id.clone());
let _ = self
.debug_info
.remove_cell_for_account(account_id, key.to_vec());
let _ = self.database.remove_contract_storage(&callee, key);
self.database
.remove_contract_storage(&callee, key)
.map(|val| val.len() as u32)
}

/// Remove the calling account and transfer remaining balance.
Expand Down
36 changes: 21 additions & 15 deletions crates/env/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ use crate::{
Environment,
Result,
};
use ink_primitives::Key;

/// Returns the address of the caller of the executed contract.
///
Expand Down Expand Up @@ -183,49 +182,56 @@ where
})
}

/// Writes the value to the contract storage under the given key and returns
/// the size of pre-existing value at the specified key if any.
/// Writes the value to the contract storage under the given storage key and returns the size
/// of pre-existing value if any.
///
/// # Panics
///
/// - If the encode length of value exceeds the configured maximum value length of a storage entry.
pub fn set_contract_storage<V>(key: &Key, value: &V) -> Option<u32>
pub fn set_contract_storage<K, V>(key: &K, value: &V) -> Option<u32>
where
K: scale::Encode,
V: scale::Encode,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
EnvBackend::set_contract_storage::<V>(instance, key, value)
EnvBackend::set_contract_storage::<K, V>(instance, key, value)
})
}

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

/// Checks whether there is a value stored under the given key in
/// the contract's storage.
/// Checks whether there is a value stored under the given storage key in the contract's storage.
///
/// If a value is stored under the specified key, the size of the value is returned.
pub fn contract_storage_contains(key: &Key) -> Option<u32> {
pub fn contains_contract_storage<K>(key: &K) -> Option<u32>
where
K: scale::Encode,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
EnvBackend::contract_storage_contains(instance, key)
EnvBackend::contains_contract_storage::<K>(instance, key)
})
}

/// Clears the contract's storage key entry.
pub fn clear_contract_storage(key: &Key) {
/// Clears the contract's storage entry under the given storage key.
pub fn clear_contract_storage<K>(key: &K) -> Option<u32>
where
K: scale::Encode,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
EnvBackend::clear_contract_storage(instance, key)
EnvBackend::clear_contract_storage::<K>(instance, key)
})
}

Expand Down
26 changes: 16 additions & 10 deletions crates/env/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use crate::{
Environment,
Result,
};
use ink_primitives::Key;

/// The flags to indicate further information about the end of a contract execution.
#[derive(Default)]
Expand Down Expand Up @@ -162,26 +161,33 @@ impl CallFlags {

/// Environmental contract functionality that does not require `Environment`.
pub trait EnvBackend {
/// Writes the value to the contract storage under the given key and returns
/// the size of the pre-existing value at the specified key if any.
fn set_contract_storage<V>(&mut self, key: &Key, value: &V) -> Option<u32>
/// 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>
where
K: scale::Encode,
V: scale::Encode;

/// Returns the value stored under the given key in the contract's storage if any.
/// Returns the value stored under the given storage key in the contract's storage if any.
///
/// # Errors
///
/// - If the decoding of the typed value failed
fn get_contract_storage<R>(&mut self, key: &Key) -> Result<Option<R>>
fn get_contract_storage<K, R>(&mut self, key: &K) -> Result<Option<R>>
where
K: scale::Encode,
R: scale::Decode;

/// Returns the size of a value stored under the specified key is returned if any.
fn contract_storage_contains(&mut self, key: &Key) -> Option<u32>;
/// Returns the size of a value stored under the given storage key is returned if any.
fn contains_contract_storage<K>(&mut self, key: &K) -> Option<u32>
where
K: scale::Encode;

/// Clears the contract's storage key entry.
fn clear_contract_storage(&mut self, key: &Key);
/// Clears the contract's storage key entry under the given storage key.
fn clear_contract_storage<K>(&mut self, key: &K) -> Option<u32>
where
K: scale::Encode;

/// Returns the execution input to the executed contract and decodes it as `T`.
///
Expand Down
25 changes: 16 additions & 9 deletions crates/env/src/engine/off_chain/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ use ink_engine::{
ext,
ext::Engine,
};
use ink_primitives::Key;

/// 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 @@ -184,20 +183,22 @@ impl EnvInstance {
}

impl EnvBackend for EnvInstance {
fn set_contract_storage<V>(&mut self, key: &Key, value: &V) -> Option<u32>
fn set_contract_storage<K, V>(&mut self, key: &K, value: &V) -> Option<u32>
where
K: scale::Encode,
V: scale::Encode,
{
let v = scale::Encode::encode(value);
self.engine.set_storage(key.as_ref(), &v[..])
self.engine.set_storage(&key.encode(), &v[..])
}

fn get_contract_storage<R>(&mut self, key: &Key) -> Result<Option<R>>
fn get_contract_storage<K, R>(&mut self, key: &K) -> Result<Option<R>>
where
K: scale::Encode,
R: scale::Decode,
{
let mut output: [u8; 9600] = [0; 9600];
match self.engine.get_storage(key.as_ref(), &mut &mut output[..]) {
match self.engine.get_storage(&key.encode(), &mut &mut output[..]) {
Ok(_) => (),
Err(ext::Error::KeyNotFound) => return Ok(None),
Err(_) => panic!("encountered unexpected error"),
Expand All @@ -206,12 +207,18 @@ impl EnvBackend for EnvInstance {
Ok(Some(decoded))
}

fn contract_storage_contains(&mut self, key: &Key) -> Option<u32> {
self.engine.contains_storage(key.as_ref())
fn contains_contract_storage<K>(&mut self, key: &K) -> Option<u32>
where
K: scale::Encode,
{
self.engine.contains_storage(&key.encode())
}

fn clear_contract_storage(&mut self, key: &Key) {
self.engine.clear_storage(key.as_ref())
fn clear_contract_storage<K>(&mut self, key: &K) -> Option<u32>
where
K: scale::Encode,
{
self.engine.clear_storage(&key.encode())
}

fn decode_input<T>(&mut self) -> Result<T>
Expand Down
6 changes: 5 additions & 1 deletion crates/env/src/engine/on_chain/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ impl StaticBuffer {
impl core::ops::Index<core::ops::RangeFull> for StaticBuffer {
type Output = [u8];

#[inline(always)]
fn index(&self, index: core::ops::RangeFull) -> &Self::Output {
core::ops::Index::index(&self.buffer[..], index)
}
}

impl core::ops::IndexMut<core::ops::RangeFull> for StaticBuffer {
#[inline(always)]
fn index_mut(&mut self, index: core::ops::RangeFull) -> &mut Self::Output {
core::ops::IndexMut::index_mut(&mut self.buffer[..], index)
}
Expand All @@ -47,7 +49,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 +156,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 +175,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
Loading