Просмотр исходного кода

validatord: added votes orphans impl, removed artificial delays when voting, remove +nightly from simulation

aggstam 4 лет назад
Родитель
Сommit
07b27791b0

+ 4 - 4
script/research/validatord/simulation/simulation.sh

@@ -9,21 +9,21 @@ do
 done
 
 # Starting node 0 (seed) in background
-cargo +nightly run -- &
+cargo run -- &
 NODE0=$!
 
 # Waiting for seed to setup
 sleep 10
 
 # Starting node 1 in background
-cargo +nightly run -- --accept 0.0.0.0:11001 --seeds 127.0.0.1:11000 --rpc 127.0.0.1:6661 --external 127.0.0.1:11001 --id 1 --state ~/.config/darkfi/validatord_state_1 &
+cargo run -- --accept 0.0.0.0:11001 --seeds 127.0.0.1:11000 --rpc 127.0.0.1:6661 --external 127.0.0.1:11001 --id 1 --state ~/.config/darkfi/validatord_state_1 &
 NODE1=$!
 
 # Waiting for node 1 to setup
 sleep 5
 
 # Starting node 2 in background
-cargo +nightly run -- --accept 0.0.0.0:11002 --seeds 127.0.0.1:11000 --rpc 127.0.0.1:6662 --external 127.0.0.1:11002 --id 2 --state ~/.config/darkfi/validatord_state_2 &
+cargo run -- --accept 0.0.0.0:11002 --seeds 127.0.0.1:11000 --rpc 127.0.0.1:6662 --external 127.0.0.1:11002 --id 2 --state ~/.config/darkfi/validatord_state_2 &
 NODE2=$!
 
 # Waiting for node 2 to setup
@@ -40,7 +40,7 @@ function ctrl_c() {
 }
 
 # Starting node 3
-cargo +nightly run -- --accept 0.0.0.0:11003 --seeds 127.0.0.1:11000 --rpc 127.0.0.1:6663 --external 127.0.0.1:11003 --id 3 --state ~/.config/darkfi/validatord_state_3
+cargo run -- --accept 0.0.0.0:11003 --seeds 127.0.0.1:11000 --rpc 127.0.0.1:6663 --external 127.0.0.1:11003 --id 3 --state ~/.config/darkfi/validatord_state_3
 
 # Node states are flushed on each node state file at epoch end (every 2 minutes).
 # To sugmit a TX, telnet to a node and push the json as per following example:

+ 3 - 2
script/research/validatord/simulation/validatord_state_0

@@ -26,5 +26,6 @@
     ]
   },
   "node_blockchains": [],
-  "unconfirmed_txs": []
-}
+  "unconfirmed_txs": [],
+  "orphan_votes": []
+}

+ 2 - 1
script/research/validatord/simulation/validatord_state_1

@@ -26,5 +26,6 @@
     ]
   },
   "node_blockchains": [],
-  "unconfirmed_txs": []
+  "unconfirmed_txs": [],
+  "orphan_votes": []
 }

+ 2 - 1
script/research/validatord/simulation/validatord_state_2

@@ -26,5 +26,6 @@
     ]
   },
   "node_blockchains": [],
-  "unconfirmed_txs": []
+  "unconfirmed_txs": [],
+  "orphan_votes": []
 }

+ 2 - 1
script/research/validatord/simulation/validatord_state_3

@@ -26,5 +26,6 @@
     ]
   },
   "node_blockchains": [],
-  "unconfirmed_txs": []
+  "unconfirmed_txs": [],
+  "orphan_votes": []
 }

+ 1 - 2
script/research/validatord/src/main.rs

@@ -1,4 +1,4 @@
-use std::{net::SocketAddr, path::PathBuf, sync::Arc, thread, time};
+use std::{net::SocketAddr, path::PathBuf, sync::Arc, thread};
 
 use async_executor::Executor;
 use async_trait::async_trait;
@@ -133,7 +133,6 @@ async fn proposal_task(p2p: net::P2pPtr, state: StatePtr, state_path: &PathBuf)
                                     Err(e) => error!("Broadcast failed. Error: {:?}", e),
                                 }
                                 // Broadcasting leader vote
-                                thread::sleep(time::Duration::from_secs(10)); // communication delay simulation
                                 let result = p2p.broadcast(vote).await;
                                 match result {
                                     Ok(()) => info!("Leader vote broadcasted successfuly."),

+ 0 - 3
script/research/validatord/src/protocols/protocol_proposal.rs

@@ -1,5 +1,3 @@
-use std::{thread, time};
-
 use async_executor::Executor;
 use async_trait::async_trait;
 
@@ -64,7 +62,6 @@ impl ProtocolProposal {
                     } else {
                         let vote = x.unwrap();
                         self.state.write().unwrap().receive_vote(&vote, nodes_count as usize);
-                        thread::sleep(time::Duration::from_secs(10)); // communication delay simulation
                         self.p2p.broadcast(vote).await?;
                     }
                 }

+ 32 - 4
src/consensus/state.rs

@@ -1,5 +1,5 @@
 use chrono::{NaiveDateTime, Utc};
-use log::error;
+use log::{debug, error};
 use serde::{Deserialize, Serialize};
 use std::{
     collections::hash_map::DefaultHasher,
@@ -45,6 +45,7 @@ pub struct State {
     pub canonical_blockchain: Blockchain,
     pub node_blockchains: Vec<Blockchain>,
     pub unconfirmed_txs: Vec<Tx>,
+    pub orphan_votes: Vec<Vote>,
 }
 
 impl State {
@@ -59,6 +60,7 @@ impl State {
             canonical_blockchain: Blockchain::new(init_block),
             node_blockchains: Vec::new(),
             unconfirmed_txs: Vec::new(),
+            orphan_votes: Vec::new(),
         }
     }
 
@@ -177,7 +179,7 @@ impl State {
     /// If block extends the canonical blockchain, a new fork blockchain is created.
     /// Node votes on the block, only if it extends the longest notarized chain it has seen.
     pub fn vote_block(&mut self, proposal: &BlockProposal, leader: bool) -> Result<Option<Vote>> {
-        let block = Block::new(
+        let mut block = Block::new(
             proposal.st.clone(),
             proposal.sl,
             proposal.txs.clone(),
@@ -186,6 +188,18 @@ impl State {
             String::from("s"),
         );
 
+        // Add orphan votes
+        let mut orphans = Vec::new();
+        for (index, vote) in self.orphan_votes.iter().enumerate() {
+            if proposal_eq_block(&vote.block, &block) {
+                block.metadata.sm.votes.push(vote.clone());
+                orphans.push(index);
+            }
+        }
+        for index in orphans {
+            self.orphan_votes.remove(index);
+        }
+
         let index = self.find_extended_blockchain_index(&block, leader);
 
         if index == -2 {
@@ -240,7 +254,7 @@ impl State {
         if (leader && block.st != hasher.finish().to_string() || block.sl < last_block.sl) ||
             (!leader && block.st != hasher.finish().to_string() || block.sl <= last_block.sl)
         {
-            error!("Proposed block doesn't extend any known chains.");
+            debug!("Proposed block doesn't extend any known chains.");
             return -2
         }
         -1
@@ -268,7 +282,10 @@ impl State {
         assert!(&vote.node_public_key.verify(&encoded_block[..], &vote.vote));
         let vote_block = self.find_block(&vote.block);
         if vote_block == None {
-            error!("Received vote for unknown block.");
+            debug!("Received vote for unknown block.");
+            if !self.orphan_votes.contains(vote) {
+                self.orphan_votes.push(vote.clone());
+            }
             return
         }
 
@@ -357,6 +374,17 @@ impl State {
                 for index in dropped_blockchains {
                     self.node_blockchains.remove(index);
                 }
+
+                // Remove orphan votes
+                let mut orphans = Vec::new();
+                for (index, vote) in self.orphan_votes.iter().enumerate() {
+                    if vote.block.sl <= last_finalized_block.sl {
+                        orphans.push(index);
+                    }
+                }
+                for index in orphans {
+                    self.orphan_votes.remove(index);
+                }
             }
         }
     }