paritytech / polkadot-sdk

The Parity Polkadot Blockchain SDK
https://polkadot.network/
1.85k stars 674 forks source link

"And gate" for EnsureOrigin #369

Open gavofyork opened 5 years ago

gavofyork commented 5 years ago

It should be possible to easily specify that two (independent) EnsureOrigin implementations must both agree that dispatch should happen as a third EnsureOrigin.

Since the origin cannot be collected together, it would necessitate a module which retained state over dispatch/proposal hashes, allowing one origin to approve a hash first, and the other origin to approve it later causing the dispatch.

An analogous "Or gate" would also be useful.

bowd commented 5 years ago

@gavofyork ✋I'm willing to give this a shot but I'm totally new to Substrate. I'm a quick learner though and I'm used to finding my way around code and resources as long as I'm pushed in the right direction. I have some rust experience, enough to make sense of things but will probably have questions on finer points.

expenses commented 5 years ago

Would you mind going into a little bit more detail about this issue? Would something like the following be sufficient?

pub struct EnsureBoth<OriginA, OriginB>(rstd::marker::PhantomData<(OriginA, OriginB)>);

impl<
    AO: Clone, BO: Clone,
    OriginA: EnsureOrigin<AO>, OriginB: EnsureOrigin<BO>,
> EnsureOrigin<(AO, BO)> for EnsureBoth<OriginA, OriginB> {
    type Success = (OriginA::Success, OriginB::Success);

    fn try_origin((a, b): (AO, BO)) -> Result<Self::Success, (AO, BO)> {
        let a_result = OriginA::try_origin(a.clone());
        let b_result = OriginB::try_origin(b.clone());

        match (a_result, b_result) {
            (Ok(a_s), Ok(b_s)) => Ok((a_s, b_s)),
            _ => Err((a, b))
        }
    }
}