Skip to content

Commit

Permalink
add other xcm_methods
Browse files Browse the repository at this point in the history
  • Loading branch information
pgherveou committed Aug 30, 2023
1 parent ba74073 commit 4340995
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
4 changes: 2 additions & 2 deletions polkadot/xcm/xcm-executor/src/traits/on_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use frame_support::{
dispatch::fmt::Debug,
pallet_prelude::{Get, TypeInfo},
};
use parity_scale_codec::{FullCodec, MaxEncodedLen};
use parity_scale_codec::{Decode, Encode, FullCodec, MaxEncodedLen};
use sp_arithmetic::traits::Zero;
use xcm::latest::{
Error as XcmError, InteriorMultiLocation, MultiLocation, QueryId, Response,
Expand Down Expand Up @@ -105,7 +105,7 @@ impl VersionChangeNotifier for () {
}

/// The possible state of an XCM query response.
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Encode, Decode)]
pub enum QueryResponseStatus<BlockNumber> {
/// The response has arrived, and includes the inner Response and the block number it arrived
/// at.
Expand Down
41 changes: 40 additions & 1 deletion substrate/frame/contracts/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ use sp_core::{
use sp_io::{crypto::secp256k1_ecdsa_recover_compressed, hashing::blake2_256};
use sp_runtime::traits::{Convert, Hash, Zero};
use sp_std::{marker::PhantomData, mem, prelude::*, vec::Vec};
use xcm::{VersionedMultiLocation, VersionedXcm};
use xcm::{v3::MultiLocation, VersionedMultiLocation, VersionedXcm};
use xcm_executor::traits::{QueryHandler, QueryResponseStatus};

pub type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
pub type MomentOf<T> = <<T as Config>::Time as Time>::Moment;
Expand Down Expand Up @@ -357,6 +358,17 @@ pub trait Ext: sealing::Sealed {
) -> DispatchResultWithPostInfo;

fn xcm_send(&self, dest: VersionedMultiLocation, msg: VersionedXcm<()>) -> DispatchResult;

fn xcm_query(
&self,
timeout: BlockNumberFor<Self::T>,
match_querier: VersionedMultiLocation,
) -> Result<<pallet_xcm::Pallet<Self::T> as QueryHandler>::QueryId, DispatchError>;

fn xcm_take_response(
&self,
query_id: <pallet_xcm::Pallet<Self::T> as QueryHandler>::QueryId,
) -> QueryResponseStatus<BlockNumberFor<Self::T>>;
}

/// Describes the different functions that can be exported by an [`Executable`].
Expand Down Expand Up @@ -1472,6 +1484,33 @@ where
pallet_xcm::Pallet::<T>::send(origin, Box::new(dest), Box::new(msg))
}

fn xcm_query(
&self,
timeout: BlockNumberFor<T>,
match_querier: VersionedMultiLocation,
) -> Result<<pallet_xcm::Pallet<Self::T> as QueryHandler>::QueryId, DispatchError> {
use frame_support::traits::EnsureOrigin;

let origin = RawOrigin::Signed(self.address().clone()).into();
let responder = <T as pallet_xcm::Config>::ExecuteXcmOrigin::ensure_origin(origin)?;

let query_id = <pallet_xcm::Pallet<T> as QueryHandler>::new_query(
responder,
timeout.into(),
MultiLocation::try_from(match_querier)
.map_err(|_| Into::<DispatchError>::into(pallet_xcm::Error::<T>::BadVersion))?,
);

Ok(query_id)
}

fn xcm_take_response(
&self,
query_id: <pallet_xcm::Pallet<Self::T> as QueryHandler>::QueryId,
) -> QueryResponseStatus<BlockNumberFor<Self::T>> {
<pallet_xcm::Pallet<T> as QueryHandler>::take_response(query_id)
}

fn ecdsa_recover(&self, signature: &[u8; 65], message_hash: &[u8; 32]) -> Result<[u8; 33], ()> {
secp256k1_ecdsa_recover_compressed(signature, message_hash).map_err(|_| ())
}
Expand Down
46 changes: 46 additions & 0 deletions substrate/frame/contracts/src/wasm/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2695,6 +2695,52 @@ pub mod env {
}
}

fn xcm_query(
ctx: _,
memory: _,
timeout_ptr: u32,
match_querier_ptr: u32,
output_ptr: u32,
) -> Result<ReturnCode, TrapReason> {
use frame_system::pallet_prelude::BlockNumberFor;
use xcm::VersionedMultiLocation;

let timeout: BlockNumberFor<E::T> = ctx.read_sandbox_memory_as(memory, timeout_ptr)?;
let match_querier: VersionedMultiLocation =
ctx.read_sandbox_memory_as(memory, match_querier_ptr)?;
// TODO benchmark
match ctx.ext.xcm_query(timeout, match_querier) {
Ok(query_id) => {
ctx.write_sandbox_memory(memory, output_ptr, &query_id.encode())?;
Ok(ReturnCode::Success)
},
Err(e) => {
if ctx.ext.append_debug_buffer("") {
ctx.ext.append_debug_buffer("call failed with: ");
ctx.ext.append_debug_buffer(e.into());
};
Ok(ReturnCode::CallRuntimeFailed)
},
}
}

fn xcm_take_response(
ctx: _,
memory: _,
query_id_ptr: u32,
output_ptr: u32,
) -> Result<ReturnCode, TrapReason> {
use xcm_executor::traits::QueryHandler;

let query_id: <pallet_xcm::Pallet<E::T> as QueryHandler>::QueryId =
ctx.read_sandbox_memory_as(memory, query_id_ptr)?;

// TODO benchmark
let response = ctx.ext.xcm_take_response(query_id);
ctx.write_sandbox_memory(memory, output_ptr, &response.encode())?;
Ok(ReturnCode::Success)
}

/// Recovers the ECDSA public key from the given message hash and signature.
///
/// Writes the public key into the given output buffer.
Expand Down

0 comments on commit 4340995

Please sign in to comment.