Эх сурвалжийг харах

script/research/streamlet_rust: Modified structures based on doc/src/architecture/blockchain.md

aggstam 4 жил өмнө
parent
commit
e82befb679

+ 3 - 3
doc/src/architecture/blockchain.md

@@ -82,9 +82,9 @@ This section gives further details about the structures that will be used by the
  \hline
  Field & Type & Description \\ [0.5ex] 
  \hline\hline
- om & Ouroboros\_Metadata & Block information used by Ouroboros consensus. \\ 
+ om & OuroborosMetadata & Block information used by Ouroboros consensus. \\ 
  \hline
- sm & Streamlet\_Metadata & Block information used by Streamlet consenus. \\
+ sm & StreamletMetadata & Block information used by Streamlet consensus. \\
  \hline
  timestamp & Timestamp & Block creation timestamp. \\ [1ex] 
  \hline
@@ -95,7 +95,7 @@ This section gives further details about the structures that will be used by the
  \hline
  Field & Type & Description \\ [0.5ex] 
  \hline\hline
- proof & VRF\_Output & Proof the stakeholder is the block owner. \\ 
+ proof & VRFOutput & Proof the stakeholder is the block owner. \\ 
  \hline
  r & Seed & Random seed for VRF. \\
  \hline

+ 10 - 3
script/research/streamlet_rust/src/lib.rs

@@ -14,9 +14,16 @@ mod tests {
     #[test]
     fn protocol_execution() {
         // Genesis block is generated.
-        let mut genesis_block = Block::new(String::from("⊥"), 0, vec![]);
-        genesis_block.notarized = true;
-        genesis_block.finalized = true;
+        let mut genesis_block = Block::new(
+            String::from("⊥"),
+            0,
+            vec![],
+            String::from("proof"),
+            String::from("r"),
+            String::from("s"),
+        );
+        genesis_block.metadata.sm.notarized = true;
+        genesis_block.metadata.sm.finalized = true;
 
         let genesis_time = Instant::now();
 

+ 22 - 19
script/research/streamlet_rust/src/structures/block.rs

@@ -1,37 +1,40 @@
 use std::hash::{Hash, Hasher};
 
-use super::vote::Vote;
+use super::metadata::Metadata;
 
 use darkfi::{tx::Transaction, util::serial::Encodable};
 
-/// This struct represents a tuple of the form (h, e, txs).
+/// This struct represents a tuple of the form (st, sl, txs, metadata).
 /// Each blocks parent hash h may be computed simply as a hash of the parent block.
 #[derive(Debug, Clone)]
 pub struct Block {
-    /// parent hash
-    pub h: String,
-    /// epoch number
-    pub e: u64,
-    /// transactions payload
+    /// Previous block hash
+    pub st: String,
+    /// Slot uid, generated by the beacon
+    pub sl: u64,
+    /// Transactions payload
     pub txs: Vec<Transaction>,
-    /// Epoch votes
-    pub votes: Vec<Vote>,
-    /// block notarization flag
-    pub notarized: bool,
-    /// block finalization flag
-    pub finalized: bool,
+    /// Additional block information
+    pub metadata: Metadata,
 }
 
 impl Block {
-    pub fn new(h: String, e: u64, txs: Vec<Transaction>) -> Block {
-        Block { h, e, txs, votes: Vec::new(), notarized: false, finalized: false }
+    pub fn new(
+        st: String,
+        sl: u64,
+        txs: Vec<Transaction>,
+        proof: String,
+        r: String,
+        s: String,
+    ) -> Block {
+        Block { st, sl, txs, metadata: Metadata::new(proof, r, s) }
     }
 
     pub fn signature_encode(&self) -> Vec<u8> {
         let mut encoded_block = Vec::new();
         let mut len = 0;
-        len += self.h.encode(&mut encoded_block).unwrap();
-        len += self.e.encode(&mut encoded_block).unwrap();
+        len += self.st.encode(&mut encoded_block).unwrap();
+        len += self.sl.encode(&mut encoded_block).unwrap();
         len += self.txs.encode(&mut encoded_block).unwrap();
         assert_eq!(len, encoded_block.len());
         encoded_block
@@ -40,12 +43,12 @@ impl Block {
 
 impl PartialEq for Block {
     fn eq(&self, other: &Self) -> bool {
-        self.h == other.h && self.e == other.e && self.txs == other.txs
+        self.st == other.st && self.sl == other.sl && self.txs == other.txs
     }
 }
 
 impl Hash for Block {
     fn hash<H: Hasher>(&self, hasher: &mut H) {
-        format!("{:?}{:?}{:?}", self.h, self.e, self.txs).hash(hasher);
+        format!("{:?}{:?}{:?}", self.st, self.sl, self.txs).hash(hasher);
     }
 }

+ 3 - 3
script/research/streamlet_rust/src/structures/blockchain.rs

@@ -20,11 +20,11 @@ impl Blockchain {
     /// previous block and their epochs are incremental, exluding genesis.
     /// Additional validity rules can be applied.
     pub fn check_block_validity(&self, block: &Block, previous_block: &Block) {
-        assert!(block.h != "⊥", "Genesis block provided.");
+        assert!(block.st != "⊥", "Genesis block provided.");
         let mut hasher = DefaultHasher::new();
         previous_block.hash(&mut hasher);
         assert!(
-            block.h == hasher.finish().to_string() && block.e > previous_block.e,
+            block.st == hasher.finish().to_string() && block.sl > previous_block.sl,
             "Provided block is invalid."
         );
     }
@@ -45,7 +45,7 @@ impl Blockchain {
     /// Blockchain notarization check.
     pub fn is_notarized(&self) -> bool {
         for block in &self.blocks {
-            if !block.notarized {
+            if !block.metadata.sm.notarized {
                 return false
             }
         }

+ 58 - 0
script/research/streamlet_rust/src/structures/metadata.rs

@@ -0,0 +1,58 @@
+use std::time::Instant;
+
+use super::vote::Vote;
+
+/// This struct represents additional Block information used by the consensus protocol.
+#[derive(Debug, Clone)]
+pub struct Metadata {
+    /// Block information used by Ouroboros consensus
+    pub om: OuroborosMetadata,
+    /// Block information used by Streamlet consensus
+    pub sm: StreamletMetadata,
+    /// Block creation timestamp
+    pub timestamp: Instant,
+}
+
+impl Metadata {
+    pub fn new(proof: String, r: String, s: String) -> Metadata {
+        Metadata {
+            om: OuroborosMetadata::new(proof, r, s),
+            sm: StreamletMetadata::new(),
+            timestamp: Instant::now(),
+        }
+    }
+}
+
+/// This struct represents Block information used by Ouroboros consensus protocol.
+#[derive(Debug, Clone)]
+pub struct OuroborosMetadata {
+    /// Proof the stakeholder is the block owner
+    pub proof: String,
+    /// Random seed for VRF
+    pub r: String,
+    /// Block owner signature
+    pub s: String,
+}
+
+impl OuroborosMetadata {
+    pub fn new(proof: String, r: String, s: String) -> OuroborosMetadata {
+        OuroborosMetadata { proof, r, s }
+    }
+}
+
+/// This struct represents Block information used by Streamlet consensus protocol.
+#[derive(Debug, Clone)]
+pub struct StreamletMetadata {
+    /// Epoch votes
+    pub votes: Vec<Vote>,
+    /// Block notarization flag
+    pub notarized: bool,
+    /// Block finalization flag
+    pub finalized: bool,
+}
+
+impl StreamletMetadata {
+    pub fn new() -> StreamletMetadata {
+        StreamletMetadata { votes: Vec::new(), notarized: false, finalized: false }
+    }
+}

+ 2 - 0
script/research/streamlet_rust/src/structures/mod.rs

@@ -4,10 +4,12 @@
 
 pub mod block;
 pub mod blockchain;
+pub mod metadata;
 pub mod node;
 pub mod vote;
 
 pub use block::Block;
 pub use blockchain::Blockchain;
+pub use metadata::Metadata;
 pub use node::Node;
 pub use vote::Vote;

+ 20 - 14
script/research/streamlet_rust/src/structures/node.rs

@@ -143,8 +143,14 @@ impl Node {
         let mut hasher = DefaultHasher::new();
         longest_notarized_chain.blocks.last().unwrap().hash(&mut hasher);
         let unproposed_transactions = self.get_unproposed_transactions();
-        let proposed_block =
-            Block::new(hasher.finish().to_string(), epoch, unproposed_transactions);
+        let proposed_block = Block::new(
+            hasher.finish().to_string(),
+            epoch,
+            unproposed_transactions,
+            String::from("proof"),
+            String::from("r"),
+            String::from("s"),
+        );
         let signed_block = self.secret_key.sign(&proposed_block.signature_encode());
         (self.public_key, Vote::new(signed_block, proposed_block, self.id))
     }
@@ -189,7 +195,7 @@ impl Node {
     /// Node verifies if provided blockchain is notarized excluding the last block.
     pub fn extends_notarized_blockchain(&self, blockchain: &Blockchain) -> bool {
         for block in &blockchain.blocks[..(blockchain.blocks.len() - 1)] {
-            if !block.notarized {
+            if !block.metadata.sm.notarized {
                 return false
             }
         }
@@ -202,14 +208,14 @@ impl Node {
         for (index, blockchain) in self.node_blockchains.iter().enumerate() {
             let last_block = blockchain.blocks.last().unwrap();
             last_block.hash(&mut hasher);
-            if block.h == hasher.finish().to_string() && block.e > last_block.e {
+            if block.st == hasher.finish().to_string() && block.sl > last_block.sl {
                 return index as i64
             }
         }
 
         let last_block = self.canonical_blockchain.blocks.last().unwrap();
         last_block.hash(&mut hasher);
-        if block.h != hasher.finish().to_string() || block.e <= last_block.e {
+        if block.st != hasher.finish().to_string() || block.sl <= last_block.sl {
             panic!("Proposed block doesn't extend any known chains.");
         }
         -1
@@ -245,14 +251,14 @@ impl Node {
         }
 
         let (unwrapped_vote_block, blockchain_index) = vote_block.unwrap();
-        if !unwrapped_vote_block.votes.contains(vote) {
-            unwrapped_vote_block.votes.push(vote.clone());
+        if !unwrapped_vote_block.metadata.sm.votes.contains(vote) {
+            unwrapped_vote_block.metadata.sm.votes.push(vote.clone());
         }
 
-        if !unwrapped_vote_block.notarized &&
-            unwrapped_vote_block.votes.len() > (2 * nodes_count / 3)
+        if !unwrapped_vote_block.metadata.sm.notarized &&
+            unwrapped_vote_block.metadata.sm.votes.len() > (2 * nodes_count / 3)
         {
-            unwrapped_vote_block.notarized = true;
+            unwrapped_vote_block.metadata.sm.notarized = true;
             self.check_blockchain_finalization(blockchain_index);
         }
     }
@@ -290,7 +296,7 @@ impl Node {
         if blockchain_len > 2 {
             let mut consecutive_notarized = 0;
             for block in &blockchain.blocks {
-                if block.notarized {
+                if block.metadata.sm.notarized {
                     consecutive_notarized = consecutive_notarized + 1;
                 } else {
                     break
@@ -300,7 +306,7 @@ impl Node {
             if consecutive_notarized > 2 {
                 let mut finalized_blocks = Vec::new();
                 for block in &mut blockchain.blocks[..(consecutive_notarized - 1)] {
-                    block.finalized = true;
+                    block.metadata.sm.finalized = true;
                     finalized_blocks.push(block.clone());
                     for transaction in block.txs.clone() {
                         if let Some(pos) =
@@ -322,8 +328,8 @@ impl Node {
                 let mut dropped_blockchains = Vec::new();
                 for (index, blockchain) in self.node_blockchains.iter().enumerate() {
                     let first_block = blockchain.blocks.first().unwrap();
-                    if first_block.h != last_finalized_block_hash ||
-                        first_block.e <= last_finalized_block.e
+                    if first_block.st != last_finalized_block_hash ||
+                        first_block.sl <= last_finalized_block.sl
                     {
                         dropped_blockchains.push(index);
                     }