diff --git a/cli/src/command.rs b/cli/src/command.rs index babfa1c3ce5e..a7ab8f67aad7 100644 --- a/cli/src/command.rs +++ b/cli/src/command.rs @@ -267,14 +267,21 @@ fn host_perf_check() -> Result<()> { /// Launch a node, accepting arguments just like a regular node, /// accepts an alternative overseer generator, to adjust behavior /// for integration tests as needed. +/// `malus_finality_delay` restrict finality votes of this node +/// to be at most `best_block - malus_finality_delay` height. #[cfg(feature = "malus")] -pub fn run_node(run: Cli, overseer_gen: impl service::OverseerGen) -> Result<()> { - run_node_inner(run, overseer_gen, |_logger_builder, _config| {}) +pub fn run_node( + run: Cli, + overseer_gen: impl service::OverseerGen, + malus_finality_delay: Option, +) -> Result<()> { + run_node_inner(run, overseer_gen, malus_finality_delay, |_logger_builder, _config| {}) } fn run_node_inner( cli: Cli, overseer_gen: impl service::OverseerGen, + maybe_malus_finality_delay: Option, logger_hook: F, ) -> Result<()> where @@ -340,6 +347,7 @@ where false, overseer_gen, cli.run.overseer_channel_capacity_override, + maybe_malus_finality_delay, hwbench, ) .map(|full| full.task_manager) @@ -377,7 +385,12 @@ pub fn run() -> Result<()> { } match &cli.subcommand { - None => run_node_inner(cli, service::RealOverseerGen, polkadot_node_metrics::logger_hook()), + None => run_node_inner( + cli, + service::RealOverseerGen, + None, + polkadot_node_metrics::logger_hook(), + ), Some(Subcommand::BuildSpec(cmd)) => { let runner = cli.create_runner(cmd)?; Ok(runner.sync_run(|config| cmd.run(config.chain_spec, config.network))?) diff --git a/node/malus/src/malus.rs b/node/malus/src/malus.rs index 88b3f8130abd..dd9f1377f14a 100644 --- a/node/malus/src/malus.rs +++ b/node/malus/src/malus.rs @@ -53,6 +53,8 @@ enum NemesisVariant { struct MalusCli { #[clap(subcommand)] pub variant: NemesisVariant, + /// Sets the minimum delay between the best and finalized block. + pub finality_delay: Option, } fn run_cmd(run: RunCmd) -> Cli { @@ -62,14 +64,16 @@ fn run_cmd(run: RunCmd) -> Cli { impl MalusCli { /// Launch a malus node. fn launch(self) -> eyre::Result<()> { + let finality_delay = self.finality_delay; match self.variant { NemesisVariant::BackGarbageCandidate(cmd) => - polkadot_cli::run_node(run_cmd(cmd), BackGarbageCandidate)?, + polkadot_cli::run_node(run_cmd(cmd), BackGarbageCandidate, finality_delay)?, NemesisVariant::SuggestGarbageCandidate(cmd) => - polkadot_cli::run_node(run_cmd(cmd), BackGarbageCandidateWrapper)?, + polkadot_cli::run_node(run_cmd(cmd), BackGarbageCandidateWrapper, finality_delay)?, NemesisVariant::DisputeAncestor(opts) => polkadot_cli::run_node( run_cmd(opts.clone().cmd), DisputeValidCandidates::new(opts), + finality_delay, )?, NemesisVariant::PvfPrepareWorker(cmd) => { #[cfg(target_os = "android")] diff --git a/node/service/src/lib.rs b/node/service/src/lib.rs index 0f131280b51d..f199bbdbc077 100644 --- a/node/service/src/lib.rs +++ b/node/service/src/lib.rs @@ -725,6 +725,7 @@ pub fn new_full( overseer_enable_anyways: bool, overseer_gen: OverseerGenerator, overseer_message_channel_capacity_override: Option, + _malus_finality_delay: Option, hwbench: Option, ) -> Result>>, Error> where @@ -1222,7 +1223,15 @@ where // add a custom voting rule to temporarily stop voting for new blocks // after the given pause block is finalized and restarting after the // given delay. - let builder = grandpa::VotingRulesBuilder::default(); + let mut builder = grandpa::VotingRulesBuilder::default(); + + #[cfg(not(feature = "malus"))] + let _malus_finality_delay = None; + + if let Some(delay) = _malus_finality_delay { + info!(?delay, "Enabling malus finality delay",); + builder = builder.add(grandpa::BeforeBestBlockBy(delay)); + }; let voting_rule = match grandpa_pause { Some((block, delay)) => { @@ -1350,6 +1359,7 @@ pub fn build_full( overseer_enable_anyways: bool, overseer_gen: impl OverseerGen, overseer_message_channel_override: Option, + malus_finality_delay: Option, hwbench: Option, ) -> Result, Error> { #[cfg(feature = "rococo-native")] @@ -1368,6 +1378,7 @@ pub fn build_full( overseer_enable_anyways, overseer_gen, overseer_message_channel_override, + malus_finality_delay, hwbench, ) .map(|full| full.with_client(Client::Rococo)) @@ -1386,6 +1397,7 @@ pub fn build_full( overseer_enable_anyways, overseer_gen, overseer_message_channel_override, + malus_finality_delay, hwbench, ) .map(|full| full.with_client(Client::Kusama)) @@ -1404,6 +1416,7 @@ pub fn build_full( overseer_enable_anyways, overseer_gen, overseer_message_channel_override, + malus_finality_delay, hwbench, ) .map(|full| full.with_client(Client::Westend)) @@ -1425,6 +1438,7 @@ pub fn build_full( gum::warn!("Channel capacity should _never_ be tampered with on polkadot!"); capacity }), + malus_finality_delay, hwbench, ) .map(|full| full.with_client(Client::Polkadot)) diff --git a/node/test/service/src/lib.rs b/node/test/service/src/lib.rs index 90e311b910da..b9b99f28d1b9 100644 --- a/node/test/service/src/lib.rs +++ b/node/test/service/src/lib.rs @@ -102,6 +102,7 @@ pub fn new_full( polkadot_service::RealOverseerGen, None, None, + None, ) } diff --git a/parachain/test-parachains/adder/collator/src/main.rs b/parachain/test-parachains/adder/collator/src/main.rs index 3a0b7805c643..e0845f68720d 100644 --- a/parachain/test-parachains/adder/collator/src/main.rs +++ b/parachain/test-parachains/adder/collator/src/main.rs @@ -67,6 +67,7 @@ fn main() -> Result<()> { polkadot_service::RealOverseerGen, None, None, + None, ) .map_err(|e| e.to_string())?; let mut overseer_handle = full_node diff --git a/parachain/test-parachains/undying/collator/src/main.rs b/parachain/test-parachains/undying/collator/src/main.rs index 2f7d683400ad..e352235679ce 100644 --- a/parachain/test-parachains/undying/collator/src/main.rs +++ b/parachain/test-parachains/undying/collator/src/main.rs @@ -67,6 +67,7 @@ fn main() -> Result<()> { polkadot_service::RealOverseerGen, None, None, + None, ) .map_err(|e| e.to_string())?; let mut overseer_handle = full_node