Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 2d19780

Browse files
ordianrphmeier
andauthored
enable disputes (#3478)
* initial integration and migration code * fix tests * fix counting test * assume the current version on missing file * use SelectRelayChain * remove duplicate metric * Update node/service/src/lib.rs Co-authored-by: Robert Habermeier <[email protected]> * remove ApprovalCheckingVotingRule * address my concern * never mode for StagnantCheckInterval * REVERTME: some logs * w00t * it's ugly but it works * Revert "REVERTME: some logs" This reverts commit e210505. * it's handle, not handler * fix a few typos Co-authored-by: Robert Habermeier <[email protected]>
1 parent 6dfdeab commit 2d19780

File tree

19 files changed

+405
-368
lines changed

19 files changed

+405
-368
lines changed

Diff for: Cargo.lock

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: node/core/chain-selection/src/lib.rs

+23-13
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use polkadot_node_subsystem::{
2828
use kvdb::KeyValueDB;
2929
use parity_scale_codec::Error as CodecError;
3030
use futures::channel::oneshot;
31+
use futures::future::Either;
3132
use futures::prelude::*;
3233

3334
use std::time::{UNIX_EPOCH, Duration,SystemTime};
@@ -244,7 +245,7 @@ impl Clock for SystemClock {
244245

245246
/// The interval, in seconds to check for stagnant blocks.
246247
#[derive(Debug, Clone)]
247-
pub struct StagnantCheckInterval(Duration);
248+
pub struct StagnantCheckInterval(Option<Duration>);
248249

249250
impl Default for StagnantCheckInterval {
250251
fn default() -> Self {
@@ -255,28 +256,37 @@ impl Default for StagnantCheckInterval {
255256
// between 2 validators is D + 5s.
256257
const DEFAULT_STAGNANT_CHECK_INTERVAL: Duration = Duration::from_secs(5);
257258

258-
StagnantCheckInterval(DEFAULT_STAGNANT_CHECK_INTERVAL)
259+
StagnantCheckInterval(Some(DEFAULT_STAGNANT_CHECK_INTERVAL))
259260
}
260261
}
261262

262263
impl StagnantCheckInterval {
263264
/// Create a new stagnant-check interval wrapping the given duration.
264265
pub fn new(interval: Duration) -> Self {
265-
StagnantCheckInterval(interval)
266+
StagnantCheckInterval(Some(interval))
266267
}
267268

268-
fn timeout_stream(&self) -> impl Stream<Item = ()> {
269-
let interval = self.0;
270-
let mut delay = futures_timer::Delay::new(interval);
269+
/// Create a `StagnantCheckInterval` which never triggers.
270+
pub fn never() -> Self {
271+
StagnantCheckInterval(None)
272+
}
271273

272-
futures::stream::poll_fn(move |cx| {
273-
let poll = delay.poll_unpin(cx);
274-
if poll.is_ready() {
275-
delay.reset(interval)
276-
}
274+
fn timeout_stream(&self) -> impl Stream<Item = ()> {
275+
match self.0 {
276+
Some(interval) => Either::Left({
277+
let mut delay = futures_timer::Delay::new(interval);
278+
279+
futures::stream::poll_fn(move |cx| {
280+
let poll = delay.poll_unpin(cx);
281+
if poll.is_ready() {
282+
delay.reset(interval)
283+
}
277284

278-
poll.map(Some)
279-
})
285+
poll.map(Some)
286+
})
287+
}),
288+
None => Either::Right(futures::stream::pending()),
289+
}
280290
}
281291
}
282292

Diff for: node/malus/src/variant-a.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use polkadot_cli::{
2727
create_default_subsystems,
2828
service::{
2929
AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer,
30-
OverseerGen, OverseerGenArgs, Handle, ParachainHost, ProvideRuntimeApi,
30+
OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, ProvideRuntimeApi,
3131
SpawnNamed,
3232
},
3333
Cli,
@@ -73,7 +73,7 @@ impl OverseerGen for BehaveMaleficient {
7373
fn generate<'a, Spawner, RuntimeClient>(
7474
&self,
7575
args: OverseerGenArgs<'a, Spawner, RuntimeClient>,
76-
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, Handle), Error>
76+
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandle), Error>
7777
where
7878
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
7979
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,

Diff for: node/overseer/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ client = { package = "sc-client-api", git = "https://github.com/paritytech/subst
1010
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
1111
futures = "0.3.15"
1212
futures-timer = "3.0.2"
13+
parking_lot = "0.11.1"
1314
polkadot-node-network-protocol = { path = "../network/protocol" }
1415
polkadot-node-primitives = { path = "../primitives" }
1516
polkadot-node-subsystem-types = { path = "../subsystem-types" }

Diff for: node/overseer/examples/minimal-example.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ fn main() {
174174
.replace_candidate_backing(Subsystem1)
175175
;
176176

177-
let (overseer, _handler) = Overseer::new(
177+
let (overseer, _handle) = Overseer::new(
178178
vec![],
179179
all_subsystems,
180180
None,

Diff for: node/overseer/overseer-gen/examples/dummy.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl SpawnNamed for DummySpawner{
123123
struct DummyCtx;
124124

125125
fn main() {
126-
let (overseer, _handler): (Xxx<_>, _) = Xxx::builder()
126+
let (overseer, _handle): (Xxx<_>, _) = Xxx::builder()
127127
.sub0(AwesomeSubSys::default())
128128
.plinkos(GoblinTower::default())
129129
.i_like_pi(::std::f64::consts::PI)

Diff for: node/overseer/src/lib.rs

+84-31
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ use futures::{
7373
Future, FutureExt, StreamExt,
7474
};
7575
use lru::LruCache;
76+
use parking_lot::RwLock;
7677

7778
use polkadot_primitives::v1::{Block, BlockId,BlockNumber, Hash, ParachainHost};
7879
use client::{BlockImportNotification, BlockchainEvents, FinalityNotification};
@@ -159,13 +160,24 @@ impl<Client> HeadSupportsParachains for Arc<Client> where
159160
}
160161

161162

162-
/// A handler used to communicate with the [`Overseer`].
163+
/// A handle used to communicate with the [`Overseer`].
163164
///
164165
/// [`Overseer`]: struct.Overseer.html
165166
#[derive(Clone)]
166-
pub struct Handle(pub OverseerHandle);
167+
pub enum Handle {
168+
/// Used only at initialization to break the cyclic dependency.
169+
// TODO: refactor in https://github.com/paritytech/polkadot/issues/3427
170+
Disconnected(Arc<RwLock<Option<OverseerHandle>>>),
171+
/// A handle to the overseer.
172+
Connected(OverseerHandle),
173+
}
167174

168175
impl Handle {
176+
/// Create a new disconnected [`Handle`].
177+
pub fn new_disconnected() -> Self {
178+
Self::Disconnected(Arc::new(RwLock::new(None)))
179+
}
180+
169181
/// Inform the `Overseer` that that some block was imported.
170182
pub async fn block_imported(&mut self, block: BlockInfo) {
171183
self.send_and_log_error(Event::BlockImported(block)).await
@@ -207,25 +219,59 @@ impl Handle {
207219

208220
/// Most basic operation, to stop a server.
209221
async fn send_and_log_error(&mut self, event: Event) {
210-
if self.0.send(event).await.is_err() {
211-
tracing::info!(target: LOG_TARGET, "Failed to send an event to Overseer");
222+
self.try_connect();
223+
if let Self::Connected(ref mut handle) = self {
224+
if handle.send(event).await.is_err() {
225+
tracing::info!(target: LOG_TARGET, "Failed to send an event to Overseer");
226+
}
227+
} else {
228+
tracing::warn!(target: LOG_TARGET, "Using a disconnected Handle to send to Overseer");
212229
}
213230
}
214231

215-
/// Whether the overseer handler is connected to an overseer.
216-
pub fn is_connected(&self) -> bool {
217-
true
232+
/// Whether the handle is disconnected.
233+
pub fn is_disconnected(&self) -> bool {
234+
match self {
235+
Self::Disconnected(ref x) => x.read().is_none(),
236+
_ => false,
237+
}
218238
}
219239

220-
/// Whether the handler is disconnected.
221-
pub fn is_disconnected(&self) -> bool {
222-
false
240+
/// Connect this handle and all disconnected clones of it to the overseer.
241+
pub fn connect_to_overseer(&mut self, handle: OverseerHandle) {
242+
match self {
243+
Self::Disconnected(ref mut x) => {
244+
let mut maybe_handle = x.write();
245+
if maybe_handle.is_none() {
246+
tracing::info!(target: LOG_TARGET, "🖇️ Connecting all Handles to Overseer");
247+
*maybe_handle = Some(handle);
248+
} else {
249+
tracing::warn!(
250+
target: LOG_TARGET,
251+
"Attempting to connect a clone of a connected Handle",
252+
);
253+
}
254+
},
255+
_ => {
256+
tracing::warn!(
257+
target: LOG_TARGET,
258+
"Attempting to connect an already connected Handle",
259+
);
260+
},
261+
}
223262
}
224263

225-
/// Using this handler, connect another handler to the same
226-
/// overseer, if any.
227-
pub fn connect_other(&self, other: &mut Handle) {
228-
*other = self.clone();
264+
/// Try upgrading from `Self::Disconnected` to `Self::Connected` state
265+
/// after calling `connect_to_overseer` on `self` or a clone of `self`.
266+
fn try_connect(&mut self) {
267+
if let Self::Disconnected(ref mut x) = self {
268+
let guard = x.write();
269+
if let Some(ref h) = *guard {
270+
let handle = h.clone();
271+
drop(guard);
272+
*self = Self::Connected(handle);
273+
}
274+
}
229275
}
230276
}
231277

@@ -301,7 +347,7 @@ pub enum ExternalRequest {
301347
/// import and finality notifications into the [`OverseerHandle`].
302348
pub async fn forward_events<P: BlockchainEvents<Block>>(
303349
client: Arc<P>,
304-
mut handler: Handle,
350+
mut handle: Handle,
305351
) {
306352
let mut finality = client.finality_notification_stream();
307353
let mut imports = client.import_notification_stream();
@@ -311,15 +357,15 @@ pub async fn forward_events<P: BlockchainEvents<Block>>(
311357
f = finality.next() => {
312358
match f {
313359
Some(block) => {
314-
handler.block_finalized(block.into()).await;
360+
handle.block_finalized(block.into()).await;
315361
}
316362
None => break,
317363
}
318364
},
319365
i = imports.next() => {
320366
match i {
321367
Some(block) => {
322-
handler.block_imported(block.into()).await;
368+
handle.block_imported(block.into()).await;
323369
}
324370
None => break,
325371
}
@@ -338,7 +384,6 @@ pub async fn forward_events<P: BlockchainEvents<Block>>(
338384
network=NetworkBridgeEvent<protocol_v1::ValidationProtocol>,
339385
)]
340386
pub struct Overseer<SupportsParachains> {
341-
342387
#[subsystem(no_dispatch, CandidateValidationMessage)]
343388
candidate_validation: CandidateValidation,
344389

@@ -390,16 +435,16 @@ pub struct Overseer<SupportsParachains> {
390435
#[subsystem(no_dispatch, GossipSupportMessage)]
391436
gossip_support: GossipSupport,
392437

393-
#[subsystem(no_dispatch, wip, DisputeCoordinatorMessage)]
394-
dipute_coordinator: DisputeCoordinator,
438+
#[subsystem(no_dispatch, DisputeCoordinatorMessage)]
439+
dispute_coordinator: DisputeCoordinator,
395440

396-
#[subsystem(no_dispatch, wip, DisputeParticipationMessage)]
441+
#[subsystem(no_dispatch, DisputeParticipationMessage)]
397442
dispute_participation: DisputeParticipation,
398443

399-
#[subsystem(no_dispatch, wip, DisputeDistributionMessage)]
400-
dipute_distribution: DisputeDistribution,
444+
#[subsystem(no_dispatch, DisputeDistributionMessage)]
445+
dispute_distribution: DisputeDistribution,
401446

402-
#[subsystem(no_dispatch, wip, ChainSelectionMessage)]
447+
#[subsystem(no_dispatch, ChainSelectionMessage)]
403448
chain_selection: ChainSelection,
404449

405450
/// External listeners waiting for a hash to be in the active-leave set.
@@ -436,7 +481,7 @@ where
436481
/// This returns the overseer along with an [`OverseerHandle`] which can
437482
/// be used to send messages from external parts of the codebase.
438483
///
439-
/// The [`OverseerHandler`] returned from this function is connected to
484+
/// The [`OverseerHandle`] returned from this function is connected to
440485
/// the returned [`Overseer`].
441486
///
442487
/// ```text
@@ -527,7 +572,7 @@ where
527572
/// let spawner = sp_core::testing::TaskExecutor::new();
528573
/// let all_subsystems = AllSubsystems::<()>::dummy()
529574
/// .replace_candidate_validation(ValidationSubsystem);
530-
/// let (overseer, _handler) = Overseer::new(
575+
/// let (overseer, _handle) = Overseer::new(
531576
/// vec![],
532577
/// all_subsystems,
533578
/// None,
@@ -549,13 +594,13 @@ where
549594
/// # });
550595
/// # }
551596
/// ```
552-
pub fn new<CV, CB, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS>(
597+
pub fn new<CV, CB, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS, DC, DP, DD, CS>(
553598
leaves: impl IntoIterator<Item = BlockInfo>,
554-
all_subsystems: AllSubsystems<CV, CB, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS>,
599+
all_subsystems: AllSubsystems<CV, CB, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS, DC, DP, DD, CS>,
555600
prometheus_registry: Option<&prometheus::Registry>,
556601
supports_parachains: SupportsParachains,
557602
s: S,
558-
) -> SubsystemResult<(Self, Handle)>
603+
) -> SubsystemResult<(Self, OverseerHandle)>
559604
where
560605
CV: Subsystem<OverseerSubsystemContext<CandidateValidationMessage>, SubsystemError> + Send,
561606
CB: Subsystem<OverseerSubsystemContext<CandidateBackingMessage>, SubsystemError> + Send,
@@ -574,11 +619,15 @@ where
574619
ApD: Subsystem<OverseerSubsystemContext<ApprovalDistributionMessage>, SubsystemError> + Send,
575620
ApV: Subsystem<OverseerSubsystemContext<ApprovalVotingMessage>, SubsystemError> + Send,
576621
GS: Subsystem<OverseerSubsystemContext<GossipSupportMessage>, SubsystemError> + Send,
622+
DC: Subsystem<OverseerSubsystemContext<DisputeCoordinatorMessage>, SubsystemError> + Send,
623+
DP: Subsystem<OverseerSubsystemContext<DisputeParticipationMessage>, SubsystemError> + Send,
624+
DD: Subsystem<OverseerSubsystemContext<DisputeDistributionMessage>, SubsystemError> + Send,
625+
CS: Subsystem<OverseerSubsystemContext<ChainSelectionMessage>, SubsystemError> + Send,
577626
S: SpawnNamed,
578627
{
579628
let metrics: Metrics = <Metrics as MetricsTrait>::register(prometheus_registry)?;
580629

581-
let (mut overseer, handler) = Self::builder()
630+
let (mut overseer, handle) = Self::builder()
582631
.candidate_validation(all_subsystems.candidate_validation)
583632
.candidate_backing(all_subsystems.candidate_backing)
584633
.statement_distribution(all_subsystems.statement_distribution)
@@ -596,6 +645,10 @@ where
596645
.approval_distribution(all_subsystems.approval_distribution)
597646
.approval_voting(all_subsystems.approval_voting)
598647
.gossip_support(all_subsystems.gossip_support)
648+
.dispute_coordinator(all_subsystems.dispute_coordinator)
649+
.dispute_participation(all_subsystems.dispute_participation)
650+
.dispute_distribution(all_subsystems.dispute_distribution)
651+
.chain_selection(all_subsystems.chain_selection)
599652
.leaves(Vec::from_iter(
600653
leaves.into_iter().map(|BlockInfo { hash, parent_hash: _, number }| (hash, number))
601654
))
@@ -647,7 +700,7 @@ where
647700
overseer.spawner().spawn("metrics_metronome", Box::pin(metronome));
648701
}
649702

650-
Ok((overseer, Handle(handler)))
703+
Ok((overseer, handle))
651704
}
652705

653706
/// Stop the overseer.

0 commit comments

Comments
 (0)