forked from filecoin-project/ref-fvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: fix read syscall and sdk method (filecoin-project#584)
* fix: fix read syscall and sdk method 1. Return the correct offset (relative to the end of the logical buffer, not relative to the end of the bytes read). 2. Don't cast "remaining" to a usize in read_block as it can be negative. 3. Add an exhaustive test. Found by @wadealexc. * review: make debug_asserts asserts This costs next to nothing, and is a good safety check.
- Loading branch information
Showing
9 changed files
with
243 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "fil_ipld_actor" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
fvm_ipld_encoding = { version = "0.2.1", path = "../../../../ipld/encoding" } | ||
fvm_sdk = { version = "1.0.0-rc.1", path = "../../../../sdk" } | ||
fvm_shared = { version = "0.7.0", path = "../../../../shared" } | ||
|
||
|
||
[build-dependencies] | ||
wasm-builder = "3.0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
fn main() { | ||
use wasm_builder::WasmBuilder; | ||
WasmBuilder::new() | ||
.with_current_project() | ||
.import_memory() | ||
.append_to_rust_flags("-Ctarget-feature=+crt-static") | ||
.append_to_rust_flags("-Cpanic=abort") | ||
.append_to_rust_flags("-Coverflow-checks=true") | ||
.append_to_rust_flags("-Clto=true") | ||
.append_to_rust_flags("-Copt-level=z") | ||
.build() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
nightly |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
use fvm_ipld_encoding::{to_vec, BytesSer, DAG_CBOR}; | ||
use fvm_sdk as sdk; | ||
use fvm_shared::error::ExitCode; | ||
|
||
#[no_mangle] | ||
pub fn invoke(_: u32) -> u32 { | ||
std::panic::set_hook(Box::new(|info| { | ||
sdk::vm::abort( | ||
ExitCode::USR_ASSERTION_FAILED.value(), | ||
Some(&format!("{}", info)), | ||
) | ||
})); | ||
|
||
test_read_block(); | ||
0 | ||
} | ||
|
||
fn test_read_block() { | ||
let test_bytes: Vec<u8> = to_vec(&BytesSer( | ||
&(0..(10 << 10)) | ||
.map(|b| (b % 256) as u8) | ||
.collect::<Vec<u8>>(), | ||
)) | ||
.unwrap(); | ||
let k = sdk::ipld::put(0xb220, 32, DAG_CBOR, &test_bytes).unwrap(); | ||
{ | ||
let block = sdk::ipld::get(&k).unwrap(); | ||
assert_eq!(test_bytes, block); | ||
} | ||
|
||
unsafe { | ||
// Open it. | ||
let k_bytes = k.to_bytes(); | ||
let sdk::sys::ipld::IpldOpen { codec, id, size } = | ||
sdk::sys::ipld::block_open(k_bytes.as_ptr()).unwrap(); | ||
|
||
assert_eq!(test_bytes.len() as u32, size, "block has an incorrect size"); | ||
assert_eq!(codec, DAG_CBOR, "block has an incorrect codec"); | ||
|
||
let mut buf = vec![0u8; 2 * test_bytes.len()]; | ||
|
||
// Try reading with too much space. | ||
{ | ||
let remaining = | ||
sdk::sys::ipld::block_read(id, 0, buf.as_mut_ptr(), buf.len() as u32).unwrap(); | ||
assert_eq!( | ||
test_bytes.len() as i32, | ||
-remaining, | ||
"should have over-allocated by 2x" | ||
); | ||
assert_eq!( | ||
test_bytes, | ||
buf[..test_bytes.len()], | ||
"should have read entire block" | ||
); | ||
} | ||
|
||
buf.fill(0); | ||
|
||
// Try reading a slice | ||
{ | ||
let remaining = sdk::sys::ipld::block_read(id, 10, buf.as_mut_ptr(), 10).unwrap(); | ||
assert_eq!( | ||
remaining, | ||
(test_bytes.len() - (2 * 10)) as i32, | ||
"should have all but 20 bytes remaining" | ||
); | ||
|
||
assert_eq!( | ||
&test_bytes[10..20], | ||
&buf[..10], | ||
"should have read the second 10 bytes" | ||
); | ||
} | ||
|
||
// Try reading past the end. | ||
{ | ||
let remaining = | ||
sdk::sys::ipld::block_read(id, test_bytes.len() as u32 + 10, buf.as_mut_ptr(), 10) | ||
.unwrap(); | ||
assert_eq!( | ||
remaining, -20, | ||
"reading past the end of the block should work" | ||
); | ||
} | ||
|
||
// Test get_block with no hint | ||
assert_eq!( | ||
test_bytes, | ||
sdk::ipld::get_block(id, None).unwrap(), | ||
"can read with no hint" | ||
); | ||
|
||
// Test get_block with a small hint | ||
assert_eq!( | ||
test_bytes, | ||
sdk::ipld::get_block(id, Some(10)).unwrap(), | ||
"can read with a small hint" | ||
); | ||
|
||
// Test get_block with an exact hint | ||
assert_eq!( | ||
test_bytes, | ||
sdk::ipld::get_block(id, Some(test_bytes.len() as u32)).unwrap(), | ||
"can read with the correct size" | ||
); | ||
|
||
// Test get_block with an oversized hint. | ||
assert_eq!( | ||
test_bytes, | ||
sdk::ipld::get_block(id, Some(test_bytes.len() as u32 + 10)).unwrap(), | ||
"can read with an over-estimated size" | ||
); | ||
|
||
// Test an offset that overflows an i32: | ||
sdk::sys::ipld::block_read(id, (i32::MAX as u32) + 1, buf.as_mut_ptr(), 0) | ||
.expect_err("expected it to fail"); | ||
|
||
// Test a length that overflows an i32 | ||
sdk::sys::ipld::block_read(id, 0, buf.as_mut_ptr(), (i32::MAX as u32) + 1) | ||
.expect_err("expected it to fail"); | ||
|
||
// Test a combined length + offset that overflow an i32 | ||
sdk::sys::ipld::block_read(id, (i32::MAX as u32) - 10, buf.as_mut_ptr(), 20) | ||
.expect_err("expected it to fail"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters