Contract storage limit (#3126)

* srml-contracts: Remove hard-coded code hashes from tests.

This makes it easier to update existing and add new test Wasm modules.

* Test maximum contract storage write size.

* Implement storage value limit for contracts.

* Bump node runtime spec version.
This commit is contained in:
Jim Posen
2019-07-16 16:23:06 +02:00
committed by Sergei Pepyakin
parent 95061beb79
commit 768eb1af4d
6 changed files with 203 additions and 55 deletions
+19 -6
View File
@@ -61,10 +61,9 @@ pub trait Ext {
/// was deleted.
fn get_storage(&self, key: &StorageKey) -> Option<Vec<u8>>;
/// Sets the storage entry by the given key to the specified value.
///
/// If `value` is `None` then the storage entry is deleted.
fn set_storage(&mut self, key: StorageKey, value: Option<Vec<u8>>);
/// Sets the storage entry by the given key to the specified value. If `value` is `None` then
/// the storage entry is deleted. Returns an Err if the value size is too large.
fn set_storage(&mut self, key: StorageKey, value: Option<Vec<u8>>) -> Result<(), &'static str>;
/// Instantiate a contract from the given code.
///
@@ -124,6 +123,9 @@ pub trait Ext {
/// Returns the current block number.
fn block_number(&self) -> BlockNumberOf<Self::T>;
/// Returns the maximum allowed size of a storage item.
fn max_value_size(&self) -> u32;
}
/// Loader is a companion of the `Vm` trait. It loads an appropriate abstract
@@ -606,10 +608,17 @@ where
self.ctx.overlay.get_storage(&self.ctx.self_account, self.ctx.self_trie_id.as_ref(), key)
}
fn set_storage(&mut self, key: StorageKey, value: Option<Vec<u8>>) {
fn set_storage(&mut self, key: StorageKey, value: Option<Vec<u8>>) -> Result<(), &'static str> {
if let Some(ref value) = value {
if self.max_value_size() < value.len() as u32 {
return Err("value size exceeds maximum");
}
}
self.ctx
.overlay
.set_storage(&self.ctx.self_account, key, value)
.set_storage(&self.ctx.self_account, key, value);
Ok(())
}
fn instantiate(
@@ -682,6 +691,10 @@ where
}
fn block_number(&self) -> T::BlockNumber { self.block_number }
fn max_value_size(&self) -> u32 {
self.ctx.config.max_value_size
}
}
/// These tests exercise the executive layer.