-
Notifications
You must be signed in to change notification settings - Fork 2
add metering for bulk memory opcodes #79
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
base: rc/after-supernova
Are you sure you want to change the base?
Changes from all commits
d433c59
ad1c798
b82a9a6
642fa74
265657f
00162a7
876a457
d434536
6aa525e
d655288
e0fbc4e
3b1185f
ed0ff7d
61697d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,7 @@ use crate::capi_instance::{CapiInstance, vm_exec_instance_t}; | |
| use crate::service_singleton::with_service; | ||
| use crate::vm_exec_result_t; | ||
| use meta::capi_safe_unwind; | ||
| use multiversx_chain_vm_executor::OpcodeCost; | ||
| use multiversx_chain_vm_executor::{OpcodeConfig, OpcodeCost, OpcodeVersion}; | ||
|
|
||
| #[allow(non_camel_case_types)] | ||
| #[repr(C)] | ||
|
|
@@ -21,14 +21,30 @@ pub struct vm_exec_opcode_cost_t; | |
| #[allow(clippy::cast_ptr_alignment)] | ||
| #[unsafe(no_mangle)] | ||
| #[capi_safe_unwind(vm_exec_result_t::VM_EXEC_ERROR)] | ||
| pub unsafe extern "C" fn vm_exec_set_opcode_costs( | ||
| pub unsafe extern "C" fn vm_exec_set_opcode_config( | ||
| executor_ptr: *mut vm_exec_executor_t, | ||
| opcode_vesion_code: i32, | ||
|
||
| opcode_cost_ptr: *const vm_exec_opcode_cost_t, | ||
| ) -> vm_exec_result_t { | ||
| let capi_executor = cast_input_ptr!(executor_ptr, CapiExecutor, "executor ptr is null"); | ||
| let opcode_costs: &OpcodeCost = unsafe { &*(opcode_cost_ptr as *const OpcodeCost) }; | ||
|
|
||
| let result = capi_executor.content.set_opcode_cost(opcode_costs); | ||
| let Some(opcode_version) = OpcodeVersion::from_i32(opcode_vesion_code) else { | ||
| with_service(|service| { | ||
| service.update_last_error_str(format!( | ||
| "invalid opcode version code: {}", | ||
| opcode_vesion_code | ||
|
||
| )) | ||
| }); | ||
| return vm_exec_result_t::VM_EXEC_ERROR; | ||
| }; | ||
|
|
||
| let opcode_costs_ref: &OpcodeCost = unsafe { &*(opcode_cost_ptr as *const OpcodeCost) }; | ||
| let opcode_config = OpcodeConfig { | ||
| opcode_version, | ||
| opcode_cost: opcode_costs_ref.clone(), | ||
| }; | ||
|
|
||
| let result = capi_executor.content.set_opcode_config(opcode_config); | ||
| match result { | ||
| Ok(()) => vm_exec_result_t::VM_EXEC_OK, | ||
| Err(message) => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,15 @@ | ||
| mod we_breakpoints; | ||
| mod we_metering; | ||
| mod we_metering_helpers; | ||
| mod we_opcode_control; | ||
| mod we_opcode_cost; | ||
| mod we_opcode_trace; | ||
| mod we_protected_globals; | ||
| mod we_protected_globals_trait; | ||
|
|
||
| pub(crate) use we_breakpoints::*; | ||
| pub(crate) use we_metering::*; | ||
| pub use we_metering_helpers::*; | ||
| pub use we_opcode_control::OpcodeControl; | ||
| pub use we_opcode_cost::*; | ||
| pub use we_opcode_trace::OpcodeTracer; | ||
| pub use we_protected_globals::ProtectedGlobals; | ||
| pub use we_protected_globals_trait::MiddlewareWithProtectedGlobals; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,13 +1,12 @@ | ||||||||||||||||
| #![allow(unused)] // TODO: until we activate the local count mechanism | ||||||||||||||||
|
|
||||||||||||||||
| use super::{ | ||||||||||||||||
| BREAKPOINT_VALUE_OUT_OF_GAS, Breakpoints, MiddlewareWithProtectedGlobals, get_local_cost, | ||||||||||||||||
| get_opcode_cost, | ||||||||||||||||
| BREAKPOINT_VALUE_OUT_OF_GAS, Breakpoints, MiddlewareWithProtectedGlobals, get_opcode_cost, | ||||||||||||||||
| }; | ||||||||||||||||
| use crate::we_helpers::{ | ||||||||||||||||
| create_global_index, get_global_value_u64, is_control_flow_operator, set_global_value_u64, | ||||||||||||||||
| }; | ||||||||||||||||
| use multiversx_chain_vm_executor::{ExecutorError, OpcodeCost}; | ||||||||||||||||
| use multiversx_chain_vm_executor::{ExecutorError, OpcodeConfig, OpcodeCost}; | ||||||||||||||||
| use std::mem; | ||||||||||||||||
| use std::sync::{Arc, Mutex}; | ||||||||||||||||
| use wasmer::sys::{FunctionMiddleware, MiddlewareReaderState, ModuleMiddleware}; | ||||||||||||||||
|
|
@@ -29,20 +28,20 @@ struct MeteringGlobalIndexes { | |||||||||||||||
| #[derive(Debug)] | ||||||||||||||||
| pub(crate) struct Metering { | ||||||||||||||||
| unmetered_locals: usize, | ||||||||||||||||
| opcode_cost: Arc<OpcodeCost>, | ||||||||||||||||
| opcode_config: Arc<OpcodeConfig>, | ||||||||||||||||
| breakpoints_middleware: Arc<Breakpoints>, | ||||||||||||||||
| global_indexes: Mutex<Option<MeteringGlobalIndexes>>, | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| impl Metering { | ||||||||||||||||
| pub(crate) fn new( | ||||||||||||||||
| unmetered_locals: usize, | ||||||||||||||||
| opcode_cost: Arc<OpcodeCost>, | ||||||||||||||||
| opcode_config: Arc<OpcodeConfig>, | ||||||||||||||||
| breakpoints_middleware: Arc<Breakpoints>, | ||||||||||||||||
| ) -> Self { | ||||||||||||||||
| Self { | ||||||||||||||||
| unmetered_locals, | ||||||||||||||||
| opcode_cost, | ||||||||||||||||
| opcode_config, | ||||||||||||||||
| breakpoints_middleware, | ||||||||||||||||
| global_indexes: Mutex::new(None), | ||||||||||||||||
| } | ||||||||||||||||
|
|
@@ -78,7 +77,7 @@ impl ModuleMiddleware for Metering { | |||||||||||||||
| Box::new(FunctionMetering { | ||||||||||||||||
| accumulated_cost: Default::default(), | ||||||||||||||||
| unmetered_locals: self.unmetered_locals, | ||||||||||||||||
| opcode_cost: self.opcode_cost.clone(), | ||||||||||||||||
| opcode_config: self.opcode_config.clone(), | ||||||||||||||||
| breakpoints_middleware: self.breakpoints_middleware.clone(), | ||||||||||||||||
| global_indexes: self.global_indexes.lock().unwrap().clone().unwrap(), | ||||||||||||||||
| }) | ||||||||||||||||
|
|
@@ -104,7 +103,7 @@ impl ModuleMiddleware for Metering { | |||||||||||||||
| struct FunctionMetering { | ||||||||||||||||
| accumulated_cost: u64, | ||||||||||||||||
| unmetered_locals: usize, | ||||||||||||||||
| opcode_cost: Arc<OpcodeCost>, | ||||||||||||||||
| opcode_config: Arc<OpcodeConfig>, | ||||||||||||||||
| breakpoints_middleware: Arc<Breakpoints>, | ||||||||||||||||
| global_indexes: MeteringGlobalIndexes, | ||||||||||||||||
| } | ||||||||||||||||
|
|
@@ -149,7 +148,7 @@ impl FunctionMiddleware for FunctionMetering { | |||||||||||||||
| // Get the cost of the current operator, and add it to the accumulator. | ||||||||||||||||
| // This needs to be done before the metering logic, to prevent operators like `Call` from escaping metering in some | ||||||||||||||||
| // corner cases. | ||||||||||||||||
| let option = get_opcode_cost(&operator, &self.opcode_cost); | ||||||||||||||||
| let option = get_opcode_cost(&operator, &self.opcode_config); | ||||||||||||||||
|
||||||||||||||||
| let option = get_opcode_cost(&operator, &self.opcode_config); | |
| let option = match &operator { | |
| // Explicit support for bulk memory operations to keep metering consistent | |
| Operator::MemoryCopy { .. } => Some(self.opcode_config.opcode_memorycopy), | |
| Operator::MemoryFill { .. } => Some(self.opcode_config.opcode_memoryfill), | |
| _ => get_opcode_cost(&operator, &self.opcode_config), | |
| }; |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter name has a typo: 'opcode_vesion_code' should be 'opcode_version_code'. This typo also affects the C header file.