Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep track of pointers and their length with a custom store #857

Merged
merged 15 commits into from
Apr 25, 2024

Conversation

iFrostizz
Copy link
Contributor

@iFrostizz iFrostizz commented Apr 24, 2024

Closes #846, closes #845

Changelog

  • Adding a new custom store that keeps track of the pointer offset and the length of the data that is at this location in the memory.
  • This lets us remove any occurence of the HostPtr type
  • Removing of any use of the SmartPtr on the Go side
  • Writing some tests for the memory module

Copy link
Contributor

@richardpringle richardpringle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall code looks great!

Take a look at my comments. I suggest a few minor changes as well as some additional tests.

x/programs/cmd/simulator/cmd/root.go Outdated Show resolved Hide resolved
x/programs/cmd/simulator/vm/actions/program_execute.go Outdated Show resolved Hide resolved
x/programs/examples/utils.go Outdated Show resolved Hide resolved
x/programs/program/function.go Outdated Show resolved Hide resolved
x/programs/program/memory.go Show resolved Hide resolved
x/programs/rust/wasmlanche-sdk/src/memory.rs Outdated Show resolved Hide resolved
x/programs/rust/wasmlanche-sdk/src/memory.rs Show resolved Hide resolved
let val = into_bytes(ptr as i64).unwrap();
assert_ne!(val, vec);
assert!(GLOBAL_STORE.with_borrow(|s| s.get(&(ptr as *const u8)).is_none()));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 this isn't really testing anything that we're doing. In other words, I'm not sure that there's any code outside of this test that you could change to only make this test fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured that this test was probably much more straightforward than writing a broken allocator to do that but that wouldn't be that useful anyway, so I will just delete this test

x/programs/rust/wasmlanche-sdk/src/memory.rs Show resolved Hide resolved
fn big_allocation_fails() {
// see https://doc.rust-lang.org/1.77.2/std/alloc/struct.Layout.html#method.array
alloc(isize::MAX as usize + 1);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're testing over the boundary here, what about on the boundary? (This test is good, I think you need another one).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when you allocate more than half the space twice? Should probably test this as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely a good idea! Adding this one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue, the allocation does fail but still abort. It's really great that you found that the null pointer is returned when the allocation failed though !

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Maybe we save the tests that abort for an integration test.

@iFrostizz
Copy link
Contributor Author

There is an irrefutable pattern here

if err != nil {
i.log.Error("failed to convert program id to id",
zap.Error(err),
)
return nil, err
}

Please thank golsp !
image

@iFrostizz
Copy link
Contributor Author

SmartPtr (go) and HostPtr (rust) are still here and will be removed in a follow-up PR, the aim here is to do the bare minimum without breaking stuffs between commits

fn into_bytes(ptr: HostPtr) -> Option<Vec<u8>> {
GLOBAL_STORE
.with_borrow_mut(|s| s.remove(&(ptr as *const u8)))
.map(|len| unsafe { std::vec::Vec::from_raw_parts(ptr as *mut u8, len, len) })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In your next PR, can you also make sure to leave a // Safety: comment on all the unsafe blocks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do!

Copy link
Contributor

@richardpringle richardpringle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

There's some follow-up work to do here, though. I think we need some more integration tests to see what happens when an abort is called in wasmtime.

@richardpringle richardpringle merged commit b7f3391 into ava-labs:main Apr 25, 2024
34 checks passed
@iFrostizz iFrostizz self-assigned this Apr 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[x/programs] Test memory module in wasmlanche-sdk. into_bytes is unsafe
2 participants