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

refactor(ethexe): remove to_vec and mem::transmute from ethexe #4419

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions ethexe/processor/src/host/api/lazy_pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,27 @@ fn pre_process_memory_accesses(

let memory = MemoryWrap(caller.data().memory());

let reads = memory.slice_by_val(&caller, reads).to_vec();
let reads = memory.slice_by_val(&caller, reads);

let writes = memory.slice_by_val(&caller, writes).to_vec();
let writes = memory.slice_by_val(&caller, writes);

// 8 len bytes of u64 counter.
// TODO: why gas_bytes is &mut [u8; 8] and not &mut u64 (?).
let gas_bytes = memory
// read gas_bytes into `mut` variable because `pre_process_memory_accesses` updates
// it, then write updated slice to memory. Can't use `slice_mut` here without using `.to_vec()`
// on `writes` and `reads`.
let mut gas_counter: u64 = u64::from_le_bytes(
memory
.slice(&caller, gas_bytes as usize, 8)
.try_into()
.unwrap(),
);

let res =
lazy_pages_detail::pre_process_memory_accesses(reads, writes, &mut gas_counter) as i32;

memory
.slice_mut(&mut caller, gas_bytes as usize, 8)
.try_into()
.unwrap();

let res = lazy_pages_detail::pre_process_memory_accesses(&reads, &writes, gas_bytes) as i32;

.copy_from_slice(&gas_counter.to_le_bytes());
log::trace!(target: "host_call", "pre_process_memory_accesses(..) -> {res:?}");

res
Expand Down
6 changes: 3 additions & 3 deletions ethexe/processor/src/host/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use super::context::HostContext;
use ethexe_runtime_common::{pack_u32_to_i64, unpack_i64_to_u32};
use parity_scale_codec::{Decode, Encode};
use sp_wasm_interface::{FunctionContext as _, IntoValue as _, StoreData};
use std::mem;
use wasmtime::{Caller, Memory, StoreContext, StoreContextMut};

pub mod allocator;
Expand Down Expand Up @@ -58,7 +58,7 @@ impl MemoryWrap {
store: impl Into<StoreContext<'a, T>>,
ptr_len: i64,
) -> &'a [u8] {
let [ptr, len]: [i32; 2] = unsafe { mem::transmute(ptr_len) };
let (ptr, len) = unpack_i64_to_u32(ptr_len);

self.slice(store, ptr as usize, len as usize)
}
Expand Down Expand Up @@ -119,7 +119,7 @@ pub fn allocate_and_write_raw(

memory.write(&mut caller, ptr as usize, data).unwrap();

let res = unsafe { mem::transmute::<[i32; 2], i64>([ptr, len as i32]) };
let res = pack_u32_to_i64(ptr as u32, len as u32);

(caller, res)
}
6 changes: 3 additions & 3 deletions ethexe/processor/src/host/api/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

use crate::host::{api::MemoryWrap, context::HostContext};
use anyhow::Result;
use core::mem;
use ethexe_runtime_common::pack_u32_to_i64;
use gear_runtime_interface::{sandbox_detail, Instantiate};
use parity_scale_codec::Encode;
use sp_wasm_interface::{FunctionContext as _, IntoValue as _, Pointer, StoreData};
Expand Down Expand Up @@ -87,7 +87,7 @@ fn get_global_val(caller: Caller<'_, StoreData>, instance_idx: i32, name: i64) -

let res = sandbox_detail::get_global_val(&mut host_context, instance_idx as u32, name);
let res = res.encode();
let res_len = res.len() as i32;
let res_len = res.len() as u32;

let ptr = host_context
.allocate_memory(res_len as u32)
Expand All @@ -102,7 +102,7 @@ fn get_global_val(caller: Caller<'_, StoreData>, instance_idx: i32, name: i64) -

memory.write(&mut caller, ptr as usize, &res).unwrap();

let res = unsafe { mem::transmute::<[i32; 2], i64>([ptr, res_len]) };
let res = pack_u32_to_i64(ptr as u32, res_len);

log::trace!(target: "host_call", "get_global_val(..) -> {res:?}");

Expand Down
8 changes: 4 additions & 4 deletions ethexe/processor/src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::Database;
use anyhow::{anyhow, Result};
use core_processor::common::JournalNote;
use ethexe_runtime_common::unpack_i64_to_u32;
use gear_core::{code::InstrumentedCode, ids::ProgramId};
use gprimitives::{CodeId, H256};
use parity_scale_codec::{Decode, Encode};
use sp_allocator::{AllocationStats, FreeingBumpHeapAllocator};
use sp_wasm_interface::{HostState, IntoValue, MemoryWrapper, StoreData};
use std::{mem, sync::Arc};

use crate::Database;
use std::sync::Arc;

pub mod api;
pub mod runtime;
Expand Down Expand Up @@ -200,7 +200,7 @@ impl InstanceWrapper {
}

fn get_call_output<D: Decode>(&mut self, ptr_len: i64) -> Result<D> {
let [ptr, len]: [i32; 2] = unsafe { mem::transmute(ptr_len) };
let (ptr, len) = unpack_i64_to_u32(ptr_len);

// TODO: check range.
let memory = self.memory()?;
Expand Down
14 changes: 14 additions & 0 deletions ethexe/runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,17 @@ where
core_processor::process::<Ext<RI::LazyPages>>(&block_config, execution_context, random_data)
.unwrap_or_else(|err| unreachable!("{err}"))
}

pub const fn pack_u32_to_i64(low: u32, high: u32) -> i64 {
let mut result = 0u64;
result |= (high as u64) << 32;
result |= low as u64;
result as i64
}

pub const fn unpack_i64_to_u32(val: i64) -> (u32, u32) {
let val = val as u64;
let high = (val >> 32) as u32;
let low = val as u32;
(low, high)
}
3 changes: 2 additions & 1 deletion ethexe/runtime/src/wasm/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use alloc::{boxed::Box, vec::Vec};
use ethexe_runtime_common::pack_u32_to_i64;
use parity_scale_codec::{Decode, Encode};

mod instrument;
Expand Down Expand Up @@ -74,5 +75,5 @@ fn return_val(val: impl Encode) -> i64 {
let len = encoded.len() as i32;
let ptr = Box::leak(Box::new(encoded)).as_ptr() as i32;

unsafe { core::mem::transmute([ptr, len]) }
pack_u32_to_i64(ptr as u32, len as u32)
}
5 changes: 3 additions & 2 deletions ethexe/runtime/src/wasm/interface/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::wasm::interface;
use core::{mem, slice};
use core::slice;
use ethexe_runtime_common::unpack_i64_to_u32;
use gprimitives::H256;
use parity_scale_codec::{Decode, Encode, Error as CodecError};

Expand All @@ -43,7 +44,7 @@ pub fn read_raw(hash: &H256) -> Option<&[u8]> {
let ptr_len = sys::ext_database_read_by_hash_version_1(hash.as_ptr() as _);

(ptr_len != 0).then(|| {
let [ptr, len]: [i32; 2] = mem::transmute(ptr_len);
let (ptr, len) = unpack_i64_to_u32(ptr_len);
slice::from_raw_parts(ptr as _, len as usize)
})
}
Expand Down
9 changes: 5 additions & 4 deletions ethexe/runtime/src/wasm/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ pub(crate) mod database_ri;
pub(crate) mod logging_ri;

pub(crate) mod utils {
use ethexe_runtime_common::pack_u32_to_i64;
playX18 marked this conversation as resolved.
Show resolved Hide resolved

pub fn repr_ri_slice(slice: impl AsRef<[u8]>) -> i64 {
let slice = slice.as_ref();

let ptr = slice.as_ptr() as i32;
let len = slice.len() as i32;

unsafe { core::mem::transmute([ptr, len]) }
let ptr = slice.as_ptr() as u32;
let len = slice.len() as u32;
pack_u32_to_i64(ptr, len)
}
}

Expand Down
25 changes: 10 additions & 15 deletions runtime-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

extern crate alloc;

use byteorder::{ByteOrder, LittleEndian};
use codec::{Decode, Encode};
use gear_core::{
gas::GasLeft,
Expand Down Expand Up @@ -153,7 +152,10 @@ pub enum ProcessAccessErrorVer1 {
pub trait GearRI {
#[version(2)]
fn pre_process_memory_accesses(reads: &[u8], writes: &[u8], gas_bytes: &mut [u8; 8]) -> u8 {
lazy_pages_detail::pre_process_memory_accesses(reads, writes, gas_bytes)
let mut gas_counter = u64::from_le_bytes(*gas_bytes);
let res = lazy_pages_detail::pre_process_memory_accesses(reads, writes, &mut gas_counter);
gas_bytes.copy_from_slice(&gas_counter.to_le_bytes());
res
}

fn lazy_pages_status() -> (Status,) {
Expand Down Expand Up @@ -224,7 +226,7 @@ pub trait GearRI {
pub mod lazy_pages_detail {
use super::*;

pub fn pre_process_memory_accesses(reads: &[u8], writes: &[u8], gas_bytes: &mut [u8; 8]) -> u8 {
pub fn pre_process_memory_accesses(reads: &[u8], writes: &[u8], gas_counter: &mut u64) -> u8 {
let mem_interval_size = size_of::<MemoryInterval>();
let reads_len = reads.len();
let writes_len = writes.len();
Expand All @@ -234,20 +236,13 @@ pub mod lazy_pages_detail {
let mut writes_intervals = Vec::with_capacity(writes_len / mem_interval_size);
deserialize_mem_intervals(writes, &mut writes_intervals);

let mut gas_counter = LittleEndian::read_u64(gas_bytes);

let res = match gear_lazy_pages::pre_process_memory_accesses(
gear_lazy_pages::pre_process_memory_accesses(
&reads_intervals,
&writes_intervals,
&mut gas_counter,
) {
Ok(_) => 0,
Err(err) => err.into(),
};

LittleEndian::write_u64(gas_bytes, gas_counter);

res
gas_counter,
)
.map(|_| 0)
.unwrap_or_else(|err| err.into())
}

pub fn lazy_pages_status() -> (Status,) {
Expand Down
Loading