Skip to content
Snippets Groups Projects
Unverified Commit ae12dafd authored by Tiago Bandeira's avatar Tiago Bandeira
Browse files

pallet_revive: add the new_query function as an unstable api

parent 4cc53b43
Branches
No related merge requests found
......@@ -19,6 +19,7 @@ use codec::{Decode, Encode};
use core::{fmt::Debug, result};
use frame_support::{pallet_prelude::Get, parameter_types};
use sp_arithmetic::traits::Zero;
use sp_core::U256;
use xcm::latest::{
Error as XcmError, InteriorLocation, Location, QueryId, Response, Result as XcmResult, Weight,
XcmContext,
......@@ -111,7 +112,7 @@ pub enum QueryResponseStatus<BlockNumber> {
/// Provides methods to expect responses from XCMs and query their status.
pub trait QueryHandler {
type BlockNumber: Zero + Encode;
type BlockNumber: Zero + Encode + TryFrom<U256>;
type Error;
type UniversalLocation: Get<InteriorLocation>;
......
......@@ -2132,6 +2132,52 @@ pub mod env {
}
}
///
/// See [`pallet_revive_uapi::HostFn::new_query`].
#[mutating]
fn xcm_new_query(
&mut self,
memory: &mut M,
responder_ptr: u32,
responder_len: u32,
maybe_notify_ptr: u32,
maybe_notify_len: u32,
timeout_ptr: u32,
output_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
use xcm::VersionedLocation;
use xcm_builder::QueryHandler;
// Read responder from contract memory and convert it to the expected Location type.
self.charge_gas(RuntimeCosts::CopyFromContract(responder_len))?;
let responder: VersionedLocation = memory.read_as_unbounded(responder_ptr, responder_len)?;
// Read maybe_notify bytes. If length is zero, treat as None; otherwise decode as a (u8, u8) tuple.
let maybe_notify: Option<(u8, u8)> = if maybe_notify_len > 0 {
self.charge_gas(RuntimeCosts::CopyFromContract(maybe_notify_len))?;
let notify = memory.read_as_unbounded(maybe_notify_ptr, maybe_notify_len)?;
Some(notify)
} else {
None
};
let timeout_u256 = memory.read_u256(timeout_ptr)?;
let timeout = <<E::T as Config>::Xcm as QueryHandler>::BlockNumber::try_from(timeout_u256)
.map_err(|_err| Error::<E::T>::DecodingFailed)?;
let querier = crate::RawOrigin::Signed(self.ext.account_id().clone()).into();
// Call pallet-xcm's new_query with the converted parameters.
let query_id = <<E::T as Config>::Xcm>::new_query(
responder.into(),
maybe_notify,
timeout,
querier,
);
memory.write(output_ptr, &query_id.encode())?;
Ok(ReturnErrorCode::Success)
}
/// Retrieves the account id for a specified contract address.
///
/// See [`pallet_revive_uapi::HostFn::to_account_id`].
......
......@@ -735,6 +735,17 @@ pub trait HostFn: private::Sealed {
/// execution fails, `ReturnErrorCode::XcmSendFailed` is returned.
#[unstable_hostfn]
fn xcm_send(dest: &[u8], msg: &[u8], output: &mut [u8; 32]) -> Result;
/// Create a new query
///
/// # Parameters
///
/// - `responder`:
/// - `maybe_notify`:
/// - `timeout`:
///
#[unstable_hostfn]
fn new_query(responder: &[u8], maybe_notify: &[u8], timeout: &[u8], output: &mut [u8; 32]) -> Result;
}
mod private {
......
......@@ -150,6 +150,14 @@ mod sys {
msg_len: u32,
out_ptr: *mut u8,
) -> ReturnCode;
pub fn new_query(
responder_ptr: *const u8,
responder_len: *const u8,
maybe_notify_ptr: *const u8,
maybe_notify_len: u32,
timeout_ptr: *const u8,
out_ptr: *mut u8,
) -> ReturnCode;
pub fn return_data_size() -> u64;
pub fn return_data_copy(out_ptr: *mut u8, out_len_ptr: *mut u32, offset: u32);
}
......@@ -610,4 +618,19 @@ impl HostFn for HostFnImpl {
};
ret_code.into()
}
#[unstable_hostfn]
fn new_query(responder: &[u8], maybe_notify: &[u8], timeout: &[u8], output: &mut [u8; 32]) -> Result {
let ret_code = unsafe {
sys::new_query(
responder.as_ptr(),
responder.len() as _,
maybe_notify.as_ptr(),
maybe_notify.len() as _,
timeout.as_ptr(),
output.as_mut_ptr(),
)
};
ret_code.into()
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment