pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> 
    Result<AccountId, BadOrigin>
    where OuterOrigin: 
        match o.into() {
            Ok(RawOrigin::Signed(t)) => Ok(t),
            _ => Err(BadOrigin),
  1. In which case, do we get the BadOrigin?

         type Origin: Into<Result<RawOrigin<Self::AccountId>, 
                      + From<RawOrigin<Self::AccountId>>
                      + Clone
                      + OriginTrait<Call = Self::Call>;
  2. type Origin is bounded to Into & From trait, I am not sure how to understand this type. Does Into<Result<RawOriginSelf::AccountId>> mean whoever implements impl Into<Result<RawOrigin<Self::AccountId> for <U> or impl From<RawOrigin<Self::AccountId>> for <U>, then this U can be Origin type?

2 Answers 2

  1. In which case, do we get the BadOrigin? Give an example(maybe not proper), maybe the RawOrigin is None, means maybe some submit an extrinsic without signing it.

  2. type Origin is bounded to Into & From trait, I am not sure how to understand this type. Does Into<ResultRawOriginSelf::AccountId> mean whoever implements impl Into<Result<RawOriginSelf::AccountId for or impl From<RawOriginSelf::AccountId> for , then this U can be Origin type?

I think so, just read the doc of these two traitFrom traitInto trait, you'll be super clear. And in the docs, you'll find following explaination:

From<T> for U implies Into<U> for T
From is reflexive, which means that From<T> for T is implemented
  • Ok, not I get it. Thank you for the answer
    – coco_yoon
    Commented Apr 28, 2022 at 11:16

In the example presented above, the code seems to call o.into(). into() comes from the Into trait. o is of OuterOrigin and it is a generic parameter, thus will be determined at the time of a call, by the caller.

Thus, if the implementation of that type o.into() returns any Err variant of the Result enum, or the variant Ok with anything else but RawOrigin::Signed then BadOrigin will be returned.

Regarding the second question. This type declaration declares an associated type Origin, which is bounded by several traits. That means, that when the trait (I assume you got that line from a trait Config) is implemented for some type then the implementer, among other things, has to provide a type into Origin, such that it satisfies all the bounds for Origin.


impl Config for X {
  type Origin = MyOrigin;
  type AccountId = MyAccountId;
  // ..

That type Y should have implementations for

impl Into<Result<RawOrigin<MyAccountId>, MyOrigin>> for MyOrigin {
  fn into(self) -> Result<RawOrigin<MyAccountId>> {
    // ...

impl From<RawOrigin<MyAccountId>> for MyOrigin {
  fn from(o: RawOrigin<MyAccountId>) -> MyOrigin {
    // .
  • Thank you for the answer. For question 1, I mean in which circumstances, more specifically, that code means if the o:OuterOrigin is signed, then it gives us AccountId that is signed, in which case o:OuterOrigin is not representing signed extrinsic? which gives us BadOrigin type.
    – coco_yoon
    Commented Apr 25, 2022 at 14:49
  • To clear my thought on question 2, so to be associated type of Origin, our own type should implement that all bounded traits for type Origin, am I right?
    – coco_yoon
    Commented Apr 25, 2022 at 15:03

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.