-
Notifications
You must be signed in to change notification settings - Fork 799
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
Using metering middleware via c-api #2025
Comments
Hello! That's a good question! We currently do not have a metering API available to the C API. It's certainly a possibility -- the hard part would be designing what that API would look like in a |
It'd be awesome to have this feature in the C API. It's indeed challenging to come up with an elegant design that is compatible with |
Hello @satrobit, It took a little bit of time, but here is the metering C API, https://wasmerio.github.io/wasmer/crates/wasmer_c_api/wasm_c_api/unstable/middlewares/metering/index.html. I'm copy pasting the example for the record: // Define our “cost function”.
uint64_t cost_function(wasmer_parser_operator_t wasm_operator) {
switch(wasm_operator) {
// `local.get` and `i32.const` cost 1 unit.
case LocalGet:
case I32Const:
return 1;
// `i32.add` costs 2 units.
case I32Add:
return 2;
// The other operations are free.
default:
return 0;
}
}
int main() {
// Create a new metering middleware, with our cost function.
wasmer_metering_t* metering = wasmer_metering_new(10, cost_function);
// Consume `metering` to produce a generic `wasmer_middleware_t` value.
wasmer_middleware_t* middleware = wasmer_metering_as_middleware(metering);
// Create a new configuration, and push the middleware in it.
wasm_config_t* config = wasm_config_new();
wasm_config_push_middleware(config, middleware);
// Create the engine and the store based on the configuration.
wasm_engine_t* engine = wasm_engine_new_with_config(config);
wasm_store_t* store = wasm_store_new(engine);
// Create the new WebAssembly module.
wasm_byte_vec_t wat;
wasmer_byte_vec_new_from_string(
&wat,
"(module\n"
" (type $add_t (func (param i32) (result i32)))\n"
" (func $add_two_f (type $add_t) (param $value i32) (result i32)\n"
" local.get $value\n"
" i32.const 1\n"
" i32.add)\n"
" (export \"add_two\" (func $add_two_f)))"
);
wasm_byte_vec_t wasm;
wat2wasm(&wat, &wasm);
wasm_module_t* module = wasm_module_new(store, &wasm);
assert(module);
// Instantiate the module.
wasm_extern_vec_t imports = WASM_EMPTY_VEC;
wasm_trap_t* traps = NULL;
wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps);
assert(instance);
// Here we go. At this step, we will get the `add_two` exported function, and
// call it.
wasm_extern_vec_t exports;
wasm_instance_exports(instance, &exports);
assert(exports.size >= 1);
assert(wasm_extern_kind(exports.data[0]) == WASM_EXTERN_FUNC);
const wasm_func_t* add_two = wasm_extern_as_func(exports.data[0]);
assert(add_two);
wasm_val_t arguments[1] = { WASM_I32_VAL(41) };
wasm_val_t results[1] = { WASM_INIT_VAL };
wasm_val_vec_t arguments_as_array = WASM_ARRAY_VEC(arguments);
wasm_val_vec_t results_as_array = WASM_ARRAY_VEC(results);
// Let's call `add_two` for the first time!
{
wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array);
assert(trap == NULL);
assert(results[0].of.i32 == 42);
// There is 6 points left!
assert(wasmer_metering_get_remaining_points(instance) == 6);
assert(wasmer_metering_points_are_exhausted(instance) == false);
}
// Let's call `add_two` for the second time!
{
wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array);
assert(trap == NULL);
assert(results[0].of.i32 == 42);
// There is 2 points left!
assert(wasmer_metering_get_remaining_points(instance) == 2);
assert(wasmer_metering_points_are_exhausted(instance) == false);
}
// Let's call `add_two` for the third time!
{
wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array);
// Oh, it failed!
assert(trap != NULL);
// There is 0 point left… they are exhausted.
assert(wasmer_metering_points_are_exhausted(instance) == true);
}
wasm_instance_delete(instance);
wasm_module_delete(module);
wasm_store_delete(store);
wasm_engine_delete(engine);
return 0;
} |
Hi! This is awesome. Thank you. |
Summary
I'm trying to add metering to wasm modules using wasmer c-api but I'm not able to find the necessary headers for it. Is it even exposed to the c-api? If it is, can you point me in the right direction?
The text was updated successfully, but these errors were encountered: