From c7dbfc21b661c39f5dc2e181109d00945638350c Mon Sep 17 00:00:00 2001
From: Davide Galassi <davxy@datawok.net>
Date: Sun, 17 Sep 2023 22:06:19 +0200
Subject: [PATCH] Babe epoch newtype (#1596)

Removal of verbatim duplication of BABE's `Epoch` struct in the client.

I think is better to have one single definition and wrap the primitive
`Epoch` in a newtype (required because we need to implement the `Epoch`
trait).
---
 Cargo.lock                                    |  3 -
 substrate/client/consensus/babe/Cargo.toml    |  3 -
 .../client/consensus/babe/src/authorship.rs   | 21 ++++---
 substrate/client/consensus/babe/src/lib.rs    | 55 +++++++++----------
 .../client/consensus/babe/src/migration.rs    |  4 +-
 substrate/client/consensus/babe/src/tests.rs  | 10 ++--
 6 files changed, 45 insertions(+), 51 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index a994d14a322..efefda5c878 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -14754,17 +14754,14 @@ dependencies = [
  "num-traits",
  "parity-scale-codec",
  "parking_lot 0.12.1",
- "rand_chacha 0.2.2",
  "sc-block-builder",
  "sc-client-api",
  "sc-consensus",
  "sc-consensus-epochs",
  "sc-consensus-slots",
- "sc-network",
  "sc-network-test",
  "sc-telemetry",
  "sc-transaction-pool-api",
- "scale-info",
  "sp-api",
  "sp-application-crypto",
  "sp-block-builder",
diff --git a/substrate/client/consensus/babe/Cargo.toml b/substrate/client/consensus/babe/Cargo.toml
index d9588794535..c8cff0981b3 100644
--- a/substrate/client/consensus/babe/Cargo.toml
+++ b/substrate/client/consensus/babe/Cargo.toml
@@ -15,7 +15,6 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 async-trait = "0.1.57"
-scale-info = { version = "2.5.0", features = ["derive"] }
 codec = { package = "parity-scale-codec", version = "3.6.1", features = ["derive"] }
 futures = "0.3.21"
 log = "0.4.17"
@@ -45,10 +44,8 @@ sp-keystore = { path = "../../../primitives/keystore" }
 sp-runtime = { path = "../../../primitives/runtime" }
 
 [dev-dependencies]
-rand_chacha = "0.2.2"
 sc-block-builder = { path = "../../block-builder" }
 sp-keyring = { path = "../../../primitives/keyring" }
-sc-network = { path = "../../network" }
 sc-network-test = { path = "../../network/test" }
 sp-timestamp = { path = "../../../primitives/timestamp" }
 sp-tracing = { path = "../../../primitives/tracing" }
diff --git a/substrate/client/consensus/babe/src/authorship.rs b/substrate/client/consensus/babe/src/authorship.rs
index 758d5321a94..3580caba746 100644
--- a/substrate/client/consensus/babe/src/authorship.rs
+++ b/substrate/client/consensus/babe/src/authorship.rs
@@ -132,23 +132,22 @@ fn claim_secondary_slot(
 	keystore: &KeystorePtr,
 	author_secondary_vrf: bool,
 ) -> Option<(PreDigest, AuthorityId)> {
-	let Epoch { authorities, randomness, mut epoch_index, .. } = epoch;
-
-	if authorities.is_empty() {
+	if epoch.authorities.is_empty() {
 		return None
 	}
 
+	let mut epoch_index = epoch.epoch_index;
 	if epoch.end_slot() <= slot {
 		// Slot doesn't strictly belong to the epoch, create a clone with fixed values.
 		epoch_index = epoch.clone_for_slot(slot).epoch_index;
 	}
 
-	let expected_author = secondary_slot_author(slot, authorities, *randomness)?;
+	let expected_author = secondary_slot_author(slot, &epoch.authorities, epoch.randomness)?;
 
 	for (authority_id, authority_index) in keys {
 		if authority_id == expected_author {
 			let pre_digest = if author_secondary_vrf {
-				let data = make_vrf_sign_data(randomness, slot, epoch_index);
+				let data = make_vrf_sign_data(&epoch.randomness, slot, epoch_index);
 				let result =
 					keystore.sr25519_vrf_sign(AuthorityId::ID, authority_id.as_ref(), &data);
 				if let Ok(Some(vrf_signature)) = result {
@@ -232,19 +231,18 @@ fn claim_primary_slot(
 	keystore: &KeystorePtr,
 	keys: &[(AuthorityId, usize)],
 ) -> Option<(PreDigest, AuthorityId)> {
-	let Epoch { authorities, randomness, mut epoch_index, .. } = epoch;
-
+	let mut epoch_index = epoch.epoch_index;
 	if epoch.end_slot() <= slot {
 		// Slot doesn't strictly belong to the epoch, create a clone with fixed values.
 		epoch_index = epoch.clone_for_slot(slot).epoch_index;
 	}
 
-	let data = make_vrf_sign_data(randomness, slot, epoch_index);
+	let data = make_vrf_sign_data(&epoch.randomness, slot, epoch_index);
 
 	for (authority_id, authority_index) in keys {
 		let result = keystore.sr25519_vrf_sign(AuthorityId::ID, authority_id.as_ref(), &data);
 		if let Ok(Some(vrf_signature)) = result {
-			let threshold = calculate_primary_threshold(c, authorities, *authority_index);
+			let threshold = calculate_primary_threshold(c, &epoch.authorities, *authority_index);
 
 			let can_claim = authority_id
 				.as_inner_ref()
@@ -274,7 +272,7 @@ fn claim_primary_slot(
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use sp_consensus_babe::{AllowedSlots, AuthorityId, BabeEpochConfiguration};
+	use sp_consensus_babe::{AllowedSlots, AuthorityId, BabeEpochConfiguration, Epoch};
 	use sp_core::{crypto::Pair as _, sr25519::Pair};
 	use sp_keystore::testing::MemoryKeystore;
 
@@ -300,7 +298,8 @@ mod tests {
 				c: (3, 10),
 				allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots,
 			},
-		};
+		}
+		.into();
 
 		assert!(claim_slot(10.into(), &epoch, &keystore).is_none());
 
diff --git a/substrate/client/consensus/babe/src/lib.rs b/substrate/client/consensus/babe/src/lib.rs
index 90b7523ec18..ccf72939631 100644
--- a/substrate/client/consensus/babe/src/lib.rs
+++ b/substrate/client/consensus/babe/src/lib.rs
@@ -69,6 +69,7 @@
 use std::{
 	collections::HashSet,
 	future::Future,
+	ops::{Deref, DerefMut},
 	pin::Pin,
 	sync::Arc,
 	task::{Context, Poll},
@@ -156,20 +157,27 @@ const AUTHORING_SCORE_VRF_CONTEXT: &[u8] = b"substrate-babe-vrf";
 const AUTHORING_SCORE_LENGTH: usize = 16;
 
 /// BABE epoch information
-#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, scale_info::TypeInfo)]
-pub struct Epoch {
-	/// The epoch index.
-	pub epoch_index: u64,
-	/// The starting slot of the epoch.
-	pub start_slot: Slot,
-	/// The duration of this epoch.
-	pub duration: u64,
-	/// The authorities and their weights.
-	pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
-	/// Randomness for this epoch.
-	pub randomness: Randomness,
-	/// Configuration of the epoch.
-	pub config: BabeEpochConfiguration,
+#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
+pub struct Epoch(sp_consensus_babe::Epoch);
+
+impl Deref for Epoch {
+	type Target = sp_consensus_babe::Epoch;
+
+	fn deref(&self) -> &Self::Target {
+		&self.0
+	}
+}
+
+impl DerefMut for Epoch {
+	fn deref_mut(&mut self) -> &mut Self::Target {
+		&mut self.0
+	}
+}
+
+impl From<sp_consensus_babe::Epoch> for Epoch {
+	fn from(epoch: sp_consensus_babe::Epoch) -> Self {
+		Epoch(epoch)
+	}
 }
 
 impl EpochT for Epoch {
@@ -180,7 +188,7 @@ impl EpochT for Epoch {
 		&self,
 		(descriptor, config): (NextEpochDescriptor, BabeEpochConfiguration),
 	) -> Epoch {
-		Epoch {
+		sp_consensus_babe::Epoch {
 			epoch_index: self.epoch_index + 1,
 			start_slot: self.start_slot + self.duration,
 			duration: self.duration,
@@ -188,6 +196,7 @@ impl EpochT for Epoch {
 			randomness: descriptor.randomness,
 			config,
 		}
+		.into()
 	}
 
 	fn start_slot(&self) -> Slot {
@@ -199,25 +208,12 @@ impl EpochT for Epoch {
 	}
 }
 
-impl From<sp_consensus_babe::Epoch> for Epoch {
-	fn from(epoch: sp_consensus_babe::Epoch) -> Self {
-		Epoch {
-			epoch_index: epoch.epoch_index,
-			start_slot: epoch.start_slot,
-			duration: epoch.duration,
-			authorities: epoch.authorities,
-			randomness: epoch.randomness,
-			config: epoch.config,
-		}
-	}
-}
-
 impl Epoch {
 	/// Create the genesis epoch (epoch #0).
 	///
 	/// This is defined to start at the slot of the first block, so that has to be provided.
 	pub fn genesis(genesis_config: &BabeConfiguration, slot: Slot) -> Epoch {
-		Epoch {
+		sp_consensus_babe::Epoch {
 			epoch_index: 0,
 			start_slot: slot,
 			duration: genesis_config.epoch_length,
@@ -228,6 +224,7 @@ impl Epoch {
 				allowed_slots: genesis_config.allowed_slots,
 			},
 		}
+		.into()
 	}
 
 	/// Clone and tweak epoch information to refer to the specified slot.
diff --git a/substrate/client/consensus/babe/src/migration.rs b/substrate/client/consensus/babe/src/migration.rs
index 2b1396c41c2..bec2d0a61f4 100644
--- a/substrate/client/consensus/babe/src/migration.rs
+++ b/substrate/client/consensus/babe/src/migration.rs
@@ -62,10 +62,11 @@ impl EpochT for EpochV0 {
 	}
 }
 
+// Implement From<EpochV0> for Epoch
 impl EpochV0 {
 	/// Migrate the sturct to current epoch version.
 	pub fn migrate(self, config: &BabeConfiguration) -> Epoch {
-		Epoch {
+		sp_consensus_babe::Epoch {
 			epoch_index: self.epoch_index,
 			start_slot: self.start_slot,
 			duration: self.duration,
@@ -73,5 +74,6 @@ impl EpochV0 {
 			randomness: self.randomness,
 			config: BabeEpochConfiguration { c: config.c, allowed_slots: config.allowed_slots },
 		}
+		.into()
 	}
 }
diff --git a/substrate/client/consensus/babe/src/tests.rs b/substrate/client/consensus/babe/src/tests.rs
index b3843f8acfa..02882d8baae 100644
--- a/substrate/client/consensus/babe/src/tests.rs
+++ b/substrate/client/consensus/babe/src/tests.rs
@@ -501,7 +501,7 @@ fn claim_epoch_slots() {
 	let authority = Sr25519Keyring::Alice;
 	let keystore = create_keystore(authority);
 
-	let mut epoch = Epoch {
+	let mut epoch: Epoch = sp_consensus_babe::Epoch {
 		start_slot: 0.into(),
 		authorities: vec![(authority.public().into(), 1)],
 		randomness: [0; 32],
@@ -511,7 +511,8 @@ fn claim_epoch_slots() {
 			c: (3, 10),
 			allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots,
 		},
-	};
+	}
+	.into();
 
 	let claim_slot_wrap = |s, e| match claim_slot(Slot::from(s as u64), &e, &keystore) {
 		None => 0,
@@ -551,7 +552,7 @@ fn claim_vrf_check() {
 
 	let public = authority.public();
 
-	let epoch = Epoch {
+	let epoch: Epoch = sp_consensus_babe::Epoch {
 		start_slot: 0.into(),
 		authorities: vec![(public.into(), 1)],
 		randomness: [0; 32],
@@ -561,7 +562,8 @@ fn claim_vrf_check() {
 			c: (3, 10),
 			allowed_slots: AllowedSlots::PrimaryAndSecondaryVRFSlots,
 		},
-	};
+	}
+	.into();
 
 	// We leverage the predictability of claim types given a constant randomness.
 
-- 
GitLab