Parcourir la source

consenus: renamed epoch to slot

aggstam il y a 4 ans
Parent
commit
360db522e5

+ 1 - 1
src/consensus/block.rs

@@ -219,7 +219,7 @@ impl ProposalChain {
     }
     }
 
 
     /// A proposal is considered valid when its parent hash is equal to the
     /// A proposal is considered valid when its parent hash is equal to the
-    /// hash of the previous proposal and their epochs are incremental,
+    /// hash of the previous proposal and their slots are incremental,
     /// excluding the genesis block proposal.
     /// excluding the genesis block proposal.
     /// Additional validity rules can be applied.
     /// Additional validity rules can be applied.
     pub fn check_proposal(&self, proposal: &BlockProposal, previous: &BlockProposal) -> bool {
     pub fn check_proposal(&self, proposal: &BlockProposal, previous: &BlockProposal) -> bool {

+ 1 - 1
src/consensus/metadata.rs

@@ -42,7 +42,7 @@ impl OuroborosMetadata {
 /// consensus protocol.
 /// consensus protocol.
 #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
 #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
 pub struct StreamletMetadata {
 pub struct StreamletMetadata {
-    /// Epoch votes
+    /// Slot votes
     pub votes: Vec<Vote>,
     pub votes: Vec<Vote>,
     /// Block notarization flag
     /// Block notarization flag
     pub notarized: bool,
     pub notarized: bool,

+ 3 - 3
src/consensus/participant.rs

@@ -8,14 +8,14 @@ use crate::{
 };
 };
 
 
 /// This struct represents a tuple of the form:
 /// This struct represents a tuple of the form:
-/// (`node_address`, `epoch_joined`, `last_epoch_voted`, `epoch_quarantined`)
+/// (`node_address`, `slot_joined`, `last_slot_voted`, `slot_quarantined`)
 #[derive(Debug, Clone, PartialEq, SerialEncodable, SerialDecodable)]
 #[derive(Debug, Clone, PartialEq, SerialEncodable, SerialDecodable)]
 pub struct Participant {
 pub struct Participant {
     /// Node wallet address
     /// Node wallet address
     pub address: Address,
     pub address: Address,
-    /// Epoch node joined the network
+    /// Slot node joined the network
     pub joined: u64,
     pub joined: u64,
-    /// Last epoch node voted
+    /// Last slot node voted
     pub voted: Option<u64>,
     pub voted: Option<u64>,
     /// Slot participant was quarantined by the node
     /// Slot participant was quarantined by the node
     pub quarantined: Option<u64>,
     pub quarantined: Option<u64>,

+ 70 - 71
src/consensus/state.rs

@@ -34,7 +34,7 @@ use crate::{
     Result,
     Result,
 };
 };
 
 
-/// `2 * DELTA` represents epoch time
+/// `2 * DELTA` represents slot time
 pub const DELTA: u64 = 20;
 pub const DELTA: u64 = 20;
 /// Quarantine duration, in slots
 /// Quarantine duration, in slots
 pub const QUARANTINE_DURATION: u64 = 5;
 pub const QUARANTINE_DURATION: u64 = 5;
@@ -53,7 +53,7 @@ pub struct ConsensusState {
     pub orphan_votes: Vec<Vote>,
     pub orphan_votes: Vec<Vote>,
     /// Validators currently participating in the consensus
     /// Validators currently participating in the consensus
     pub participants: BTreeMap<Address, Participant>,
     pub participants: BTreeMap<Address, Participant>,
-    /// Validators to be added on the next epoch as participants
+    /// Validators to be added on the next slot as participants
     pub pending_participants: Vec<Participant>,
     pub pending_participants: Vec<Participant>,
     /// Last slot participants where refreshed
     /// Last slot participants where refreshed
     pub refreshed: u64,
     pub refreshed: u64,
@@ -123,12 +123,11 @@ pub struct ValidatorState {
     pub client: Arc<Client>,
     pub client: Arc<Client>,
     /// Pending transactions
     /// Pending transactions
     pub unconfirmed_txs: Vec<Transaction>,
     pub unconfirmed_txs: Vec<Transaction>,
-    /// Participating start epoch
+    /// Participating start slot
     pub participating: Option<u64>,
     pub participating: Option<u64>,
 }
 }
 
 
 impl ValidatorState {
 impl ValidatorState {
-    // TODO: Clock sync
     pub async fn new(
     pub async fn new(
         db: &sled::Db, // <-- TODO: Avoid this with some wrapping, sled should only be in blockchain
         db: &sled::Db, // <-- TODO: Avoid this with some wrapping, sled should only be in blockchain
         genesis_ts: Timestamp,
         genesis_ts: Timestamp,
@@ -188,79 +187,79 @@ impl ValidatorState {
         true
         true
     }
     }
 
 
-    /// Calculates current epoch, based on elapsed time from the genesis block.
-    /// Epoch duration is configured using the `DELTA` value.
-    pub fn current_epoch(&self) -> u64 {
+    /// Calculates current slot, based on elapsed time from the genesis block.
+    /// Slot duration is configured using the `DELTA` value.
+    pub fn current_slot(&self) -> u64 {
         self.consensus.genesis_ts.elapsed() / (2 * DELTA)
         self.consensus.genesis_ts.elapsed() / (2 * DELTA)
     }
     }
 
 
-    /// Finds the last epoch a proposal or block was generated.
-    pub fn last_epoch(&self) -> Result<u64> {
-        let mut epoch = 0;
+    /// Finds the last slot a proposal or block was generated.
+    pub fn last_slot(&self) -> Result<u64> {
+        let mut slot = 0;
         for chain in &self.consensus.proposals {
         for chain in &self.consensus.proposals {
             for proposal in &chain.proposals {
             for proposal in &chain.proposals {
-                if proposal.block.sl > epoch {
-                    epoch = proposal.block.sl;
+                if proposal.block.sl > slot {
+                    slot = proposal.block.sl;
                 }
                 }
             }
             }
         }
         }
 
 
         // We return here in case proposals exist,
         // We return here in case proposals exist,
         // so we don't query the sled database.
         // so we don't query the sled database.
-        if epoch > 0 {
-            return Ok(epoch)
+        if slot > 0 {
+            return Ok(slot)
         }
         }
 
 
         let (last_sl, _) = self.blockchain.last()?;
         let (last_sl, _) = self.blockchain.last()?;
         Ok(last_sl)
         Ok(last_sl)
     }
     }
 
 
-    /// Calculates seconds until next epoch starting time.
-    /// Epochs durationis configured using the delta value.
-    pub fn next_epoch_start(&self) -> Duration {
+    /// Calculates seconds until next slot starting time.
+    /// Slots durationis configured using the delta value.
+    pub fn next_slot_start(&self) -> Duration {
         let start_time = NaiveDateTime::from_timestamp(self.consensus.genesis_ts.0, 0);
         let start_time = NaiveDateTime::from_timestamp(self.consensus.genesis_ts.0, 0);
-        let current_epoch = self.current_epoch() + 1;
-        let next_epoch_start = (current_epoch * (2 * DELTA)) + (start_time.timestamp() as u64);
-        let next_epoch_start = NaiveDateTime::from_timestamp(next_epoch_start as i64, 0);
+        let current_slot = self.current_slot() + 1;
+        let next_slot_start = (current_slot * (2 * DELTA)) + (start_time.timestamp() as u64);
+        let next_slot_start = NaiveDateTime::from_timestamp(next_slot_start as i64, 0);
         let current_time = NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0);
         let current_time = NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0);
-        let diff = next_epoch_start - current_time;
+        let diff = next_slot_start - current_time;
 
 
         Duration::new(diff.num_seconds().try_into().unwrap(), 0)
         Duration::new(diff.num_seconds().try_into().unwrap(), 0)
     }
     }
 
 
-    /// Set participating epoch to next.
+    /// Set participating slot to next.
     pub fn set_participating(&mut self) -> Result<()> {
     pub fn set_participating(&mut self) -> Result<()> {
-        self.participating = Some(self.current_epoch() + 1);
+        self.participating = Some(self.current_slot() + 1);
         Ok(())
         Ok(())
     }
     }
 
 
-    /// Find epoch leader, using a simple hash method.
+    /// Find slot leader, using a simple hash method.
     /// Leader calculation is based on how many nodes are participating
     /// Leader calculation is based on how many nodes are participating
     /// in the network.
     /// in the network.
-    pub fn epoch_leader(&mut self) -> Address {
-        let epoch = self.current_epoch();
-        // DefaultHasher is used to hash the epoch number
+    pub fn slot_leader(&mut self) -> Address {
+        let slot = self.current_slot();
+        // DefaultHasher is used to hash the slot number
         // because it produces a number string which then can be modulated by the len.
         // because it produces a number string which then can be modulated by the len.
         // blake3 produces alphanumeric
         // blake3 produces alphanumeric
         let mut hasher = DefaultHasher::new();
         let mut hasher = DefaultHasher::new();
-        epoch.hash(&mut hasher);
+        slot.hash(&mut hasher);
         let pos = hasher.finish() % (self.consensus.participants.len() as u64);
         let pos = hasher.finish() % (self.consensus.participants.len() as u64);
         // Since BTreeMap orders by key in asceding order, each node will have
         // Since BTreeMap orders by key in asceding order, each node will have
         // the same key in calculated position.
         // the same key in calculated position.
         self.consensus.participants.iter().nth(pos as usize).unwrap().1.address
         self.consensus.participants.iter().nth(pos as usize).unwrap().1.address
     }
     }
 
 
-    /// Check if we're the current epoch leader
-    pub fn is_epoch_leader(&mut self) -> bool {
+    /// Check if we're the current slot leader
+    pub fn is_slot_leader(&mut self) -> bool {
         let address = self.address;
         let address = self.address;
-        address == self.epoch_leader()
+        address == self.slot_leader()
     }
     }
 
 
-    /// Generate a block proposal for the current epoch, containing all
+    /// Generate a block proposal for the current slot, containing all
     /// unconfirmed transactions. Proposal extends the longest notarized fork
     /// unconfirmed transactions. Proposal extends the longest notarized fork
     /// chain the node is holding.
     /// chain the node is holding.
     pub fn propose(&self) -> Result<Option<BlockProposal>> {
     pub fn propose(&self) -> Result<Option<BlockProposal>> {
-        let epoch = self.current_epoch();
+        let slot = self.current_slot();
         let (prev_hash, index) = self.longest_notarized_chain_last_hash().unwrap();
         let (prev_hash, index) = self.longest_notarized_chain_last_hash().unwrap();
         let unproposed_txs = self.unproposed_txs(index);
         let unproposed_txs = self.unproposed_txs(index);
 
 
@@ -272,7 +271,7 @@ impl ValidatorState {
         );
         );
 
 
         let sm = StreamletMetadata::new(self.consensus.participants.values().cloned().collect());
         let sm = StreamletMetadata::new(self.consensus.participants.values().cloned().collect());
-        let prop = BlockProposal::to_proposal_hash(prev_hash, epoch, &unproposed_txs, &metadata);
+        let prop = BlockProposal::to_proposal_hash(prev_hash, slot, &unproposed_txs, &metadata);
         let signed_proposal = self.secret.sign(&prop.as_bytes()[..]);
         let signed_proposal = self.secret.sign(&prop.as_bytes()[..]);
 
 
         Ok(Some(BlockProposal::new(
         Ok(Some(BlockProposal::new(
@@ -280,7 +279,7 @@ impl ValidatorState {
             signed_proposal,
             signed_proposal,
             self.address,
             self.address,
             prev_hash,
             prev_hash,
-            epoch,
+            slot,
             unproposed_txs,
             unproposed_txs,
             metadata,
             metadata,
             sm,
             sm,
@@ -337,13 +336,13 @@ impl ValidatorState {
         Ok((hash, index))
         Ok((hash, index))
     }
     }
 
 
-    /// Receive the proposed block, verify its sender (epoch leader),
+    /// Receive the proposed block, verify its sender (slot leader),
     /// and proceed with voting on it.
     /// and proceed with voting on it.
     pub fn receive_proposal(&mut self, proposal: &BlockProposal) -> Result<Option<Vote>> {
     pub fn receive_proposal(&mut self, proposal: &BlockProposal) -> Result<Option<Vote>> {
         // Node hasn't started participating
         // Node hasn't started participating
         match self.participating {
         match self.participating {
             Some(start) => {
             Some(start) => {
-                if self.current_epoch() < start {
+                if self.current_slot() < start {
                     return Ok(None)
                     return Ok(None)
                 }
                 }
             }
             }
@@ -353,10 +352,10 @@ impl ValidatorState {
         // Node refreshes participants records
         // Node refreshes participants records
         self.refresh_participants()?;
         self.refresh_participants()?;
 
 
-        let leader = self.epoch_leader();
+        let leader = self.slot_leader();
         if leader != proposal.address {
         if leader != proposal.address {
             warn!(
             warn!(
-                "Received proposal not from epoch leader ({}), but from ({})",
+                "Received proposal not from slot leader ({}), but from ({})",
                 leader,
                 leader,
                 proposal.address.to_string()
                 proposal.address.to_string()
             );
             );
@@ -500,11 +499,11 @@ impl ValidatorState {
     /// Finally, we check if the notarization of the proposal can finalize
     /// Finally, we check if the notarization of the proposal can finalize
     /// parent proposals in its chain.
     /// parent proposals in its chain.
     pub async fn receive_vote(&mut self, vote: &Vote) -> Result<(bool, Option<Vec<BlockInfo>>)> {
     pub async fn receive_vote(&mut self, vote: &Vote) -> Result<(bool, Option<Vec<BlockInfo>>)> {
-        let current_epoch = self.current_epoch();
+        let current_slot = self.current_slot();
         // Node hasn't started participating
         // Node hasn't started participating
         match self.participating {
         match self.participating {
             Some(start) => {
             Some(start) => {
-                if current_epoch < start {
+                if current_slot < start {
                     return Ok((false, None))
                     return Ok((false, None))
                 }
                 }
             }
             }
@@ -532,8 +531,8 @@ impl ValidatorState {
         match self.consensus.participants.get(&vote.address) {
         match self.consensus.participants.get(&vote.address) {
             Some(participant) => {
             Some(participant) => {
                 let mut participant = participant.clone();
                 let mut participant = participant.clone();
-                if current_epoch <= participant.joined {
-                    warn!("consensus: Voter ({}) joined after current epoch.", va);
+                if current_slot <= participant.joined {
+                    warn!("consensus: Voter ({}) joined after current slot.", va);
                     return Ok((false, None))
                     return Ok((false, None))
                 }
                 }
 
 
@@ -734,17 +733,17 @@ impl ValidatorState {
     }
     }
 
 
     /// Refresh the participants map, to retain only the active ones.
     /// Refresh the participants map, to retain only the active ones.
-    /// Active nodes are considered those that joined previous epoch
-    /// or on the epoch the last proposal was generated, either voted
-    /// or joined the previous of that epoch. That ensures we cover
-    /// the case of a node joining while the chosen epoch leader is inactive.
+    /// Active nodes are considered those that joined previous slot
+    /// or on the slot the last proposal was generated, either voted
+    /// or joined the previous of that slot. That ensures we cover
+    /// the case of a node joining while the chosen slot leader is inactive.
     /// Inactive nodes are marked as quarantined, so they can be removed if
     /// Inactive nodes are marked as quarantined, so they can be removed if
     /// they are in quarantine more than the predifined quarantine period.
     /// they are in quarantine more than the predifined quarantine period.
     pub fn refresh_participants(&mut self) -> Result<()> {
     pub fn refresh_participants(&mut self) -> Result<()> {
         // Node checks if it should refresh its participants list
         // Node checks if it should refresh its participants list
-        let current = self.current_epoch();
+        let current = self.current_slot();
         if current <= self.consensus.refreshed {
         if current <= self.consensus.refreshed {
-            debug!("refresh_participants(): Participants have been refreshed this epoch.");
+            debug!("refresh_participants(): Participants have been refreshed this slot.");
             return Ok(())
             return Ok(())
         }
         }
 
 
@@ -762,34 +761,34 @@ impl ValidatorState {
         self.consensus.pending_participants = vec![];
         self.consensus.pending_participants = vec![];
 
 
         let mut inactive = Vec::new();
         let mut inactive = Vec::new();
-        let mut last_epoch = self.last_epoch()?;
+        let mut last_slot = self.last_slot()?;
 
 
-        // This check ensures that we don't chech the current epoch,
-        // as a node might receive the proposal of current epoch before
-        // starting refreshing participants, so the last_epoch will be
+        // This check ensures that we don't chech the current slot,
+        // as a node might receive the proposal of current slot before
+        // starting refreshing participants, so the last_slot will be
         // the current one.
         // the current one.
-        if last_epoch >= current {
-            last_epoch = current - 1;
+        if last_slot >= current {
+            last_slot = current - 1;
         }
         }
 
 
-        let previous_epoch = current - 1;
+        let previous_slot = current - 1;
         // This check ensures that when restarting the network, previous
         // This check ensures that when restarting the network, previous
-        // from last epoch is not u64::MAX
-        let previous_from_last_epoch = match last_epoch {
+        // from last slot is not u64::MAX
+        let previous_from_last_slot = match last_slot {
             0 => 0,
             0 => 0,
-            _ => last_epoch - 1,
+            _ => last_slot - 1,
         };
         };
 
 
         debug!(
         debug!(
-            "refresh_participants(): Node {:?} checking epochs: previous - {:?}, last - {:?}, previous from last - {:?}",
-            self.address.to_string(), previous_epoch, last_epoch, previous_from_last_epoch
+            "refresh_participants(): Node {:?} checking slots: previous - {:?}, last - {:?}, previous from last - {:?}",
+            self.address.to_string(), previous_slot, last_slot, previous_from_last_slot
         );
         );
 
 
-        let leader = self.epoch_leader();
+        let leader = self.slot_leader();
         for (index, participant) in self.consensus.participants.iter_mut() {
         for (index, participant) in self.consensus.participants.iter_mut() {
             match participant.quarantined {
             match participant.quarantined {
-                Some(epoch) => {
-                    if (current - epoch) > QUARANTINE_DURATION {
+                Some(slot) => {
+                    if (current - slot) > QUARANTINE_DURATION {
                         warn!(
                         warn!(
                             "refresh_participants(): Removing participant: {:?} (joined {:?}, voted {:?})",
                             "refresh_participants(): Removing participant: {:?} (joined {:?}, voted {:?})",
                             participant.address.to_string(),
                             participant.address.to_string(),
@@ -800,7 +799,7 @@ impl ValidatorState {
                     }
                     }
                 }
                 }
                 None => {
                 None => {
-                    // Epoch leader is always quarantined, to cover the case they become inactive the epoch before
+                    // Slot leader is always quarantined, to cover the case they become inactive the slot before
                     // becoming the leader. This can be used for slashing in the future.
                     // becoming the leader. This can be used for slashing in the future.
                     if participant.address == leader {
                     if participant.address == leader {
                         debug!(
                         debug!(
@@ -813,8 +812,8 @@ impl ValidatorState {
                         continue
                         continue
                     }
                     }
                     match participant.voted {
                     match participant.voted {
-                        Some(epoch) => {
-                            if epoch < last_epoch {
+                        Some(slot) => {
+                            if slot < last_slot {
                                 warn!(
                                 warn!(
                                     "refresh_participants(): Quaranteening participant: {:?} (joined {:?}, voted {:?})",
                                     "refresh_participants(): Quaranteening participant: {:?} (joined {:?}, voted {:?})",
                                     participant.address.to_string(),
                                     participant.address.to_string(),
@@ -825,9 +824,9 @@ impl ValidatorState {
                             }
                             }
                         }
                         }
                         None => {
                         None => {
-                            if (previous_epoch == last_epoch && participant.joined < previous_epoch) ||
-                                (previous_epoch != last_epoch &&
-                                    participant.joined < previous_from_last_epoch)
+                            if (previous_slot == last_slot && participant.joined < previous_slot) ||
+                                (previous_slot != last_slot &&
+                                    participant.joined < previous_from_last_slot)
                             {
                             {
                                 warn!(
                                 warn!(
                                     "refresh_participants(): Quaranteening participant: {:?} (joined {:?}, voted {:?})",
                                     "refresh_participants(): Quaranteening participant: {:?} (joined {:?}, voted {:?})",
@@ -849,7 +848,7 @@ impl ValidatorState {
 
 
         if self.consensus.participants.is_empty() {
         if self.consensus.participants.is_empty() {
             // If no nodes are active, node becomes a single node network.
             // If no nodes are active, node becomes a single node network.
-            let participant = Participant::new(self.address, self.current_epoch());
+            let participant = Participant::new(self.address, self.current_slot());
             self.consensus.participants.insert(participant.address, participant);
             self.consensus.participants.insert(participant.address, participant);
         }
         }
 
 

+ 22 - 22
src/consensus/task/proposal.rs

@@ -11,24 +11,24 @@ use crate::{
 
 
 /// async task used for participating in the consensus protocol
 /// async task used for participating in the consensus protocol
 pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: ValidatorStatePtr) {
 pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: ValidatorStatePtr) {
-    // Node waits just before the current or next epoch end, so it can
+    // Node waits just before the current or next slot end, so it can
     // start syncing latest state.
     // start syncing latest state.
-    let mut seconds_until_next_epoch = state.read().await.next_epoch_start();
+    let mut seconds_until_next_slot = state.read().await.next_slot_start();
     let one_sec = Duration::new(1, 0);
     let one_sec = Duration::new(1, 0);
 
 
     loop {
     loop {
-        if seconds_until_next_epoch > one_sec {
-            seconds_until_next_epoch -= one_sec;
+        if seconds_until_next_slot > one_sec {
+            seconds_until_next_slot -= one_sec;
             break
             break
         }
         }
 
 
-        info!("consensus: Waiting for next epoch ({:?} sec)", seconds_until_next_epoch);
-        sleep(seconds_until_next_epoch.as_secs()).await;
-        seconds_until_next_epoch = state.read().await.next_epoch_start();
+        info!("consensus: Waiting for next slot ({:?} sec)", seconds_until_next_slot);
+        sleep(seconds_until_next_slot.as_secs()).await;
+        seconds_until_next_slot = state.read().await.next_slot_start();
     }
     }
 
 
-    info!("consensus: Waiting for next epoch ({:?} sec)", seconds_until_next_epoch);
-    sleep(seconds_until_next_epoch.as_secs()).await;
+    info!("consensus: Waiting for next slot ({:?} sec)", seconds_until_next_slot);
+    sleep(seconds_until_next_slot.as_secs()).await;
 
 
     // Node syncs its consensus state
     // Node syncs its consensus state
     if let Err(e) = consensus_sync_task(consensus_p2p.clone(), state.clone()).await {
     if let Err(e) = consensus_sync_task(consensus_p2p.clone(), state.clone()).await {
@@ -40,8 +40,8 @@ pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: Valid
 
 
     // Node signals the network that it will start participating
     // Node signals the network that it will start participating
     let address = state.read().await.address;
     let address = state.read().await.address;
-    let cur_epoch = state.read().await.current_epoch();
-    let participant = Participant::new(address, cur_epoch);
+    let cur_slot = state.read().await.current_slot();
+    let participant = Participant::new(address, cur_slot);
     state.write().await.append_participant(participant.clone());
     state.write().await.append_participant(participant.clone());
 
 
     match consensus_p2p.broadcast(participant).await {
     match consensus_p2p.broadcast(participant).await {
@@ -49,16 +49,16 @@ pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: Valid
         Err(e) => error!("Failed broadcasting consensus participation: {}", e),
         Err(e) => error!("Failed broadcasting consensus participation: {}", e),
     }
     }
 
 
-    // Node modifies its participating epoch to next.
+    // Node modifies its participating slot to next.
     match state.write().await.set_participating() {
     match state.write().await.set_participating() {
-        Ok(()) => info!("consensus: Node will start participating in the next epoch"),
-        Err(e) => error!("Failed to set participation epoch: {}", e),
+        Ok(()) => info!("consensus: Node will start participating in the next slot"),
+        Err(e) => error!("Failed to set participation slot: {}", e),
     }
     }
 
 
     loop {
     loop {
-        let seconds_next_epoch = state.read().await.next_epoch_start().as_secs();
-        info!("consensus: Waiting for next epoch ({} sec)", seconds_next_epoch);
-        sleep(seconds_next_epoch).await;
+        let seconds_next_slot = state.read().await.next_slot_start().as_secs();
+        info!("consensus: Waiting for next slot ({} sec)", seconds_next_slot);
+        sleep(seconds_next_slot).await;
 
 
         // Node refreshes participants records
         // Node refreshes participants records
         match state.write().await.refresh_participants() {
         match state.write().await.refresh_participants() {
@@ -66,9 +66,9 @@ pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: Valid
             Err(e) => error!("Failed refreshing consensus participants: {}", e),
             Err(e) => error!("Failed refreshing consensus participants: {}", e),
         }
         }
 
 
-        // Node checks if it's the epoch leader to generate a new proposal
-        // for that epoch.
-        let result = if state.write().await.is_epoch_leader() {
+        // Node checks if it's the slot leader to generate a new proposal
+        // for that slot.
+        let result = if state.write().await.is_slot_leader() {
             state.read().await.propose()
             state.read().await.propose()
         } else {
         } else {
             Ok(None)
             Ok(None)
@@ -77,7 +77,7 @@ pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: Valid
         let proposal = match result {
         let proposal = match result {
             Ok(prop) => {
             Ok(prop) => {
                 if prop.is_none() {
                 if prop.is_none() {
-                    info!("consensus: Node is not the epoch lead");
+                    info!("consensus: Node is not the slot lead");
                     continue
                     continue
                 }
                 }
                 prop.unwrap()
                 prop.unwrap()
@@ -88,7 +88,7 @@ pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: Valid
             }
             }
         };
         };
 
 
-        info!("consensus: Node is the epoch leader: Proposed block: {:?}", proposal);
+        info!("consensus: Node is the slot leader: Proposed block: {:?}", proposal);
         let vote = state.write().await.receive_proposal(&proposal);
         let vote = state.write().await.receive_proposal(&proposal);
         let vote = match vote {
         let vote = match vote {
             Ok(v) => {
             Ok(v) => {