wasm_host_simulator/
vm_wamr.rs

1use crate::data_provider::DataProvider;
2use crate::host_functions_wamr::{
3    account_keylet, amm_keylet, cache_ledger_obj, check_keylet, compute_sha512_half,
4    credential_keylet, delegate_keylet, deposit_preauth_keylet, did_keylet, escrow_keylet,
5    float_add, float_compare, float_divide, float_from_int, float_from_uint, float_log,
6    float_multiply, float_pow, float_root, float_set, float_subtract,
7    get_current_ledger_obj_array_len, get_current_ledger_obj_field,
8    get_current_ledger_obj_nested_array_len, get_current_ledger_obj_nested_field,
9    get_ledger_obj_array_len, get_ledger_obj_field, get_ledger_obj_nested_array_len,
10    get_ledger_obj_nested_field, get_ledger_sqn, get_nft, get_parent_ledger_hash,
11    get_parent_ledger_time, get_tx_array_len, get_tx_field, get_tx_nested_array_len,
12    get_tx_nested_field, line_keylet, mpt_issuance_keylet, mptoken_keylet, nft_offer_keylet,
13    offer_keylet, oracle_keylet, paychan_keylet, permissioned_domain_keylet, signers_keylet,
14    ticket_keylet, trace, trace_account, trace_amount, trace_num, trace_opaque_float, update_data,
15    vault_keylet,
16};
17use crate::mock_data::MockData;
18use log::{debug, info, warn};
19use std::ffi::c_void;
20use std::path::PathBuf;
21use wamr_rust_sdk::RuntimeError;
22use wamr_rust_sdk::function::Function;
23use wamr_rust_sdk::instance::Instance;
24use wamr_rust_sdk::module::Module;
25use wamr_rust_sdk::runtime::Runtime;
26use wamr_rust_sdk::value::WasmValue;
27
28#[rustfmt::skip]
29#[allow(unused)]
30pub fn run_func(wasm_file: String, func_name: &str, gas_cap: Option<u32>, data_source: MockData) -> Result<bool, RuntimeError>{
31    debug!("Setting up wamr runtime and registering host functions");
32    let mut data_provider = DataProvider::new(data_source);
33    let runtime = Runtime::builder()
34        .use_system_allocator()
35        .register_host_function("get_ledger_sqn", get_ledger_sqn as *mut c_void, "()i", 60, data_provider.as_ptr())
36        .register_host_function("get_parent_ledger_time", get_parent_ledger_time as *mut c_void, "()i", 60, data_provider.as_ptr())
37        .register_host_function("get_parent_ledger_hash", get_parent_ledger_hash as *mut c_void, "(*~)i", 60, data_provider.as_ptr())
38        .register_host_function("cache_ledger_obj", cache_ledger_obj as *mut c_void, "(*~i)i", 5000, data_provider.as_ptr())
39        .register_host_function("get_tx_field", get_tx_field as *mut c_void, "(i*~)i", 70, data_provider.as_ptr())
40        .register_host_function("get_current_ledger_obj_field", get_current_ledger_obj_field as *mut c_void, "(i*~)i", 70, data_provider.as_ptr())
41        .register_host_function("get_ledger_obj_field", get_ledger_obj_field as *mut c_void, "(ii*~)i", 70, data_provider.as_ptr())
42        .register_host_function("get_tx_nested_field", get_tx_nested_field as *mut c_void, "(*~*~)i", 110, data_provider.as_ptr())
43        .register_host_function("get_current_ledger_obj_nested_field", get_current_ledger_obj_nested_field as *mut c_void, "(*~*~)i", 110, data_provider.as_ptr())
44        .register_host_function("get_ledger_obj_nested_field", get_ledger_obj_nested_field as *mut c_void, "(i*~*~)i", 110, data_provider.as_ptr())
45        .register_host_function("get_tx_array_len", get_tx_array_len as *mut c_void, "(i)i", 40, data_provider.as_ptr())
46        .register_host_function("get_current_ledger_obj_array_len", get_current_ledger_obj_array_len as *mut c_void, "(i)i", 40, data_provider.as_ptr())
47        .register_host_function("get_ledger_obj_array_len", get_ledger_obj_array_len as *mut c_void, "(ii)i", 40, data_provider.as_ptr())
48        .register_host_function("get_tx_nested_array_len", get_tx_nested_array_len as *mut c_void, "(*~)i", 70, data_provider.as_ptr())
49        .register_host_function("get_current_ledger_obj_nested_array_len", get_current_ledger_obj_nested_array_len as *mut c_void, "(*~)i", 70, data_provider.as_ptr())
50        .register_host_function("get_ledger_obj_nested_array_len", get_ledger_obj_nested_array_len as *mut c_void, "(i*~)i", 70, data_provider.as_ptr())
51        .register_host_function("update_data", update_data as *mut c_void, "(*~)i", 1000, data_provider.as_ptr())
52        .register_host_function("compute_sha512_half", compute_sha512_half as *mut c_void, "(*~*~)i", 2000, data_provider.as_ptr())
53        .register_host_function("account_keylet", account_keylet as *mut c_void, "(*~*~)i", 350, data_provider.as_ptr())
54        .register_host_function("amm_keylet", amm_keylet as *mut c_void, "(*~*~*~)i", 350, data_provider.as_ptr())
55        .register_host_function("credential_keylet", credential_keylet as *mut c_void, "(*~*~*~*~)i", 350, data_provider.as_ptr())
56        .register_host_function("check_keylet", check_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
57        .register_host_function("delegate_keylet", delegate_keylet as *mut c_void, "(*~*~*~)i", 350, data_provider.as_ptr())
58        .register_host_function("deposit_preauth_keylet", deposit_preauth_keylet as *mut c_void, "(*~*~*~)i", 350, data_provider.as_ptr())
59        .register_host_function("did_keylet", did_keylet as *mut c_void, "(*~*~)i", 350, data_provider.as_ptr())
60        .register_host_function("escrow_keylet", escrow_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
61        .register_host_function("line_keylet", line_keylet as *mut c_void, "(*~*~*~*~)i", 350, data_provider.as_ptr())
62        .register_host_function("mpt_issuance_keylet", mpt_issuance_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
63        .register_host_function("mptoken_keylet", mptoken_keylet as *mut c_void, "(*~*~*~)i", 350, data_provider.as_ptr())
64        .register_host_function("nft_offer_keylet", nft_offer_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
65        .register_host_function("offer_keylet", offer_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
66        .register_host_function("oracle_keylet", oracle_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
67        .register_host_function("paychan_keylet", paychan_keylet as *mut c_void, "(*~*~i*~)i", 350, data_provider.as_ptr())
68        .register_host_function("permissioned_domain_keylet", permissioned_domain_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
69        .register_host_function("signers_keylet", signers_keylet as *mut c_void, "(*~*~)i", 350, data_provider.as_ptr())
70        .register_host_function("ticket_keylet", ticket_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
71        .register_host_function("vault_keylet", vault_keylet as *mut c_void, "(*~i*~)i", 350, data_provider.as_ptr())
72        .register_host_function("get_nft", get_nft as *mut c_void, "(*~*~*~)i", 1000, data_provider.as_ptr())
73        .register_host_function("float_from_int", float_from_int as *mut c_void, "(I*~i)i", 1000, data_provider.as_ptr())
74        .register_host_function("float_from_uint", float_from_uint as *mut c_void, "(*~*~i)i", 1000, data_provider.as_ptr())
75        .register_host_function("float_set", float_set as *mut c_void, "(iI*~i)i", 1000, data_provider.as_ptr())
76        .register_host_function("float_compare", float_compare as *mut c_void, "(*~*~)i", 1000, data_provider.as_ptr())
77        .register_host_function("float_add", float_add as *mut c_void, "(*~*~*~i)i", 1000, data_provider.as_ptr())
78        .register_host_function("float_subtract", float_subtract as *mut c_void, "(*~*~*~i)i", 1000, data_provider.as_ptr())
79        .register_host_function("float_multiply", float_multiply as *mut c_void, "(*~*~*~i)i", 1000, data_provider.as_ptr())
80        .register_host_function("float_divide", float_divide as *mut c_void, "(*~*~*~i)i", 1000, data_provider.as_ptr())
81        .register_host_function("float_pow", float_pow as *mut c_void, "(*~i*~i)i", 1000, data_provider.as_ptr())
82        .register_host_function("float_root", float_root as *mut c_void, "(*~i*~i)i", 1000, data_provider.as_ptr())
83        .register_host_function("float_log", float_log as *mut c_void, "(*~*~i)i", 1000, data_provider.as_ptr())
84        .register_host_function("trace", trace as *mut c_void, "(*~*~i)i", 500, data_provider.as_ptr())
85        .register_host_function("trace_num", trace_num as *mut c_void, "(*~I)i", 500, data_provider.as_ptr())
86        .register_host_function("trace_opaque_float", trace_opaque_float as *mut c_void, "(*~*~)i", 500, data_provider.as_ptr())
87        .register_host_function("trace_account", trace_account as *mut c_void, "(*~*~)i", 500, data_provider.as_ptr())
88        .register_host_function("trace_amount", trace_amount as *mut c_void, "(*~*~)i", 500, data_provider.as_ptr())
89        .build()?;
90
91    debug!("Loading WASM module from file: {}", wasm_file);
92    let wasm_path = PathBuf::from(wasm_file);
93    let module = Module::from_file(&runtime, wasm_path.as_path())?;
94    // rippled currently allows 128kb for each VM instance, so we use the same here in Craft.
95    let instance = Instance::new(&runtime, &module, 1024 * 128)?;
96
97    debug!("Executing WASM function: {}", func_name);
98    let func = Function::find_export_func(&instance, "finish")?;
99    let gas_begin = gas_cap.map_or(0, |x|x);
100    let results = func.call(&instance, &vec![], gas_cap)?;
101    match results {
102        (rv, gas_end) if rv.len() == 1 => {
103            if let WasmValue::I32(r1) = rv[0] {
104                info!("run_func result: {}", r1);
105                if gas_begin > 0 {
106                    info!("run_func gas cost: {}", gas_begin - gas_end);
107                }
108                Ok(r1 == 1)
109            } else {
110                warn!("Unexpected run_func result vec: {:?}", rv[0]);
111                Ok(false)
112            }
113        }
114        _ => {
115            warn!("run_func error: {:?}", results);
116            Ok(false)
117        }
118    }
119}