diff --git a/polkadot/node/core/prospective-parachains/src/fragment_tree.rs b/polkadot/node/core/prospective-parachains/src/fragment_tree.rs
index 292e4ebe5282b4344853ca5f3247caf1d9af6cc7..f7b97f0782739a10926cd252e9c7b4184f93db93 100644
--- a/polkadot/node/core/prospective-parachains/src/fragment_tree.rs
+++ b/polkadot/node/core/prospective-parachains/src/fragment_tree.rs
@@ -202,7 +202,10 @@ impl CandidateStorage {
 	/// Note that an existing candidate has been backed.
 	pub fn mark_backed(&mut self, candidate_hash: &CandidateHash) {
 		if let Some(entry) = self.by_candidate_hash.get_mut(candidate_hash) {
+			gum::trace!(target: LOG_TARGET, ?candidate_hash, "Candidate marked as backed");
 			entry.state = CandidateState::Backed;
+		} else {
+			gum::trace!(target: LOG_TARGET, ?candidate_hash, "Candidate not found while marking as backed");
 		}
 	}
 
diff --git a/polkadot/node/core/prospective-parachains/src/lib.rs b/polkadot/node/core/prospective-parachains/src/lib.rs
index dabcfb80e02ee7943885888aef183a327579e3bd..aba3d092a4182c55ba32a1df5650277b5adbbec2 100644
--- a/polkadot/node/core/prospective-parachains/src/lib.rs
+++ b/polkadot/node/core/prospective-parachains/src/lib.rs
@@ -607,6 +607,14 @@ fn answer_get_backable_candidate(
 	let Some(child_hash) =
 		tree.select_child(&required_path, |candidate| storage.is_backed(candidate))
 	else {
+		gum::trace!(
+			target: LOG_TARGET,
+			?required_path,
+			para_id = ?para,
+			%relay_parent,
+			"Could not find any backable candidate",
+		);
+
 		let _ = tx.send(None);
 		return
 	};
@@ -621,6 +629,14 @@ fn answer_get_backable_candidate(
 		return
 	};
 
+	gum::trace!(
+		target: LOG_TARGET,
+		?relay_parent,
+		candidate_hash = ?child_hash,
+		?candidate_relay_parent,
+		"Found backable candidate",
+	);
+
 	let _ = tx.send(Some((child_hash, candidate_relay_parent)));
 }
 
diff --git a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs
index 5e460f18903b7f387772bc847a9699ea2fd085d3..22b44ddd1dc359620b199118bebf0bb83b69dada 100644
--- a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs
+++ b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs
@@ -22,6 +22,7 @@
 
 #![allow(missing_docs)]
 
+use futures::channel::oneshot;
 use polkadot_cli::{
 	service::{
 		AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs,
@@ -30,7 +31,6 @@ use polkadot_cli::{
 	},
 	validator_overseer_builder, Cli,
 };
-use polkadot_node_core_candidate_validation::find_validation_data;
 use polkadot_node_primitives::{AvailableData, BlockData, PoV};
 use polkadot_node_subsystem_types::DefaultSubsystemClient;
 use polkadot_primitives::{CandidateDescriptor, CandidateReceipt};
@@ -82,7 +82,7 @@ where
 					CandidateBackingMessage::Second(
 						relay_parent,
 						ref candidate,
-						ref _validation_data,
+						ref validation_data,
 						ref _pov,
 					),
 			} => {
@@ -112,6 +112,7 @@ where
 					let (sender, receiver) = std::sync::mpsc::channel();
 					let mut new_sender = subsystem_sender.clone();
 					let _candidate = candidate.clone();
+					let validation_data = validation_data.clone();
 					self.spawner.spawn_blocking(
 						"malus-get-validation-data",
 						Some("malus"),
@@ -124,22 +125,51 @@ where
 								.unwrap()
 								.len();
 							gum::trace!(target: MALUS, "Validators {}", n_validators);
-							match find_validation_data(&mut new_sender, &_candidate.descriptor())
-								.await
-							{
-								Ok(Some((validation_data, validation_code))) => {
-									sender
-										.send(Some((
-											validation_data,
-											validation_code,
-											n_validators,
-										)))
-										.expect("channel is still open");
-								},
-								_ => {
-									sender.send(None).expect("channel is still open");
-								},
-							}
+
+							let validation_code = {
+								let validation_code_hash =
+									_candidate.descriptor().validation_code_hash;
+								let (tx, rx) = oneshot::channel();
+								new_sender
+									.send_message(RuntimeApiMessage::Request(
+										relay_parent,
+										RuntimeApiRequest::ValidationCodeByHash(
+											validation_code_hash,
+											tx,
+										),
+									))
+									.await;
+
+								let code = rx.await.expect("Querying the RuntimeApi should work");
+								match code {
+									Err(e) => {
+										gum::error!(
+											target: MALUS,
+											?validation_code_hash,
+											error = %e,
+											"Failed to fetch validation code",
+										);
+
+										sender.send(None).expect("channel is still open");
+										return
+									},
+									Ok(None) => {
+										gum::debug!(
+											target: MALUS,
+											?validation_code_hash,
+											"Could not find validation code on chain",
+										);
+
+										sender.send(None).expect("channel is still open");
+										return
+									},
+									Ok(Some(c)) => c,
+								}
+							};
+
+							sender
+								.send(Some((validation_data, validation_code, n_validators)))
+								.expect("channel is still open");
 						}),
 					);
 
diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs
index 1b4a97290c6a71ea17b82cfc728323c60b980e87..af241d1cbc558c849bbf533dd644848b20fa4491 100644
--- a/polkadot/node/service/src/chain_spec.rs
+++ b/polkadot/node/service/src/chain_spec.rs
@@ -120,7 +120,7 @@ pub fn wococo_config() -> Result<RococoChainSpec, String> {
 fn default_parachains_host_configuration(
 ) -> polkadot_runtime_parachains::configuration::HostConfiguration<polkadot_primitives::BlockNumber>
 {
-	use polkadot_primitives::{MAX_CODE_SIZE, MAX_POV_SIZE};
+	use polkadot_primitives::{AsyncBackingParams, MAX_CODE_SIZE, MAX_POV_SIZE};
 
 	polkadot_runtime_parachains::configuration::HostConfiguration {
 		validation_upgrade_cooldown: 2u32,
@@ -151,6 +151,11 @@ fn default_parachains_host_configuration(
 		relay_vrf_modulo_samples: 2,
 		zeroth_delay_tranche_width: 0,
 		minimum_validation_upgrade_delay: 5,
+		scheduling_lookahead: 2,
+		async_backing_params: AsyncBackingParams {
+			max_candidate_depth: 3,
+			allowed_ancestry_len: 2,
+		},
 		..Default::default()
 	}
 }