wevm-core 0.4.1

Waves Enterprise Virtual Machine for WASM smart-contracts
Documentation
use crate::{
    error::{ExecutableError, RuntimeError},
    node::Node,
    runtime::{data_entry::DataEntry, Runtime},
};
use wasmi::Caller;

pub fn contains_key(
    offset_address: u32,
    length_address: u32,
    offset_key: u32,
    length_key: u32,
    mut caller: Caller<Runtime>,
) -> (i32, i32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0),
    };

    let address = if length_address != 0 {
        memory[offset_address as usize..offset_address as usize + length_address as usize].to_vec()
    } else {
        ctx.vm.top_frame().contract_id()
    };

    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];

    match ctx.vm.contains_key(address.as_slice(), key) {
        Ok(result) => (0, result as i32),
        Err(error) => (error.as_i32(), 0),
    }
}

pub fn get_storage_int(
    offset_address: u32,
    length_address: u32,
    offset_key: u32,
    length_key: u32,
    mut caller: Caller<Runtime>,
) -> (i32, i64) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0),
    };

    let address = if length_address != 0 {
        memory[offset_address as usize..offset_address as usize + length_address as usize].to_vec()
    } else {
        ctx.vm.top_frame().contract_id()
    };

    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];

    match ctx.vm.get_storage(address.as_slice(), key) {
        Ok(bytes) => match DataEntry::deserialize(bytes.as_slice()) {
            Ok(DataEntry::Integer(integer)) => (0, integer),
            _ => (ExecutableError::FailedDeserialize.as_i32(), 0),
        },
        Err(error) => (error.as_i32(), 0),
    }
}

pub fn get_storage_bool(
    offset_address: u32,
    length_address: u32,
    offset_key: u32,
    length_key: u32,
    mut caller: Caller<Runtime>,
) -> (i32, i32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0),
    };

    let address = if length_address != 0 {
        memory[offset_address as usize..offset_address as usize + length_address as usize].to_vec()
    } else {
        ctx.vm.top_frame().contract_id()
    };

    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];

    match ctx.vm.get_storage(address.as_slice(), key) {
        Ok(bytes) => match DataEntry::deserialize(bytes.as_slice()) {
            Ok(DataEntry::Boolean(boolean)) => (0, boolean),
            _ => (ExecutableError::FailedDeserialize.as_i32(), 0),
        },
        Err(error) => (error.as_i32(), 0),
    }
}

pub fn get_storage_binary(
    offset_address: u32,
    length_address: u32,
    offset_key: u32,
    length_key: u32,
    mut caller: Caller<Runtime>,
) -> (i32, u32, u32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0, 0),
    };
    let offset_memory = ctx.heap_base() as usize;

    let address = if length_address != 0 {
        memory[offset_address as usize..offset_address as usize + length_address as usize].to_vec()
    } else {
        ctx.vm.top_frame().contract_id()
    };

    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];

    match ctx.vm.get_storage(address.as_slice(), key) {
        Ok(bytes) => {
            let result = match DataEntry::deserialize(bytes.as_slice()) {
                Ok(DataEntry::Binary(bytes)) => bytes,
                _ => return (ExecutableError::FailedDeserialize.as_i32(), 0, 0),
            };
            crate::env::write_memory(ctx, memory, offset_memory, result)
        }
        Err(error) => (error.as_i32(), 0, 0),
    }
}

pub fn get_storage_string(
    offset_address: u32,
    length_address: u32,
    offset_key: u32,
    length_key: u32,
    mut caller: Caller<Runtime>,
) -> (i32, u32, u32) {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return (RuntimeError::MemoryNotFound.as_i32(), 0, 0),
    };
    let offset_memory = ctx.heap_base() as usize;

    let address = if length_address != 0 {
        memory[offset_address as usize..offset_address as usize + length_address as usize].to_vec()
    } else {
        ctx.vm.top_frame().contract_id()
    };

    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];

    match ctx.vm.get_storage(address.as_slice(), key) {
        Ok(bytes) => {
            let result = match DataEntry::deserialize(bytes.as_slice()) {
                Ok(DataEntry::String(bytes)) => bytes,
                _ => return (ExecutableError::FailedDeserialize.as_i32(), 0, 0),
            };
            crate::env::write_memory(ctx, memory, offset_memory, result)
        }
        Err(error) => (error.as_i32(), 0, 0),
    }
}

pub fn set_storage_int(
    offset_key: u32,
    length_key: u32,
    value: i64,
    mut caller: Caller<Runtime>,
) -> i32 {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return RuntimeError::MemoryNotFound.as_i32(),
    };

    let contract_id = ctx.vm.top_frame().contract_id();
    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];
    let data_entry = DataEntry::Integer(value).serialize(Some(key));

    match ctx
        .vm
        .set_storage(contract_id.as_slice(), data_entry.as_slice())
    {
        Ok(_) => 0,
        Err(error) => error.as_i32(),
    }
}

pub fn set_storage_bool(
    offset_key: u32,
    length_key: u32,
    value: i32,
    mut caller: Caller<Runtime>,
) -> i32 {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return RuntimeError::MemoryNotFound.as_i32(),
    };

    let contract_id = ctx.vm.top_frame().contract_id();
    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];
    let data_entry = DataEntry::Boolean(value).serialize(Some(key));

    match ctx
        .vm
        .set_storage(contract_id.as_slice(), data_entry.as_slice())
    {
        Ok(_) => 0,
        Err(error) => error.as_i32(),
    }
}

pub fn set_storage_binary(
    offset_key: u32,
    length_key: u32,
    offset_value: u32,
    length_value: u32,
    mut caller: Caller<Runtime>,
) -> i32 {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return RuntimeError::MemoryNotFound.as_i32(),
    };

    let contract_id = ctx.vm.top_frame().contract_id();
    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];
    let value = &memory[offset_value as usize..offset_value as usize + length_value as usize];
    let data_entry = DataEntry::Binary(value.to_vec()).serialize(Some(key));

    match ctx
        .vm
        .set_storage(contract_id.as_slice(), data_entry.as_slice())
    {
        Ok(_) => 0,
        Err(error) => error.as_i32(),
    }
}

pub fn set_storage_string(
    offset_key: u32,
    length_key: u32,
    offset_value: u32,
    length_value: u32,
    mut caller: Caller<Runtime>,
) -> i32 {
    let (memory, ctx) = match caller.data().memory() {
        Some(memory) => memory.data_and_store_mut(&mut caller),
        None => return RuntimeError::MemoryNotFound.as_i32(),
    };

    let contract_id = ctx.vm.top_frame().contract_id();
    let key = &memory[offset_key as usize..offset_key as usize + length_key as usize];
    let value = &memory[offset_value as usize..offset_value as usize + length_value as usize];
    let data_entry = DataEntry::String(value.to_vec()).serialize(Some(key));

    match ctx
        .vm
        .set_storage(contract_id.as_slice(), data_entry.as_slice())
    {
        Ok(_) => 0,
        Err(error) => error.as_i32(),
    }
}