variant-a.rs 3.69 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot 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.

// Polkadot 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 Polkadot.  If not, see <http://www.gnu.org/licenses/>.

//! A malicious overseer.
//!
//! An example on how to use the `OverseerGen` pattern to
//! instantiate a modified subsystem implementation
Denis_P's avatar
Denis_P committed
21
//! for usage with `simnet`/Gurke.
22
23
24
25
26
27
28
29

#![allow(missing_docs)]

use color_eyre::eyre;
use polkadot_cli::{
	create_default_subsystems,
	service::{
		AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer,
30
		OverseerGen, OverseerGenArgs, ParachainHost, ProvideRuntimeApi, SpawnNamed,
31
32
33
34
35
36
	},
	Cli,
};

// Import extra types relevant to the particular
// subsystem.
37
use polkadot_node_core_candidate_validation::CandidateValidationSubsystem;
38
39
40
41
42
use polkadot_node_subsystem::{
	messages::{AllMessages, CandidateValidationMessage},
	overseer::{self, OverseerHandle},
	FromOverseer,
};
43
44
45

use malus::*;

46
// Filter wrapping related types.
Shawn Tabrizi's avatar
Shawn Tabrizi committed
47
48
49
50
use std::sync::{
	atomic::{AtomicUsize, Ordering},
	Arc,
};
51
52
53
54
55
56
57

use structopt::StructOpt;

/// Silly example, just drop every second outgoing message.
#[derive(Clone, Default, Debug)]
struct Skippy(Arc<AtomicUsize>);

58
59
60
61
62
63
64
impl<Sender> MessageInterceptor<Sender> for Skippy
where
	Sender: overseer::SubsystemSender<AllMessages>
		+ overseer::SubsystemSender<CandidateValidationMessage>
		+ Clone
		+ 'static,
{
65
66
	type Message = CandidateValidationMessage;

67
68
69
70
71
	fn intercept_incoming(
		&self,
		_sender: &mut Sender,
		msg: FromOverseer<Self::Message>,
	) -> Option<FromOverseer<Self::Message>> {
72
73
74
75
76
77
		if self.0.fetch_add(1, Ordering::Relaxed) % 2 == 0 {
			Some(msg)
		} else {
			None
		}
	}
78
	fn intercept_outgoing(&self, msg: AllMessages) -> Option<AllMessages> {
79
80
81
82
83
84
85
86
87
88
89
		Some(msg)
	}
}

/// Generates an overseer that exposes bad behavior.
struct BehaveMaleficient;

impl OverseerGen for BehaveMaleficient {
	fn generate<'a, Spawner, RuntimeClient>(
		&self,
		args: OverseerGenArgs<'a, Spawner, RuntimeClient>,
Andronik Ordian's avatar
Andronik Ordian committed
90
	) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandle), Error>
91
92
93
94
95
96
97
98
99
100
101
102
103
	where
		RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
		RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
		Spawner: 'static + SpawnNamed + Clone + Unpin,
	{
		let spawner = args.spawner.clone();
		let leaves = args.leaves.clone();
		let runtime_client = args.runtime_client.clone();
		let registry = args.registry.clone();
		let candidate_validation_config = args.candidate_validation_config.clone();
		// modify the subsystem(s) as needed:
		let all_subsystems = create_default_subsystems(args)?.replace_candidate_validation(
			// create the filtered subsystem
104
			|orig: CandidateValidationSubsystem| {
105
				InterceptedSubsystem::new(
106
107
108
109
110
111
112
113
					CandidateValidationSubsystem::with_config(
						candidate_validation_config,
						orig.metrics,
						orig.pvf_metrics,
					),
					Skippy::default(),
				)
			},
114
115
116
117
118
119
120
121
122
123
124
125
126
127
		);

		Overseer::new(leaves, all_subsystems, registry, runtime_client, spawner)
			.map_err(|e| e.into())
	}
}

fn main() -> eyre::Result<()> {
	color_eyre::install()?;
	let cli = Cli::from_args();
	assert_matches::assert_matches!(cli.subcommand, None);
	polkadot_cli::run_node(cli, BehaveMaleficient)?;
	Ok(())
}