mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 22:47:56 +00:00
a808a3a091
See #1345, <https://github.com/paritytech/substrate/pull/14207>. This adds all the necessary mixnet components, and puts them together in the "kitchen-sink" node/runtime. The components added are: - A pallet (`frame/mixnet`). This is responsible for determining the current mixnet session and phase, and the mixnodes to use in each session. It provides a function that validators can call to register a mixnode for the next session. The logic of this pallet is very similar to that of the `im-online` pallet. - A service (`client/mixnet`). This implements the core mixnet logic, building on the `mixnet` crate. The service communicates with other nodes using notifications sent over the "mixnet" protocol. - An RPC interface. This currently only supports sending transactions over the mixnet. --------- Co-authored-by: David Emett <dave@sp4m.net> Co-authored-by: Javier Viola <javier@parity.io>
112 lines
3.7 KiB
Rust
112 lines
3.7 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
use futures::{future::FusedFuture, FutureExt};
|
|
use futures_timer::Delay;
|
|
use std::{
|
|
future::Future,
|
|
pin::Pin,
|
|
task::{Context, Poll, Waker},
|
|
time::Duration,
|
|
};
|
|
|
|
enum Inner {
|
|
Infinite {
|
|
/// Waker from the most recent `poll` call. If `None`, either `poll` has not been called
|
|
/// yet, we returned `Poll::Ready` from the last call, or the waker is attached to `delay`.
|
|
waker: Option<Waker>,
|
|
delay: Option<Delay>,
|
|
},
|
|
Finite(Delay),
|
|
}
|
|
|
|
/// Like [`Delay`] but the duration can be infinite (in which case the future will never fire).
|
|
/// Unlike [`Delay`], implements [`FusedFuture`], with [`is_terminated`](Self::is_terminated)
|
|
/// returning `true` when the delay is infinite. As with [`Delay`], once [`poll`](Self::poll)
|
|
/// returns [`Poll::Ready`], it will continue to do so until [`reset`](Self::reset) is called.
|
|
pub struct MaybeInfDelay(Inner);
|
|
|
|
impl MaybeInfDelay {
|
|
/// Create a new `MaybeInfDelay` future. If `duration` is [`Some`], the future will fire after
|
|
/// the given duration has elapsed. If `duration` is [`None`], the future will "never" fire
|
|
/// (although see [`reset`](Self::reset)).
|
|
pub fn new(duration: Option<Duration>) -> Self {
|
|
match duration {
|
|
Some(duration) => Self(Inner::Finite(Delay::new(duration))),
|
|
None => Self(Inner::Infinite { waker: None, delay: None }),
|
|
}
|
|
}
|
|
|
|
/// Reset the timer. `duration` is handled just like in [`new`](Self::new). Note that while
|
|
/// this is similar to `std::mem::replace(&mut self, MaybeInfDelay::new(duration))`, with
|
|
/// `replace` you would have to manually ensure [`poll`](Self::poll) was called again; with
|
|
/// `reset` this is not necessary.
|
|
pub fn reset(&mut self, duration: Option<Duration>) {
|
|
match duration {
|
|
Some(duration) => match &mut self.0 {
|
|
Inner::Infinite { waker, delay } => {
|
|
let mut delay = match delay.take() {
|
|
Some(mut delay) => {
|
|
delay.reset(duration);
|
|
delay
|
|
},
|
|
None => Delay::new(duration),
|
|
};
|
|
if let Some(waker) = waker.take() {
|
|
let mut cx = Context::from_waker(&waker);
|
|
match delay.poll_unpin(&mut cx) {
|
|
Poll::Pending => (), // Waker attached to delay
|
|
Poll::Ready(_) => waker.wake(),
|
|
}
|
|
}
|
|
self.0 = Inner::Finite(delay);
|
|
},
|
|
Inner::Finite(delay) => delay.reset(duration),
|
|
},
|
|
None =>
|
|
self.0 = match std::mem::replace(
|
|
&mut self.0,
|
|
Inner::Infinite { waker: None, delay: None },
|
|
) {
|
|
Inner::Finite(delay) => Inner::Infinite { waker: None, delay: Some(delay) },
|
|
infinite => infinite,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Future for MaybeInfDelay {
|
|
type Output = ();
|
|
|
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
match &mut self.0 {
|
|
Inner::Infinite { waker, .. } => {
|
|
*waker = Some(cx.waker().clone());
|
|
Poll::Pending
|
|
},
|
|
Inner::Finite(delay) => delay.poll_unpin(cx),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl FusedFuture for MaybeInfDelay {
|
|
fn is_terminated(&self) -> bool {
|
|
matches!(self.0, Inner::Infinite { .. })
|
|
}
|
|
}
|