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

More control over fuel consumption #5109

Open
coolreader18 opened this issue Oct 24, 2022 · 4 comments · Fixed by #7240
Open

More control over fuel consumption #5109

coolreader18 opened this issue Oct 24, 2022 · 4 comments · Fixed by #7240

Comments

@coolreader18
Copy link
Contributor

coolreader18 commented Oct 24, 2022

Feature

A set of new APIs that provide more control over fuel consumption:

impl Config {
    fn fuel_cost(&mut self, f: impl Fn(WasmOpcode) -> u64 + Send + Sync + 'static) -> &mut Self;
}
enum WasmOpcode {
    Unreachable,
    Nop,
    Block,
    Loop,
    // ...
}
impl Store {
    fn fuel_remaining(&self) -> Option<u64>;
    /// Returns an error if the store is not configured for fuel consumption
    fn set_fuel(&mut self, value: u64) -> Result<()>;
}
#[non_exhaustive]
struct OutOfFuelError;

Benefit

Allows more direct control over fuel consumption and filling, letting users set custom fuel costs for each operand if they deem some to be more costly/intensive in their environment, as well letting them set precisely how much fuel they might allow a single function call or set of function calls. OutOfFuelError being made public allows users to check when a Trap was caused by fuel running out.

Implementation

I have an implementation for the custom fuel cost configuration, and the methods on Store should be fairly trivial.

Alternatives

fuel_remaining and set_fuel can be approximated by consume_fuel(0) and if new_fuel > fuel_remaining() { add_fuel(delta) } else { consume_fuel(delta) } respectively. fuel_cost cannot be emulated, so the alternative is to just accept wasmtime's default cost function. As an alternative in designing the API, the fuel_cost closure could take a &wasmparser::Operator<'_> as it did in the original version of this issue. However, that would require exposing wasmparser in wasmtime's public api, which is undesirable.

@coolreader18
Copy link
Contributor Author

Oh, looks like wasmtime-fuzzing has a shim for set_fuel the same as I described:

https://github.com/bytecodealliance/wasmtime/blob/main/crates/fuzzing/src/oracles.rs#L790-L802

@howjmay
Copy link
Contributor

howjmay commented Feb 8, 2023

Hi I am curious why #5220 can help us set customized fuel for each opcode?

rockwotj added a commit to rockwotj/wasmtime that referenced this issue Oct 13, 2023
Fixes: bytecodealliance#5109

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
github-merge-queue bot pushed a commit that referenced this issue Oct 16, 2023
* Support set_fuel in store APIs

Fixes: #5109

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>

* rename set_fuel to reset_fuel

To make it more clear that consumed fuel is being reset.

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>

* update out of date documentation for fuel in C API

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>

---------

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
@RReverser
Copy link
Contributor

Looks like #7240 only adds reset_fuel, I don't think it should've auto-closed this issue?

In particular,

fn fuel_cost(&mut self, f: impl Fn(WasmOpcode) -> u64 + Send + Sync + 'static) -> &mut Self;

this would be still desirable.

@alexcrichton alexcrichton reopened this Oct 16, 2023
@rockwotj
Copy link
Contributor

Apologies for this getting closed. I was picking up #5220 which also would have closed this issue. Maybe @coolreader18 could update this issue to have it be more about a custom cost function for fuel APIs?

Also if you have opinions on store fuel related APIs would love to hear there here #7255

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants