#![deny(clippy::arithmetic_side_effects)]
#![deny(clippy::cast_possible_truncation)]
#![deny(unused_crate_dependencies)]
#![deny(warnings)]
use crate as fuel_core_wasm_executor;
use crate::utils::{
convert_to_v1_execution_result,
InputDeserializationType,
WasmDeserializationBlockTypes,
};
use fuel_core_executor::executor::ExecutionInstance;
use fuel_core_types::{
blockchain::block::Block,
services::{
block_producer::Components,
executor::Error as ExecutorError,
},
};
use fuel_core_wasm_executor::{
relayer::WasmRelayer,
storage::WasmStorage,
tx_source::WasmTxSource,
utils::{
pack_ptr_and_len,
ReturnType,
},
};
mod ext;
mod relayer;
mod storage;
mod tx_source;
pub mod utils;
#[no_mangle]
pub extern "C" fn execute(input_len: u32) -> u64 {
let output: ReturnType = execute_without_commit(input_len);
let encoded = postcard::to_allocvec(&output).expect("Failed to encode the output");
let static_slice = encoded.leak();
pack_ptr_and_len(
static_slice.as_ptr() as u32,
u32::try_from(static_slice.len()).expect("We only support wasm32 target; qed"),
)
}
pub fn execute_without_commit(input_len: u32) -> ReturnType {
let input =
ext::input(input_len as usize).map_err(|e| ExecutorError::Other(e.to_string()));
let input = match input {
Ok(input) => input,
Err(err) => {
return ReturnType::ExecutionV1(Err(err.into()));
}
};
let (block, options) = match input {
InputDeserializationType::V1 { block, options } => {
let block = match block {
WasmDeserializationBlockTypes::DryRun(c) => {
WasmDeserializationBlockTypes::DryRun(use_wasm_tx_source(c))
}
WasmDeserializationBlockTypes::Production(c) => {
WasmDeserializationBlockTypes::Production(use_wasm_tx_source(c))
}
WasmDeserializationBlockTypes::Validation(c) => {
WasmDeserializationBlockTypes::Validation(c)
}
};
(block, options)
}
};
let instance = ExecutionInstance {
relayer: WasmRelayer {},
database: WasmStorage {},
options,
};
match block {
WasmDeserializationBlockTypes::DryRun(c) => execute_dry_run(instance, c),
WasmDeserializationBlockTypes::Production(c) => execute_production(instance, c),
WasmDeserializationBlockTypes::Validation(c) => execute_validation(instance, c),
}
}
fn execute_dry_run(
instance: ExecutionInstance<WasmRelayer, WasmStorage>,
block: Components<WasmTxSource>,
) -> ReturnType {
let result = instance.produce_without_commit(block, true);
ReturnType::ExecutionV1(convert_to_v1_execution_result(result))
}
fn execute_production(
instance: ExecutionInstance<WasmRelayer, WasmStorage>,
block: Components<WasmTxSource>,
) -> ReturnType {
let result = instance.produce_without_commit(block, false);
ReturnType::ExecutionV1(convert_to_v1_execution_result(result))
}
fn execute_validation(
instance: ExecutionInstance<WasmRelayer, WasmStorage>,
block: Block,
) -> ReturnType {
ReturnType::Validation(instance.validate_without_commit(&block).map_err(Into::into))
}
fn use_wasm_tx_source(component: Components<()>) -> Components<WasmTxSource> {
let Components {
header_to_produce,
gas_price,
coinbase_recipient,
..
} = component;
Components {
header_to_produce,
gas_price,
transactions_source: WasmTxSource::new(),
coinbase_recipient,
}
}
fn main() {}