aggstam 4 лет назад
Родитель
Сommit
93ae339b5f
4 измененных файлов с 56 добавлено и 23 удалено
  1. 4 7
      script/consensus_simulation.sh
  2. 2 2
      src/blockchain/mod.rs
  3. 33 13
      src/consensus/block.rs
  4. 17 1
      src/consensus/state.rs

+ 4 - 7
script/consensus_simulation.sh

@@ -20,8 +20,7 @@ LOG_TARGETS="!sled,!net" ./darkfid \
     --rpc-listen tcp://127.0.0.1:6010 \
     --sync-p2p-accept tcp://127.0.0.1:6020 \
     --sync-p2p-external tcp://127.0.0.1:6020 \
-    --wallet-path ./tmp/node0/wallet.db \
-    --clock-sync &
+    --wallet-path ./tmp/node0/wallet.db &
     
 pids[${#pids[@]}]=$!
 
@@ -33,7 +32,7 @@ bound=$(($nodes-2))
 for i in $(eval echo "{1..$bound}")
 do
   LOG_TARGETS="!sled,!net" ./darkfid \
-      -v \
+    -v \
     --consensus \
     --consensus-p2p-seed tcp://127.0.0.1:6000 \
     --sync-p2p-seed tcp://127.0.0.1:6020 \
@@ -43,8 +42,7 @@ do
     --rpc-listen tcp://127.0.0.1:601$i \
     --sync-p2p-accept tcp://127.0.0.1:602$i \
     --sync-p2p-external tcp://127.0.0.1:602$i \
-    --wallet-path ./tmp/node$i/wallet.db \
-    --clock-sync &
+    --wallet-path ./tmp/node$i/wallet.db &
   pids[${#pids[@]}]=$!
   # waiting for node to setup
   sleep 20
@@ -74,5 +72,4 @@ LOG_TARGETS="!sled,!net" ./darkfid \
     --rpc-listen tcp://127.0.0.1:601$bound \
     --sync-p2p-accept tcp://127.0.0.1:602$bound \
     --sync-p2p-external tcp://127.0.0.1:602$bound \
-    --wallet-path ./tmp/node$bound/wallet.db \
-    --clock-sync
+    --wallet-path ./tmp/node$bound/wallet.db

+ 2 - 2
src/blockchain/mod.rs

@@ -69,7 +69,7 @@ impl Blockchain {
             let tx_hashes = self.transactions.insert(&block.txs)?;
 
             // Store block
-            let _block = Block::new(block.st, block.sl, tx_hashes, block.metadata.clone());
+            let _block = Block::new(block.st, block.e, block.sl, tx_hashes, block.metadata.clone());
             let blockhash = self.blocks.insert(&[_block])?;
             ret.push(blockhash[0]);
 
@@ -113,7 +113,7 @@ impl Blockchain {
             let txs = self.transactions.get(&block.txs, true)?;
             let txs = txs.iter().map(|x| x.clone().unwrap()).collect();
 
-            let info = BlockInfo::new(block.st, block.sl, txs, block.metadata.clone(), sm);
+            let info = BlockInfo::new(block.st, block.e, block.sl, txs, block.metadata.clone(), sm);
             ret.push(info);
         }
 

+ 33 - 13
src/consensus/block.rs

@@ -14,7 +14,7 @@ use crate::{
     Result,
 };
 
-/// This struct represents a tuple of the form ('v', `st`, `sl`, txs`, `metadata`).
+/// This struct represents a tuple of the form (`v`, `st`, `e`, `sl`, `txs`, `metadata`).
 /// The transactions here are stored as hashes, which serve as pointers to
 /// the actual transaction data in the blockchain database.
 #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
@@ -23,7 +23,9 @@ pub struct Block {
     pub v: u8,
     /// Previous block hash
     pub st: blake3::Hash,
-    /// Slot uid, generated by the beacon
+    /// Epoch
+    pub e: u64,
+    /// Slot uid
     pub sl: u64,
     /// Transaction hashes
     pub txs: Vec<blake3::Hash>,
@@ -32,9 +34,15 @@ pub struct Block {
 }
 
 impl Block {
-    pub fn new(st: blake3::Hash, sl: u64, txs: Vec<blake3::Hash>, metadata: Metadata) -> Self {
+    pub fn new(
+        st: blake3::Hash,
+        e: u64,
+        sl: u64,
+        txs: Vec<blake3::Hash>,
+        metadata: Metadata,
+    ) -> Self {
         let v = *BLOCK_VERSION;
-        Self { v, st, sl, txs, metadata }
+        Self { v, st, e, sl, txs, metadata }
     }
 
     /// Generate the genesis block.
@@ -42,7 +50,7 @@ impl Block {
         let metadata =
             Metadata::new(genesis_ts, String::from("proof"), String::from("r"), String::from("s"));
 
-        Self::new(genesis_data, 0, vec![], metadata)
+        Self::new(genesis_data, 0, 0, vec![], metadata)
     }
 
     /// Calculate the block hash
@@ -73,7 +81,9 @@ pub struct BlockInfo {
     pub v: u8,
     /// Previous block hash
     pub st: blake3::Hash,
-    /// Slot UID, generated by the beacon
+    /// Epoch
+    pub e: u64,
+    /// Slot uid
     pub sl: u64,
     /// Transactions payload
     pub txs: Vec<Transaction>,
@@ -86,13 +96,14 @@ pub struct BlockInfo {
 impl BlockInfo {
     pub fn new(
         st: blake3::Hash,
+        e: u64,
         sl: u64,
         txs: Vec<Transaction>,
         metadata: Metadata,
         sm: StreamletMetadata,
     ) -> Self {
         let v = *BLOCK_VERSION;
-        Self { v, st, sl, txs, metadata, sm }
+        Self { v, st, e, sl, txs, metadata, sm }
     }
 
     /// Calculate the block hash
@@ -105,7 +116,7 @@ impl BlockInfo {
 impl From<BlockInfo> for Block {
     fn from(b: BlockInfo) -> Self {
         let txids = b.txs.iter().map(|x| blake3::hash(&serialize(x))).collect();
-        Self { v: b.v, st: b.st, sl: b.sl, txs: txids, metadata: b.metadata }
+        Self { v: b.v, st: b.st, e: b.e, sl: b.sl, txs: txids, metadata: b.metadata }
     }
 }
 
@@ -150,23 +161,31 @@ impl BlockProposal {
         signature: Signature,
         address: Address,
         st: blake3::Hash,
+        e: u64,
         sl: u64,
         txs: Vec<Transaction>,
         metadata: Metadata,
         sm: StreamletMetadata,
     ) -> Self {
-        let block = BlockInfo::new(st, sl, txs, metadata, sm);
+        let block = BlockInfo::new(st, e, sl, txs, metadata, sm);
         Self { public_key, signature, address, block }
     }
 
-    /// Produce proposal hash using `st`, `sl`, `txs`, and `metadata`.
+    /// Produce proposal hash using `st`, `e`, `sl`, `txs`, and `metadata`.
     pub fn hash(&self) -> blake3::Hash {
-        Self::to_proposal_hash(self.block.st, self.block.sl, &self.block.txs, &self.block.metadata)
+        Self::to_proposal_hash(
+            self.block.st,
+            self.block.e,
+            self.block.sl,
+            &self.block.txs,
+            &self.block.metadata,
+        )
     }
 
-    /// Generate a proposal hash using provided `st`, `sl`, `txs`, and `metadata`.
+    /// Generate a proposal hash using provided `st`, `e`, `sl`, `txs`, and `metadata`.
     pub fn to_proposal_hash(
         st: blake3::Hash,
+        e: u64,
         sl: u64,
         transactions: &[Transaction],
         metadata: &Metadata,
@@ -176,7 +195,7 @@ impl BlockProposal {
             txs.push(blake3::hash(&serialize(tx)));
         }
 
-        blake3::hash(&serialize(&Block::new(st, sl, txs, metadata.clone())))
+        blake3::hash(&serialize(&Block::new(st, e, sl, txs, metadata.clone())))
     }
 }
 
@@ -186,6 +205,7 @@ impl PartialEq for BlockProposal {
             self.signature == other.signature &&
             self.address == other.address &&
             self.block.st == other.block.st &&
+            self.block.e == other.block.e &&
             self.block.sl == other.block.sl &&
             self.block.txs == other.block.txs &&
             self.block.metadata == other.block.metadata

+ 17 - 1
src/consensus/state.rs

@@ -36,6 +36,8 @@ use crate::{
 
 /// `2 * DELTA` represents slot time
 pub const DELTA: u64 = 20;
+/// Slots in an epoch
+pub const EPOCH_SLOTS: u64 = 10;
 /// Quarantine duration, in slots
 pub const QUARANTINE_DURATION: u64 = 5;
 
@@ -187,6 +189,12 @@ impl ValidatorState {
         true
     }
 
+    /// Calculates the epoch of the provided slot.
+    /// Epoch duration is configured using the `EPOCH_SLOTS` value.
+    pub fn slot_epoch(&self, slot: u64) -> u64 {
+        slot / EPOCH_SLOTS
+    }
+
     /// 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 {
@@ -271,7 +279,13 @@ impl ValidatorState {
         );
 
         let sm = StreamletMetadata::new(self.consensus.participants.values().cloned().collect());
-        let prop = BlockProposal::to_proposal_hash(prev_hash, slot, &unproposed_txs, &metadata);
+        let prop = BlockProposal::to_proposal_hash(
+            prev_hash,
+            self.slot_epoch(slot),
+            slot,
+            &unproposed_txs,
+            &metadata,
+        );
         let signed_proposal = self.secret.sign(&prop.as_bytes()[..]);
 
         Ok(Some(BlockProposal::new(
@@ -279,6 +293,7 @@ impl ValidatorState {
             signed_proposal,
             self.address,
             prev_hash,
+            self.slot_epoch(slot),
             slot,
             unproposed_txs,
             metadata,
@@ -365,6 +380,7 @@ impl ValidatorState {
         if !proposal.public_key.verify(
             BlockProposal::to_proposal_hash(
                 proposal.block.st,
+                proposal.block.e,
                 proposal.block.sl,
                 &proposal.block.txs,
                 &proposal.block.metadata,