mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 07:41:08 +00:00
Check storage_key for validity (#2316)
* Intro `ChildStorageKey` for checked child keys * Get rid of Into in Externalities trait * Use Cow in ChildStorageKey * Fix tests for state-machine. * Clean * child_storage_root always return a value * Don't return Option from Ext::child_storage_root * Return 42 in child_storage_root * Return CHILD_STORAGE_KEY_PREFIX from trie id gen * Bump spec and impl version. * Require `:default:` in `is_child_trie_key_valid` * Add `default:` prefix. * Introduce `into_owned` for `ChildStorageKey`. * Add documentation. * Fix state-machine tests * Remove outdated TODO I check out with Emeric and he is ok with that * child_storage_root is infailable * Nit * Move assert after check. * Apply suggestions from @DemiMarie-parity Co-Authored-By: pepyakin <s.pepyakin@gmail.com> * Formatting nit in core/executor/src/wasm_executor.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Formatting nits from @thiolliere
This commit is contained in:
@@ -25,7 +25,7 @@ use wasmi::{
|
||||
};
|
||||
use wasmi::RuntimeValue::{I32, I64, self};
|
||||
use wasmi::memory_units::{Pages};
|
||||
use state_machine::Externalities;
|
||||
use state_machine::{Externalities, ChildStorageKey};
|
||||
use crate::error::{Error, ErrorKind, Result};
|
||||
use crate::wasm_utils::UserError;
|
||||
use primitives::{blake2_256, twox_128, twox_256, ed25519, sr25519, Pair};
|
||||
@@ -174,6 +174,10 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
HexDisplay::from(&key)
|
||||
);
|
||||
}
|
||||
let storage_key = ChildStorageKey::from_vec(storage_key)
|
||||
.ok_or_else(||
|
||||
UserError("ext_set_child_storage: child storage key is invalid")
|
||||
)?;
|
||||
this.ext.set_child_storage(storage_key, key, value);
|
||||
Ok(())
|
||||
},
|
||||
@@ -189,8 +193,13 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
format!("%{}", ::primitives::hexdisplay::ascii_format(&_preimage))
|
||||
} else {
|
||||
format!(" {}", ::primitives::hexdisplay::ascii_format(&key))
|
||||
}, HexDisplay::from(&key));
|
||||
this.ext.clear_child_storage(&storage_key, &key);
|
||||
}, HexDisplay::from(&key)
|
||||
);
|
||||
let storage_key = ChildStorageKey::from_vec(storage_key)
|
||||
.ok_or_else(||
|
||||
UserError("ext_clear_child_storage: child storage key is not valid")
|
||||
)?;
|
||||
this.ext.clear_child_storage(storage_key, &key);
|
||||
Ok(())
|
||||
},
|
||||
ext_clear_storage(key_data: *const u8, key_len: u32) => {
|
||||
@@ -214,7 +223,11 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
storage_key_len as usize
|
||||
).map_err(|_| UserError("Invalid attempt to determine storage_key in ext_exists_child_storage"))?;
|
||||
let key = this.memory.get(key_data, key_len as usize).map_err(|_| UserError("Invalid attempt to determine key in ext_exists_child_storage"))?;
|
||||
Ok(if this.ext.exists_child_storage(&storage_key, &key) { 1 } else { 0 })
|
||||
let storage_key = ChildStorageKey::from_vec(storage_key)
|
||||
.ok_or_else(||
|
||||
UserError("ext_exists_child_storage: child storage key is not valid")
|
||||
)?;
|
||||
Ok(if this.ext.exists_child_storage(storage_key, &key) { 1 } else { 0 })
|
||||
},
|
||||
ext_clear_prefix(prefix_data: *const u8, prefix_len: u32) => {
|
||||
let prefix = this.memory.get(prefix_data, prefix_len as usize).map_err(|_| UserError("Invalid attempt to determine prefix in ext_clear_prefix"))?;
|
||||
@@ -226,7 +239,11 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
storage_key_data,
|
||||
storage_key_len as usize
|
||||
).map_err(|_| UserError("Invalid attempt to determine storage_key in ext_kill_child_storage"))?;
|
||||
this.ext.kill_child_storage(&storage_key);
|
||||
let storage_key = ChildStorageKey::from_vec(storage_key)
|
||||
.ok_or_else(||
|
||||
UserError("ext_exists_child_storage: child storage key is not valid")
|
||||
)?;
|
||||
this.ext.kill_child_storage(storage_key);
|
||||
Ok(())
|
||||
},
|
||||
// return 0 and place u32::max_value() into written_out if no value exists for the key.
|
||||
@@ -273,7 +290,14 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
key_data,
|
||||
key_len as usize
|
||||
).map_err(|_| UserError("Invalid attempt to determine key in ext_get_allocated_child_storage"))?;
|
||||
let maybe_value = this.ext.child_storage(&storage_key, &key);
|
||||
|
||||
let maybe_value = {
|
||||
let storage_key = ChildStorageKey::from_slice(&storage_key)
|
||||
.ok_or_else(||
|
||||
UserError("ext_get_allocated_child_storage: child storage key is not valid")
|
||||
)?;
|
||||
this.ext.child_storage(storage_key, &key)
|
||||
};
|
||||
|
||||
debug_trace!(target: "wasm-trace", "*** Getting child storage: {} -> {} == {} [k={}]",
|
||||
::primitives::hexdisplay::ascii_format(&storage_key),
|
||||
@@ -339,7 +363,14 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
key_data,
|
||||
key_len as usize
|
||||
).map_err(|_| UserError("Invalid attempt to get key in ext_get_child_storage_into"))?;
|
||||
let maybe_value = this.ext.child_storage(&storage_key, &key);
|
||||
|
||||
let maybe_value = {
|
||||
let storage_key = ChildStorageKey::from_slice(&*storage_key)
|
||||
.ok_or_else(||
|
||||
UserError("ext_get_child_storage_into: child storage key is not valid")
|
||||
)?;
|
||||
this.ext.child_storage(storage_key, &key)
|
||||
};
|
||||
debug_trace!(target: "wasm-trace", "*** Getting storage: {} -> {} == {} [k={}]",
|
||||
::primitives::hexdisplay::ascii_format(&storage_key),
|
||||
if let Some(_preimage) = this.hash_lookup.get(&key) {
|
||||
@@ -371,18 +402,17 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
},
|
||||
ext_child_storage_root(storage_key_data: *const u8, storage_key_len: u32, written_out: *mut u32) -> *mut u8 => {
|
||||
let storage_key = this.memory.get(storage_key_data, storage_key_len as usize).map_err(|_| UserError("Invalid attempt to determine storage_key in ext_child_storage_root"))?;
|
||||
let r = this.ext.child_storage_root(&storage_key);
|
||||
if let Some(value) = r {
|
||||
let offset = this.heap.allocate(value.len() as u32)? as u32;
|
||||
this.memory.set(offset, &value).map_err(|_| UserError("Invalid attempt to set memory in ext_child_storage_root"))?;
|
||||
this.memory.write_primitive(written_out, value.len() as u32)
|
||||
.map_err(|_| UserError("Invalid attempt to write written_out in ext_child_storage_root"))?;
|
||||
Ok(offset)
|
||||
} else {
|
||||
this.memory.write_primitive(written_out, u32::max_value())
|
||||
.map_err(|_| UserError("Invalid attempt to write failed written_out in ext_child_storage_root"))?;
|
||||
Ok(0)
|
||||
}
|
||||
let storage_key = ChildStorageKey::from_slice(&*storage_key)
|
||||
.ok_or_else(||
|
||||
UserError("ext_child_storage_root: child storage key is not valid")
|
||||
)?;
|
||||
let value = this.ext.child_storage_root(storage_key);
|
||||
|
||||
let offset = this.heap.allocate(value.len() as u32)? as u32;
|
||||
this.memory.set(offset, &value).map_err(|_| UserError("Invalid attempt to set memory in ext_child_storage_root"))?;
|
||||
this.memory.write_primitive(written_out, value.len() as u32)
|
||||
.map_err(|_| UserError("Invalid attempt to write written_out in ext_child_storage_root"))?;
|
||||
Ok(offset)
|
||||
},
|
||||
ext_storage_changes_root(parent_hash_data: *const u8, parent_hash_len: u32, parent_number: u64, result: *mut u8) -> u32 => {
|
||||
let mut parent_hash = H256::default();
|
||||
|
||||
Reference in New Issue
Block a user