I'm using Transact to execute an extrinsic from one parachain to another. This extrinsic requires the origin to be a signed account which I'm verifying with ensure_signed.
The way I'm getting a signed account from an xcm origin is through the OriginConverter type defined on xcm_executor::Config in the runtime. I had to implement my own struct to retrieve the account id sent down and converted into a signed accountId:
pub struct SignedAccountId32FromXcm<Origin>(PhantomData<(Origin)>);
impl< Origin: OriginTrait> ConvertOrigin<Origin>
for SignedAccountId32FromXcm<Origin>
where
Origin::AccountId: From<[u8; 32]>,
{
fn convert_origin(
origin: impl Into<MultiLocation>,
kind: OriginKind,
) -> Result<Origin, MultiLocation> {
let origin = origin.into();
log::trace!(
target: "xcm::origin_conversion",
"SignedAccountId32AsNative origin: {:?}, kind: {:?}",
origin, kind,
);
match (kind, origin) {
(
OriginKind::Xcm,
MultiLocation { parents: 1, interior: X2(Junction::Parachain(para_id), Junction::AccountId32 { id, network }) },
) =>
Ok(Origin::signed(id.into())),
(_, origin) => Err(origin),
}
}
}
The way I see it, there is no actual check that the person who sent the xcm is the owner of the accountId. There is no signature on the message or anything. I am just creating a Origin::signed(id) from the id extracted.
So how would I go about ensuring that an origin sent with DescendOrigin is signed, or trusted to be from the person who own the private key of that account?