Replace Vec<u8> with [u8; 32] for contract storage key (#2184)

* Replace Vec<u8> with [u8; 32] for contract storage key

* Read storage keys from sandbox memory into fixed size buffer

* Increment `impl_version`
This commit is contained in:
Andrew Jones
2019-04-03 09:12:54 +01:00
committed by Sergei Pepyakin
parent c98db99d80
commit 4c115e3f2d
5 changed files with 45 additions and 20 deletions
+6 -6
View File
@@ -174,7 +174,7 @@ mod tests {
use super::*;
use std::collections::HashMap;
use substrate_primitives::H256;
use crate::exec::{CallReceipt, Ext, InstantiateReceipt, EmptyOutputBuf};
use crate::exec::{CallReceipt, Ext, InstantiateReceipt, EmptyOutputBuf, StorageKey};
use crate::gas::GasMeter;
use crate::tests::{Test, Call};
use wabt;
@@ -199,7 +199,7 @@ mod tests {
}
#[derive(Default)]
pub struct MockExt {
storage: HashMap<Vec<u8>, Vec<u8>>,
storage: HashMap<StorageKey, Vec<u8>>,
creates: Vec<CreateEntry>,
transfers: Vec<TransferEntry>,
dispatches: Vec<DispatchEntry>,
@@ -210,11 +210,11 @@ mod tests {
impl Ext for MockExt {
type T = Test;
fn get_storage(&self, key: &[u8]) -> Option<Vec<u8>> {
fn get_storage(&self, key: &StorageKey) -> Option<Vec<u8>> {
self.storage.get(key).cloned()
}
fn set_storage(&mut self, key: &[u8], value: Option<Vec<u8>>) {
*self.storage.entry(key.to_vec()).or_insert(Vec::new()) = value.unwrap_or(Vec::new());
fn set_storage(&mut self, key: StorageKey, value: Option<Vec<u8>>) {
*self.storage.entry(key).or_insert(Vec::new()) = value.unwrap_or(Vec::new());
}
fn instantiate(
&mut self,
@@ -568,7 +568,7 @@ mod tests {
let mut mock_ext = MockExt::default();
mock_ext
.storage
.insert([0x11; 32].to_vec(), [0x22; 32].to_vec());
.insert([0x11; 32], [0x22; 32].to_vec());
let mut return_buf = Vec::new();
execute(
+25 -3
View File
@@ -177,6 +177,26 @@ fn read_sandbox_memory<E: Ext>(
Ok(buf)
}
/// Read designated chunk from the sandbox memory into the supplied buffer, consuming
/// an appropriate amount of gas.
///
/// Returns `Err` if one of the following conditions occurs:
///
/// - calculating the gas cost resulted in overflow.
/// - out of gas
/// - requested buffer is not within the bounds of the sandbox memory.
fn read_sandbox_memory_into_buf<E: Ext>(
ctx: &mut Runtime<E>,
ptr: u32,
buf: &mut [u8],
) -> Result<(), sandbox::HostError> {
charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReadMemory(buf.len() as u32))?;
ctx.memory().get(ptr, buf)?;
Ok(())
}
/// Write the given buffer to the designated location in the sandbox memory, consuming
/// an appropriate amount of gas.
///
@@ -228,14 +248,15 @@ define_env!(Env, <E: Ext>,
// where the value to set is placed. If `value_non_null` is set to 0, then this parameter is ignored.
// - value_len: the length of the value. If `value_non_null` is set to 0, then this parameter is ignored.
ext_set_storage(ctx, key_ptr: u32, value_non_null: u32, value_ptr: u32, value_len: u32) => {
let key = read_sandbox_memory(ctx, key_ptr, 32)?;
let mut key = [0; 32];
read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?;
let value =
if value_non_null != 0 {
Some(read_sandbox_memory(ctx, value_ptr, value_len)?)
} else {
None
};
ctx.ext.set_storage(&key, value);
ctx.ext.set_storage(key, value);
Ok(())
},
@@ -247,7 +268,8 @@ define_env!(Env, <E: Ext>,
// - key_ptr: pointer into the linear memory where the key
// of the requested value is placed.
ext_get_storage(ctx, key_ptr: u32) -> u32 => {
let key = read_sandbox_memory(ctx, key_ptr, 32)?;
let mut key = [0; 32];
read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?;
if let Some(value) = ctx.ext.get_storage(&key) {
ctx.scratch_buf = value;
Ok(0)