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

Make gas limit immutable in cosmwasm_vm::instance::Instance #136

Merged
merged 3 commits into from
Feb 1, 2020

Conversation

webmaster128
Copy link
Member

During review, I found it hard to follow test code that included instance.set_gas calls. This seems to be an unnatural use of an instance. I could easily rewrite the tests in a way that set the gas limit once and calculate diffs using get_gas.

However, this PR does not work well together with the LRU cache. In

        // pop from lru cache if present
        if let Some(cache) = &mut self.instances {
            let val = cache.pop(&hash);
            if let Some(inst) = val {
                inst.leave_storage(Some(deps.storage));
                return Ok(inst);
            }
        }

it is not possible to reset the gas limit due API I want to remove.

I wonder if you have a good design around this. Re-using an "instance" seems to be counter-intuitive. I was thinking about caching raw wasmer_runtime_core::Instances. 👍/👎/thoughts?

@webmaster128 webmaster128 added the WIP work in progress label Jan 28, 2020
@ethanfrey
Copy link
Member

ethanfrey commented Jan 28, 2020

The whole set_gas stuff is a bit of a mess, as there is no way to change the gas limit (which is what I want), so we need to compile it with a huge one, then use up a bunch of gas before calling.

There is an open PR to make this much more intuitive (just set_limit) wasmerio/wasmer#996 but it seems to be hanging without merge for 2 months. I can ask about it.

As to reusing instances, I did this for performance. But actually disable the LRU by default now in wasmd for concerns on stability. I would like to go through with this most recent version and try to benchmark all the steps and see what savings we get from caching instances, rather than just caching the precompile (until wasmer 0.12, singlepass precompiles could not be persisted/cached, making this more important).

We could also cache raw wasmer::Instance. That does make sense. Just the raw vm. However, I would like to wait a bit before changing this code and tackle it when there are a few issues to do at once and then give a deeper inspection and refactoring. (The set_limit is just one issue... I don't like how I handle Storage, but I see no other way)

@webmaster128
Copy link
Member Author

The whole set_gas stuff is a bit of a mess

The good thing is that the mess is nicely encapsulated in backends::set_gas, which works as expected and can remain untauched here.

We could also cache raw wasmer::Instance. That does make sense. Just the raw vm. However, I would like to wait a bit before changing this code and tackle it when there are a few issues to do at once and then give a deeper inspection and refactoring.

Created an issue for that: #137

Copy link
Member

@ethanfrey ethanfrey left a comment

Choose a reason for hiding this comment

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

In general, the approach makes sense, but I think we need the other issue to make this work (wasmer::Instance in cache). Note the gas limit is set incorrectly after reading from cache

lib/vm/src/cache.rs Outdated Show resolved Hide resolved
id: &[u8],
deps: Extern<S, A>,
gas_limit: u64,
) -> Result<Instance<S, A>, Error> {
let hash = WasmHash::generate(&id);

// pop from lru cache if present
Copy link
Member

Choose a reason for hiding this comment

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

The issue with this PR, is that if I pull an Instance off the lru cache, it will have the same gas limit as the first time.

Try this, by running some code (with lru), get_instance the first time with a too low gas, and it fails. Then put it back on cache. Then try get_instance with more than enough gas. I believe it will fail again as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

I am working on a dedicated test for the recovering after out of gas now.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done in 201829c

@ethanfrey
Copy link
Member

I guess this is unblocked by #140

Let me know if you finish it up / reimplememt

@webmaster128
Copy link
Member Author

This is ready from my side

@webmaster128 webmaster128 changed the title Idea: Make gas limit immutable in cosmwasm_vm::instance::Instance Make gas limit immutable in cosmwasm_vm::instance::Instance Jan 31, 2020
Copy link
Member

@ethanfrey ethanfrey left a comment

Choose a reason for hiding this comment

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

Lgtm

@@ -40,5 +40,10 @@ pub fn set_gas(instance: &mut Instance, limit: u64) {

pub fn get_gas(instance: &Instance) -> u64 {
let used = metering::get_points_used(instance);
GAS_LIMIT - used
// when running out of gas, get_points_used can exceed GAS_LIMIT
if used < GAS_LIMIT {
Copy link
Member

Choose a reason for hiding this comment

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

Safer for sure

Copy link
Member Author

Choose a reason for hiding this comment

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

Without that, I got overflow crashes

Copy link
Member

Choose a reason for hiding this comment

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

I did also months ago with huge values, but then just used smaller numbers and forgot about it. Good fix

deps: Extern<S, A>,
gas_limit: u64,
) -> Self {
set_gas(&mut wasmer_instance, gas_limit);
let res = Instance {
Copy link
Member

Choose a reason for hiding this comment

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

Yes. Looks proper

@webmaster128 webmaster128 merged commit f5ff5a3 into 0.7 Feb 1, 2020
@webmaster128 webmaster128 deleted the remove_set_gas branch February 1, 2020 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants