ronantakizawa/codereview-bench huggingface dataset:
Repository: paritytech/substrate
File: primitives/core/src/lib.rs (Rust)

Code before:

/// A trait for querying a single value from a type.
///
/// It is not required that the value is constant.
pub trait Get<T> {
	/// Return the current value.
	fn get() -> T;
}

impl<T: Default> Get<T> for () {
	fn get() -> T {
		T::default()
	}
}

/// Implement Get by returning Default for any type that implements Default.
pub struct GetDefault;
impl<T: Default> Get<T> for GetDefault {
	fn get() -> T {
		T::default()
	}
}

/// A simple wrapper to turn a `Get<u16>` to `Get<u32>`.
pub struct GetU16ToU32<T>(core::marker::PhantomData<T>);
impl<T: Get<u16>> Get<u32> for GetU16ToU32<T> {
	fn get() -> u32 {
		T::get().into()
	}
}

macro_rules! impl_const_get {
	($name:ident, $t:ty) => {
		#[doc = "Const getter for a basic type."]
		#[derive($crate::RuntimeDebug)]
		pub struct $name<const T: $t>;
		impl<const T: $t> Get<$t> for $name<T> {
			fn get() -> $t {
				T
			}
		}
		impl<const T: $t> Get<Option<$t>> for $name<T> {
			fn get() -> Option<$t> {
				Some(T)
			}
		}
		impl<const T: $t> TypedGet for $name<T> {
			type Type = $t;
			fn get() -> $t {
				T
			}

Review comment (suggestion):
Do you know why `MaxSignatories` is `u16` instead of `u32`?  
Since we have the MEL bound now, i think it can be changed.

Code after:

/// A trait for querying a single value from a type.
///
/// It is not required that the value is constant.
pub trait Get<T> {
	/// Return the current value.
	fn get() -> T;
}

impl<T: Default> Get<T> for () {
	fn get() -> T {
		T::default()
	}
}

/// Implement Get by returning Default for any type that implements Default.
pub struct GetDefault;
impl<T: Default> Get<T> for GetDefault {
	fn get() -> T {
		T::default()
	}
}

macro_rules! impl_const_get {
	($name:ident, $t:ty) => {
		#[doc = "Const getter for a basic type."]
		#[derive($crate::RuntimeDebug)]
		pub struct $name<const T: $t>;
		impl<const T: $t> Get<$t> for $name<T> {
			fn get() -> $t {
				T
			}
		}
		impl<const T: $t> Get<Option<$t>> for $name<T> {
			fn get() -> Option<$t> {
				Some(T)
			}
		}
		impl<const T: $t> TypedGet for $name<T> {
			type Type = $t;
			fn get() -> $t {
				T
			}
		}
	};
}

impl_const_get!(ConstBool, bool);
impl_const_get!(ConstU8, u8);
impl_const_get!(ConstU16, u16);
impl_const_get!(ConstU32, u32);
Repository: paritytech/substrate
File: client/cli/src/commands/export_state_cmd.rs (Rust)

Code before:
	#[clap(value_name = "HASH or NUMBER")]
	pub input: Option<BlockNumberOrHash>,

	#[allow(missing_docs)]
	#[clap(flatten)]
	pub shared_params: SharedParams,

	#[allow(missing_docs)]
	#[clap(flatten)]
	pub pruning_params: PruningParams,

	#[allow(missing_docs)]
	#[clap(flatten)]
	pub database_params: DatabaseParams,
}

impl ExportStateCmd {
	/// Run the `export-state` command
	pub async fn run<B, BA, C>(
		&self,
		client: Arc<C>,
		mut input_spec: Box<dyn sc_service::ChainSpec>,
	) -> error::Result<()>
	where
		B: BlockT,
		C: UsageProvider<B> + StorageProvider<B, BA> + HeaderBackend<B>,
		BA: sc_client_api::backend::Backend<B>,
		B::Hash: FromStr,
		<B::Hash as FromStr>::Err: Debug,
		<<B::Header as HeaderT>::Number as FromStr>::Err: Debug,
	{
		info!("Exporting raw state...");
		let block_id = self.input.as_ref().map(|b| b.parse()).transpose()?;
		let raw_state = sc_service::chain_ops::export_raw_state(client, block_id)?;
		input_spec.set_storage(raw_state);

		info!("Generating new chain spec...");
		let json = sc_service::chain_ops::build_spec(&*input_spec, true)?;
		if std::io::stdout().write_all(json.as_bytes()).is_err() {
			let _ = std::io::stderr().write_all(b"Error writing to stdout\n");
		}
		Ok(())
	}
}

impl CliConfiguration for ExportStateCmd {
	fn shared_params(&self) -> &SharedParams {
		&self.shared_params
	}

	fn pruning_params(&self) -> Option<&PruningParams> {

Review comment (suggestion):
```suggestion
		C: UsageProvider<B> + StorageProvider<B, BA>,
```

Code after:
	#[arg(value_name = "HASH or NUMBER")]
	pub input: Option<BlockNumberOrHash>,

	#[allow(missing_docs)]
	#[clap(flatten)]
	pub shared_params: SharedParams,

	#[allow(missing_docs)]
	#[clap(flatten)]
	pub pruning_params: PruningParams,

	#[allow(missing_docs)]
	#[clap(flatten)]
	pub database_params: DatabaseParams,
}

impl ExportStateCmd {
	/// Run the `export-state` command
	pub async fn run<B, BA, C>(
		&self,
		client: Arc<C>,
		mut input_spec: Box<dyn sc_service::ChainSpec>,
	) -> error::Result<()>
	where
		B: BlockT,
		C: UsageProvider<B> + StorageProvider<B, BA> + HeaderBackend<B>,
		BA: sc_client_api::backend::Backend<B>,
		B::Hash: FromStr,
		<B::Hash as FromStr>::Err: Debug,
		<<B::Header as HeaderT>::Number as FromStr>::Err: Debug,
	{
		info!("Exporting raw state...");
		let block_id = self.input.as_ref().map(|b| b.parse()).transpose()?;
		let hash = match block_id {
			Some(id) => client.expect_block_hash_from_id(&id)?,
			None => client.usage_info().chain.best_hash,
		};
		let raw_state = sc_service::chain_ops::export_raw_state(client, &hash)?;
		input_spec.set_storage(raw_state);

		info!("Generating new chain spec...");
		let json = sc_service::chain_ops::build_spec(&*input_spec, true)?;
		if std::io::stdout().write_all(json.as_bytes()).is_err() {
			let _ = std::io::stderr().write_all(b"Error writing to stdout\n");
		}
		Ok(())
	}
}

impl CliConfiguration for ExportStateCmd {
	fn shared_params(&self) -> &SharedParams {
Repository: paritytech/substrate
File: client/service/test/src/client/mod.rs (Rust)

Code before:

	let res: Vec<_> = client
		.child_storage_keys_iter(&block_hash, child_info.clone(), Some(&child_prefix), None)
		.unwrap()
		.map(|x| x.0)
		.collect();
	assert_eq!(res, [b"second".to_vec()]);

	let res: Vec<_> = client
		.child_storage_keys_iter(
			&block_hash,
			child_info,
			None,
			Some(&StorageKey(b"second".to_vec())),
		)
		.unwrap()
		.map(|x| x.0)
		.collect();
	assert_eq!(res, [b"third".to_vec()]);
}

#[test]
fn storage_keys_iter_works() {
	let client = substrate_test_runtime_client::new();

	let block_hash = client.block_hash_from_id(&BlockId::Number(0)).unwrap().unwrap();

	let prefix = StorageKey(array_bytes::hex2bytes_unchecked(""));

	let res: Vec<_> = client
		.storage_keys_iter(&block_hash, Some(&prefix), None)
		.unwrap()
		.take(9)
		.map(|x| array_bytes::bytes2hex("", &x.0))
		.collect();
	assert_eq!(
		res,
		[
			"00c232cf4e70a5e343317016dc805bf80a6a8cd8ad39958d56f99891b07851e0",
			"085b2407916e53a86efeb8b72dbe338c4b341dab135252f96b6ed8022209b6cb",
			"0befda6e1ca4ef40219d588a727f1271",
			"1a560ecfd2a62c2b8521ef149d0804eb621050e3988ed97dca55f0d7c3e6aa34",
			"1d66850d32002979d67dd29dc583af5b2ae2a1f71c1f35ad90fff122be7a3824",
			"237498b98d8803334286e9f0483ef513098dd3c1c22ca21c4dc155b4ef6cc204",
			"26aa394eea5630e07c48ae0c9558cef75e0621c4869aa60c02be9adcc98a0d1d",
			"29b9db10ec5bf7907d8f74b5e60aa8140c4fbdd8127a1ee5600cb98e5ec01729",
			"3a636f6465",
		]
	);

	let res: Vec<_> = client

Review comment (suggestion):
```suggestion
	let block_hash = client.info().best_hash;
```

Code after:

	let res: Vec<_> = client
		.child_storage_keys_iter(&block_hash, child_info.clone(), Some(&child_prefix), None)
		.unwrap()
		.map(|x| x.0)
		.collect();
	assert_eq!(res, [b"second".to_vec()]);

	let res: Vec<_> = client
		.child_storage_keys_iter(
			&block_hash,
			child_info,
			None,
			Some(&StorageKey(b"second".to_vec())),
		)
		.unwrap()
		.map(|x| x.0)
		.collect();
	assert_eq!(res, [b"third".to_vec()]);
}

#[test]
fn storage_keys_iter_works() {
	let client = substrate_test_runtime_client::new();

	let block_hash = client.info().best_hash;

	let prefix = StorageKey(array_bytes::hex2bytes_unchecked(""));

	let res: Vec<_> = client
		.storage_keys_iter(&block_hash, Some(&prefix), None)
		.unwrap()
		.take(9)
		.map(|x| array_bytes::bytes2hex("", &x.0))
		.collect();
	assert_eq!(
		res,
		[
			"00c232cf4e70a5e343317016dc805bf80a6a8cd8ad39958d56f99891b07851e0",
			"085b2407916e53a86efeb8b72dbe338c4b341dab135252f96b6ed8022209b6cb",
			"0befda6e1ca4ef40219d588a727f1271",
			"1a560ecfd2a62c2b8521ef149d0804eb621050e3988ed97dca55f0d7c3e6aa34",
			"1d66850d32002979d67dd29dc583af5b2ae2a1f71c1f35ad90fff122be7a3824",
			"237498b98d8803334286e9f0483ef513098dd3c1c22ca21c4dc155b4ef6cc204",
			"26aa394eea5630e07c48ae0c9558cef75e0621c4869aa60c02be9adcc98a0d1d",
			"29b9db10ec5bf7907d8f74b5e60aa8140c4fbdd8127a1ee5600cb98e5ec01729",
			"3a636f6465",
		]
	);

	let res: Vec<_> = client
Repository: paritytech/substrate
File: client/db/src/lib.rs (Rust)

Code before:
		update: StorageCollection,
		child_update: ChildStorageCollection,
	) -> ClientResult<()> {
		self.storage_updates = update;
		self.child_storage_updates = child_update;
		Ok(())
	}

	fn update_offchain_storage(
		&mut self,
		offchain_update: OffchainChangesCollection,
	) -> ClientResult<()> {
		self.offchain_storage_updates = offchain_update;
		Ok(())
	}

	fn mark_finalized(
		&mut self,
		block: &Block::Hash,
		justification: Option<Justification>,
	) -> ClientResult<()> {
		self.finalized_blocks.push((*block, justification));
		Ok(())
	}

	fn mark_head(&mut self, block: &Block::Hash) -> ClientResult<()> {
		assert!(self.set_head.is_none(), "Only one set head per operation is allowed");
		self.set_head = Some(*block);
		Ok(())
	}

	fn update_transaction_index(&mut self, index_ops: Vec<IndexOperation>) -> ClientResult<()> {
		self.index_ops = index_ops;
		Ok(())
	}
}

struct StorageDb<Block: BlockT> {
	pub db: Arc<dyn Database<DbHash>>,
	pub state_db: StateDb<Block::Hash, Vec<u8>, StateMetaDb>,
	prefix_keys: bool,
}

impl<Block: BlockT> sp_state_machine::Storage<HashFor<Block>> for StorageDb<Block> {
	fn get(&self, key: &Block::Hash, prefix: Prefix) -> Result<Option<DBValue>, String> {
		if self.prefix_keys {
			let key = prefixed_key::<HashFor<Block>>(key, prefix);
			self.state_db.get(&key, self)
		} else {
			self.state_db.get(key.as_ref(), self)
		}

Review comment (suggestion):
```suggestion
	fn mark_head(&mut self, hash: &Block::Hash) -> ClientResult<()> {
```

Code after:
		update: StorageCollection,
		child_update: ChildStorageCollection,
	) -> ClientResult<()> {
		self.storage_updates = update;
		self.child_storage_updates = child_update;
		Ok(())
	}

	fn update_offchain_storage(
		&mut self,
		offchain_update: OffchainChangesCollection,
	) -> ClientResult<()> {
		self.offchain_storage_updates = offchain_update;
		Ok(())
	}

	fn mark_finalized(
		&mut self,
		block: &Block::Hash,
		justification: Option<Justification>,
	) -> ClientResult<()> {
		self.finalized_blocks.push((*block, justification));
		Ok(())
	}

	fn mark_head(&mut self, hash: &Block::Hash) -> ClientResult<()> {
		assert!(self.set_head.is_none(), "Only one set head per operation is allowed");
		self.set_head = Some(*hash);
		Ok(())
	}

	fn update_transaction_index(&mut self, index_ops: Vec<IndexOperation>) -> ClientResult<()> {
		self.index_ops = index_ops;
		Ok(())
	}
}

struct StorageDb<Block: BlockT> {
	pub db: Arc<dyn Database<DbHash>>,
	pub state_db: StateDb<Block::Hash, Vec<u8>, StateMetaDb>,
	prefix_keys: bool,
}

impl<Block: BlockT> sp_state_machine::Storage<HashFor<Block>> for StorageDb<Block> {
	fn get(&self, key: &Block::Hash, prefix: Prefix) -> Result<Option<DBValue>, String> {
		if self.prefix_keys {
			let key = prefixed_key::<HashFor<Block>>(key, prefix);
			self.state_db.get(&key, self)
		} else {
			self.state_db.get(key.as_ref(), self)
		}
Repository: paritytech/substrate
File: frame/proxy/src/lib.rs (Rust)

Code before:
	) {
		// This is a freshly authenticated new account, the origin restrictions doesn't apply.
		let mut origin: T::RuntimeOrigin = frame_system::RawOrigin::Signed(real).into();
		origin.add_filter(move |c: &<T as frame_system::Config>::RuntimeCall| {
			let c = <T as Config>::RuntimeCall::from_ref(c);
			// We make sure the proxy call does access this pallet to change modify proxies.
			match c.is_sub_type() {
				// Proxy call cannot add or remove a proxy with more permissions than it already
				// has.
				Some(Call::add_proxy { ref proxy_type, .. }) |
				Some(Call::remove_proxy { ref proxy_type, .. })
					if !def.proxy_type.is_superset(proxy_type) =>
					false,
				// Proxy call cannot remove all proxies or kill pure proxies unless it has full
				// permissions.
				Some(Call::remove_proxies { .. }) | Some(Call::kill_pure { .. })
					if def.proxy_type != T::ProxyType::default() =>
					false,
				_ => def.proxy_type.filter(c),
			}
		});
		let e = call.dispatch(origin);
		Self::deposit_event(Event::ProxyExecuted { result: e.map(|_| ()).map_err(|e| e.error) });
	}

	fn remove_all_proxy_delegates(who: &T::AccountId) {
		<Proxies<T>>::mutate(| proxies: &mut <Proxies<T>> | 
			{
			if let Some(delegates) = proxies.get_mut(&who) {
				let old_deposit = proxies.take(&who); 
				delegates.clear(); 
				if let Some(old_deposit) = old_deposit {
					// Return the deposit back to the sender account
					T::Currency::unreserve(&who, old_deposit);
				}
			}
		});
	}
}


Review comment (suggestion):
```suggestion
	pub fn remove_all_proxy_delegates(who: &T::AccountId) {
```

Code after:
			let c = <T as Config>::RuntimeCall::from_ref(c);
			// We make sure the proxy call does access this pallet to change modify proxies.
			match c.is_sub_type() {
				// Proxy call cannot add or remove a proxy with more permissions than it already
				// has.
				Some(Call::add_proxy { ref proxy_type, .. }) |
				Some(Call::remove_proxy { ref proxy_type, .. })
					if !def.proxy_type.is_superset(proxy_type) =>
					false,
				// Proxy call cannot remove all proxies or kill pure proxies unless it has full
				// permissions.
				Some(Call::remove_proxies { .. }) | Some(Call::kill_pure { .. })
					if def.proxy_type != T::ProxyType::default() =>
					false,
				_ => def.proxy_type.filter(c),
			}
		});
		let e = call.dispatch(origin);
		Self::deposit_event(Event::ProxyExecuted { result: e.map(|_| ()).map_err(|e| e.error) });
	}

	/// Removes all proxy delegates for a given delegator.
	///
	/// Parameters:
	/// - `delegator`: The delegator account.
	pub fn remove_all_proxy_delegates(delegator: &T::AccountId) {
		let (_, old_deposit) = Proxies::<T>::take(&delegator);
		T::Currency::unreserve(&delegator, old_deposit);
	}
}
Repository: paritytech/substrate
File: frame/proxy/src/lib.rs (Rust)

Code before:
		origin.add_filter(move |c: &<T as frame_system::Config>::RuntimeCall| {
			let c = <T as Config>::RuntimeCall::from_ref(c);
			// We make sure the proxy call does access this pallet to change modify proxies.
			match c.is_sub_type() {
				// Proxy call cannot add or remove a proxy with more permissions than it already
				// has.
				Some(Call::add_proxy { ref proxy_type, .. }) |
				Some(Call::remove_proxy { ref proxy_type, .. })
					if !def.proxy_type.is_superset(proxy_type) =>
					false,
				// Proxy call cannot remove all proxies or kill pure proxies unless it has full
				// permissions.
				Some(Call::remove_proxies { .. }) | Some(Call::kill_pure { .. })
					if def.proxy_type != T::ProxyType::default() =>
					false,
				_ => def.proxy_type.filter(c),
			}
		});
		let e = call.dispatch(origin);
		Self::deposit_event(Event::ProxyExecuted { result: e.map(|_| ()).map_err(|e| e.error) });
	}

	pub fn remove_all_proxy_delegates(who: &T::AccountId) {
		let (_, old_deposit) = Proxies::<T>::take(&who);
		T::Currency::unreserve(&who, old_deposit);
	}
}


Review comment (suggestion):
```suggestion
	pub fn remove_all_proxy_delegates(delegator: &T::AccountId) {
		let (_, old_deposit) = Proxies::<T>::take(&delegator);
		T::Currency::unreserve(&delegator, old_deposit);
	}
```

Code after:
			let c = <T as Config>::RuntimeCall::from_ref(c);
			// We make sure the proxy call does access this pallet to change modify proxies.
			match c.is_sub_type() {
				// Proxy call cannot add or remove a proxy with more permissions than it already
				// has.
				Some(Call::add_proxy { ref proxy_type, .. }) |
				Some(Call::remove_proxy { ref proxy_type, .. })
					if !def.proxy_type.is_superset(proxy_type) =>
					false,
				// Proxy call cannot remove all proxies or kill pure proxies unless it has full
				// permissions.
				Some(Call::remove_proxies { .. }) | Some(Call::kill_pure { .. })
					if def.proxy_type != T::ProxyType::default() =>
					false,
				_ => def.proxy_type.filter(c),
			}
		});
		let e = call.dispatch(origin);
		Self::deposit_event(Event::ProxyExecuted { result: e.map(|_| ()).map_err(|e| e.error) });
	}

	/// Removes all proxy delegates for a given delegator.
	///
	/// Parameters:
	/// - `delegator`: The delegator account.
	pub fn remove_all_proxy_delegates(delegator: &T::AccountId) {
		let (_, old_deposit) = Proxies::<T>::take(&delegator);
		T::Currency::unreserve(&delegator, old_deposit);
	}
}
Repository: paritytech/substrate
File: frame/proxy/src/lib.rs (Rust)

Code before:
		// This is a freshly authenticated new account, the origin restrictions doesn't apply.
		let mut origin: T::RuntimeOrigin = frame_system::RawOrigin::Signed(real).into();
		origin.add_filter(move |c: &<T as frame_system::Config>::RuntimeCall| {
			let c = <T as Config>::RuntimeCall::from_ref(c);
			// We make sure the proxy call does access this pallet to change modify proxies.
			match c.is_sub_type() {
				// Proxy call cannot add or remove a proxy with more permissions than it already
				// has.
				Some(Call::add_proxy { ref proxy_type, .. }) |
				Some(Call::remove_proxy { ref proxy_type, .. })
					if !def.proxy_type.is_superset(proxy_type) =>
					false,
				// Proxy call cannot remove all proxies or kill pure proxies unless it has full
				// permissions.
				Some(Call::remove_proxies { .. }) | Some(Call::kill_pure { .. })
					if def.proxy_type != T::ProxyType::default() =>
					false,
				_ => def.proxy_type.filter(c),
			}
		});
		let e = call.dispatch(origin);
		Self::deposit_event(Event::ProxyExecuted { result: e.map(|_| ()).map_err(|e| e.error) });
	}

	/// Removes all proxy delegates for a given delegator.
	/// It takes the delegator's account ID as a parameter.
	pub fn remove_all_proxy_delegates(delegator: &T::AccountId) {
		let (_, old_deposit) = Proxies::<T>::take(&delegator);
		T::Currency::unreserve(&delegator, old_deposit);
	}
}


Review comment (suggestion):
```suggestion
	///
	/// Parameters:
	/// - `delegator`: The delegator account.
```

Code after:
		let mut origin: T::RuntimeOrigin = frame_system::RawOrigin::Signed(real).into();
		origin.add_filter(move |c: &<T as frame_system::Config>::RuntimeCall| {
			let c = <T as Config>::RuntimeCall::from_ref(c);
			// We make sure the proxy call does access this pallet to change modify proxies.
			match c.is_sub_type() {
				// Proxy call cannot add or remove a proxy with more permissions than it already
				// has.
				Some(Call::add_proxy { ref proxy_type, .. }) |
				Some(Call::remove_proxy { ref proxy_type, .. })
					if !def.proxy_type.is_superset(proxy_type) =>
					false,
				// Proxy call cannot remove all proxies or kill pure proxies unless it has full
				// permissions.
				Some(Call::remove_proxies { .. }) | Some(Call::kill_pure { .. })
					if def.proxy_type != T::ProxyType::default() =>
					false,
				_ => def.proxy_type.filter(c),
			}
		});
		let e = call.dispatch(origin);
		Self::deposit_event(Event::ProxyExecuted { result: e.map(|_| ()).map_err(|e| e.error) });
	}

	/// Removes all proxy delegates for a given delegator.
	///
	/// Parameters:
	/// - `delegator`: The delegator account.
	pub fn remove_all_proxy_delegates(delegator: &T::AccountId) {
		let (_, old_deposit) = Proxies::<T>::take(&delegator);
		T::Currency::unreserve(&delegator, old_deposit);
	}
}
Repository: paritytech/substrate
File: client/network/test/src/sync.rs (Rust)

Code before:
/// that is currently also doing a major sync.
#[test]
fn sync_to_tip_when_we_sync_together_with_multiple_peers() {
	sp_tracing::try_init_simple();

	let mut net = TestNet::new(3);

	let block_hash =
		net.peer(0)
			.push_blocks_at_without_informing_sync(BlockId::Number(0), 10_000, false, false);

	let block_hash2 =
		net.peer(1)
			.push_blocks_at_without_informing_sync(BlockId::Number(0), 5_000, false, false);

	assert!(!net.peer(2).has_block(block_hash));
	net.peer(0).network_service().new_best_block_imported(block_hash, 10_000);

	net.block_until_connected();
	net.block_until_idle();

	while !net.peer(2).has_block(block_hash) && !net.peer(1).has_block(block_hash) {
		net.block_until_idle();
	}

	// verify that peer1 and peer3 also downloaded the other fork
	assert!(net.peer(0).has_block(block_hash2));
	assert!(net.peer(2).has_block(block_hash2));
}

/// Ensures that when we receive a block announcement with some data attached, that we propagate
/// this data when reannouncing the block.
#[test]
fn block_announce_data_is_propagated() {
	struct TestBlockAnnounceValidator;

	impl BlockAnnounceValidator<Block> for TestBlockAnnounceValidator {
		fn validate(
			&mut self,
			_: &Header,
			data: &[u8],
		) -> Pin<
			Box<dyn Future<Output = Result<Validation, Box<dyn std::error::Error + Send>>> + Send>,
		> {
			let correct = data.get(0) == Some(&137);
			async move {
				if correct {
					Ok(Validation::Success { is_new_best: true })
				} else {
					Ok(Validation::Failure { disconnect: false })
				}

Review comment (suggestion):
```suggestion
	// verify that peer1 and peer3 also download the other fork
```

Code after:
/// that is currently also doing a major sync.
#[test]
fn sync_to_tip_when_we_sync_together_with_multiple_peers() {
	sp_tracing::try_init_simple();

	let mut net = TestNet::new(3);

	let block_hash =
		net.peer(0)
			.push_blocks_at_without_informing_sync(BlockId::Number(0), 10_000, false, false);

	net.peer(1)
		.push_blocks_at_without_informing_sync(BlockId::Number(0), 5_000, false, false);

	net.block_until_connected();
	net.block_until_idle();

	assert!(!net.peer(2).has_block(block_hash));

	net.peer(0).network_service().new_best_block_imported(block_hash, 10_000);
	net.peer(0).network_service().announce_block(block_hash, None);

	while !net.peer(2).has_block(block_hash) && !net.peer(1).has_block(block_hash) {
		net.block_until_idle();
	}
}

/// Ensures that when we receive a block announcement with some data attached, that we propagate
/// this data when reannouncing the block.
#[test]
fn block_announce_data_is_propagated() {
	struct TestBlockAnnounceValidator;

	impl BlockAnnounceValidator<Block> for TestBlockAnnounceValidator {
		fn validate(
			&mut self,
			_: &Header,
			data: &[u8],
		) -> Pin<
			Box<dyn Future<Output = Result<Validation, Box<dyn std::error::Error + Send>>> + Send>,
		> {
			let correct = data.get(0) == Some(&137);
			async move {
				if correct {
					Ok(Validation::Success { is_new_best: true })
				} else {
					Ok(Validation::Failure { disconnect: false })
				}
			}
			.boxed()
		}