Skip to content

Commit 4c67ecd

Browse files
pepyakinen
authored andcommitted
read_storage panics (paritytech#3589)
* Add a failing test case * Actual fix * read_child_storage, fix wasm side * Bump the impl version. * Alternative (paritytech#3597) * Update with_std.rs * Update with_std.rs * Update wasm_executor.rs * Update wasm_executor.rs * Update with_std.rs * Update wasm_executor.rs
1 parent 0d1d8bf commit 4c67ecd

File tree

4 files changed

+79
-14
lines changed

4 files changed

+79
-14
lines changed

core/executor/src/wasm_executor.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -629,9 +629,9 @@ impl_wasm_host_interface! {
629629
)?;
630630

631631
if let Some(value) = maybe_value {
632-
let value = &value[value_offset as usize..];
633-
let written = std::cmp::min(value_len as usize, value.len());
634-
context.write_memory(value_data, &value[..written])
632+
let data = &value[value.len().min(value_offset as usize)..];
633+
let written = std::cmp::min(value_len as usize, data.len());
634+
context.write_memory(value_data, &data[..written])
635635
.map_err(|_| "Invalid attempt to set value in ext_get_storage_into")?;
636636
Ok(value.len() as u32)
637637
} else {
@@ -658,10 +658,10 @@ impl_wasm_host_interface! {
658658
)?;
659659

660660
if let Some(value) = maybe_value {
661-
let value = &value[value_offset as usize..];
662-
let written = std::cmp::min(value_len as usize, value.len());
663-
context.write_memory(value_data, &value[..written])
664-
.map_err(|_| "Invalid attempt to set value in ext_get_child_storage_into")?;
661+
let data = &value[value.len().min(value_offset as usize)..];
662+
let written = std::cmp::min(value_len as usize, data.len());
663+
context.write_memory(value_data, &data[..written])
664+
.map_err(|_| "Invalid attempt to get value in ext_get_child_storage_into")?;
665665
Ok(value.len() as u32)
666666
} else {
667667
Ok(u32::max_value())

core/sr-io/with_std.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ impl StorageApi for () {
5454

5555
fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option<usize> {
5656
ext::with(|ext| ext.storage(key).map(|value| {
57-
let value = &value[value_offset..];
58-
let written = std::cmp::min(value.len(), value_out.len());
59-
value_out[..written].copy_from_slice(&value[..written]);
57+
let data = &value[value_offset.min(value.len())..];
58+
let written = std::cmp::min(data.len(), value_out.len());
59+
value_out[..written].copy_from_slice(&data[..written]);
6060
value.len()
6161
})).expect("read_storage cannot be called outside of an Externalities-provided environment.")
6262
}
@@ -85,9 +85,9 @@ impl StorageApi for () {
8585
let storage_key = child_storage_key_or_panic(storage_key);
8686
ext.child_storage(storage_key, key)
8787
.map(|value| {
88-
let value = &value[value_offset..];
89-
let written = std::cmp::min(value.len(), value_out.len());
90-
value_out[..written].copy_from_slice(&value[..written]);
88+
let data = &value[value_offset.min(value.len())..];
89+
let written = std::cmp::min(data.len(), value_out.len());
90+
value_out[..written].copy_from_slice(&data[..written]);
9191
value.len()
9292
})
9393
})

core/test-runtime/src/lib.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ cfg_if! {
280280
///
281281
/// Returns the signature generated for the message `sr25519`.
282282
fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic);
283+
/// Run various tests against storage.
284+
fn test_storage();
283285
}
284286
}
285287
} else {
@@ -322,6 +324,8 @@ cfg_if! {
322324
///
323325
/// Returns the signature generated for the message `sr25519`.
324326
fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic);
327+
/// Run various tests against storage.
328+
fn test_storage();
325329
}
326330
}
327331
}
@@ -590,6 +594,11 @@ cfg_if! {
590594
fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) {
591595
test_sr25519_crypto()
592596
}
597+
598+
fn test_storage() {
599+
test_read_storage();
600+
test_read_child_storage();
601+
}
593602
}
594603

595604
impl aura_primitives::AuraApi<Block, AuraId> for Runtime {
@@ -805,6 +814,11 @@ cfg_if! {
805814
fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) {
806815
test_sr25519_crypto()
807816
}
817+
818+
fn test_storage() {
819+
test_read_storage();
820+
test_read_child_storage();
821+
}
808822
}
809823

810824
impl aura_primitives::AuraApi<Block, AuraId> for Runtime {
@@ -887,6 +901,46 @@ fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) {
887901
(signature, public0)
888902
}
889903

904+
fn test_read_storage() {
905+
const KEY: &[u8] = b":read_storage";
906+
runtime_io::set_storage(KEY, b"test");
907+
908+
let mut v = [0u8; 4];
909+
let r = runtime_io::read_storage(
910+
KEY,
911+
&mut v,
912+
0
913+
);
914+
assert_eq!(r, Some(4));
915+
assert_eq!(&v, b"test");
916+
917+
let mut v = [0u8; 4];
918+
let r = runtime_io::read_storage(KEY, &mut v, 8);
919+
assert_eq!(r, Some(4));
920+
assert_eq!(&v, &[0, 0, 0, 0]);
921+
}
922+
923+
fn test_read_child_storage() {
924+
const CHILD_KEY: &[u8] = b":child_storage:default:read_child_storage";
925+
const KEY: &[u8] = b":read_child_storage";
926+
runtime_io::set_child_storage(CHILD_KEY, KEY, b"test");
927+
928+
let mut v = [0u8; 4];
929+
let r = runtime_io::read_child_storage(
930+
CHILD_KEY,
931+
KEY,
932+
&mut v,
933+
0
934+
);
935+
assert_eq!(r, Some(4));
936+
assert_eq!(&v, b"test");
937+
938+
let mut v = [0u8; 4];
939+
let r = runtime_io::read_child_storage(CHILD_KEY, KEY, &mut v, 8);
940+
assert_eq!(r, Some(4));
941+
assert_eq!(&v, &[0, 0, 0, 0]);
942+
}
943+
890944
#[cfg(test)]
891945
mod tests {
892946
use substrate_test_runtime_client::{
@@ -981,4 +1035,15 @@ mod tests {
9811035
let ret = runtime_api.vec_with_capacity(&new_block_id, 1048576);
9821036
assert!(ret.is_ok());
9831037
}
1038+
1039+
#[test]
1040+
fn test_storage() {
1041+
let client = TestClientBuilder::new()
1042+
.set_execution_strategy(ExecutionStrategy::Both)
1043+
.build();
1044+
let runtime_api = client.runtime_api();
1045+
let block_id = BlockId::Number(client.info().chain.best_number);
1046+
1047+
runtime_api.test_storage(&block_id).unwrap();
1048+
}
9841049
}

node/runtime/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
8383
// implementation changes and behavior does not, then leave spec_version as
8484
// is and increment impl_version.
8585
spec_version: 156,
86-
impl_version: 156,
86+
impl_version: 157,
8787
apis: RUNTIME_API_VERSIONS,
8888
};
8989

0 commit comments

Comments
 (0)