Skip to content

Design of APIs between XCQ host and guest program

Jiyuan Zheng edited this page Jul 30, 2024 · 3 revisions

Make APIs more ergonomic

  • feature discovery
    • hasExtension
  • return type decode

Example:

// TODO: this function is automatically generated, and shouldn't be displayed/moved/deleted
#[polkavm_derive::polkavm_import]
extern "C" {
    fn call(extension_id: u64, call_ptr: u32, call_len: u32) -> u64;
}
#[polkavm_derive::polkavm_export]
extern "C" fn main(ptr: u32, size: u32) -> u64 {
    // TODO: make extension_id reading automatically
    // TODO: make pointer moving automatically
    let extension_id = unsafe { core::ptr::read_volatile(ptr as *const u64) };
    let num_query = unsafe { core::ptr::read_volatile((ptr + 8) as *const u8) };
    let query_size = (size - 9) / num_query as u32;
    let mut sum = 0u64;
    for i in 0..num_query { 
        // TODO: single call need to be wrapped in a semantic context 
        let res = unsafe { call(extension_id, ptr + 9 + query_size * i as u32, query_size) };
        let res_len = (res >> 32) as u32;
        let res_ptr = (res & 0xffffffff) as *const u8;
        let res_bytes = unsafe { core::slice::from_raw_parts(res_ptr, res_len as usize) };
        // TODO: there needs a codec::Decode call(doing in guest or via a host call)
        sum += u64::from_le_bytes(res_bytes.try_into().unwrap());
    }
    let sum_bytes = sum.to_le_bytes();
    let ptr = polkavm_derive::sbrk(sum_bytes.len());
    if ptr.is_null() {
        return 0;
    }
    unsafe {
        core::ptr::copy_nonoverlapping(sum_bytes.as_ptr(), ptr, sum_bytes.len());
    }
    (sum_bytes.len() as u64) << 32 | (ptr as u64)
}

parameters passing convention

The interface between xcq-executor and polkavm program is: (ptr: *u8, length: u32) -> u64. It takes a pointer to an u8 array and its length as an argument. This u8 array is expected to be the SCALE encoded parameters of the function as defined in the trait. The return value is an u64 that represents length << 32 | pointer of an u8 array. This return value u8 array contains the SCALE encoded return value as defined by the trait function. This convention is the same as sp_api

Clone this wiki locally