2

When I select the Transact instruction, I can select an OriginKind (Native, SovereignAccount, Superuser, Xcm) but it isn't clear to me how these different origins are interpreted. I thought I saw information about this somewhere, but can't find it. Are there examples of the implications of using different origins or use cases that highlight when to use which origin?

1

1 Answer 1

1

There are descriptions of the origins in the codebase.

https://github.com/paritytech/polkadot/blob/master/xcm/src/v0/mod.rs#L60

/// Basically just the XCM (more general) version of `ParachainDispatchOrigin`.
#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)]
pub enum OriginKind {
    /// Origin should just be the native dispatch origin representation for the sender in the
    /// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin
    /// if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a
    /// primary/native dispatch origin form.
    Native,

    /// Origin should just be the standard account-based origin with the sovereign account of
    /// the sender. For Cumulus/Frame chains, this is the `Signed` origin.
    SovereignAccount,

    /// Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin.
    /// This will not usually be an available option.
    Superuser,

    /// Origin should be interpreted as an XCM native origin and the `MultiLocation` should be
    /// encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be
    /// the `pallet_xcm::Origin::Xcm` type.
    Xcm,
}

The implications of using different origins depends on the code you are calling, and if you are able to generate that origin at all.

For example, it would not be normal for a regular user to be able to generate the Superuser origin, but it may be possible for the chain logic itself to do that. Having access to the Superuser origin will allow you to use configurations like ParentAsSuperuser which specifically check for these things:

pub struct ParentAsSuperuser<RuntimeOrigin>(PhantomData<RuntimeOrigin>);
impl<RuntimeOrigin: OriginTrait> ConvertOrigin<RuntimeOrigin> for ParentAsSuperuser<RuntimeOrigin> {
    fn convert_origin(
        origin: impl Into<MultiLocation>,
        kind: OriginKind,
    ) -> Result<RuntimeOrigin, MultiLocation> {
        let origin = origin.into();
        log::trace!(target: "xcm::origin_conversion", "ParentAsSuperuser origin: {:?}, kind: {:?}", origin, kind);
        if kind == OriginKind::Superuser && origin.contains_parents_only(1) {
            Ok(RuntimeOrigin::root())
        } else {
            Err(origin)
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.