Selaa lähdekoodia

dnetview: partial fix for out of bounds index error

* fix bug that make duplicate empty ids
* disable parse_manual
* standard
lunar-mining 4 vuotta sitten
vanhempi
sitoutus
a5af09e26c
4 muutettua tiedostoa jossa 177 lisäystä ja 49 poistoa
  1. 50 21
      bin/dnetview/src/main.rs
  2. 6 3
      bin/dnetview/src/model.rs
  3. 33 0
      bin/dnetview/src/util.rs
  4. 88 25
      bin/dnetview/src/view.rs

+ 50 - 21
bin/dnetview/src/main.rs

@@ -16,7 +16,7 @@ use tui::{
 use url::Url;
 
 use darkfi::{
-    error::{Error, Result},
+    error::Result,
     rpc::{jsonrpc, rpcclient::RpcClient},
     util::{
         async_util,
@@ -152,12 +152,37 @@ async fn poll(client: DnetView, model: Arc<Model>) -> DnetViewResult<()> {
 }
 
 async fn parse_offline(client: &DnetView, model: Arc<Model>) -> DnetViewResult<()> {
+    let name = "Offline".to_string();
+    let session_type = Session::Offline;
     let node_name = &client.name;
     let node_id = make_node_id(node_name)?;
-    let node = NodeInfo::new(node_id.clone(), node_name.to_string(), None, None);
+    let session_id = make_session_id(&node_id, &session_type)?;
+    let mut connects: Vec<ConnectInfo> = Vec::new();
+    let mut sessions: Vec<SessionInfo> = Vec::new();
+
+    // initialize with empty values
+    let id = make_empty_id(&node_id, &session_type, 0)?;
+    //debug!("Make EMPTY ID: {}", id);
+    let addr = "Null".to_string();
+    let state = "Null".to_string();
+    let parent = node_id.clone();
+    let msg_log = Vec::new();
+    let is_empty = true;
+    let last_msg = "Null".to_string();
+    let last_status = "Null".to_string();
+    let connect_info =
+        ConnectInfo::new(id, addr, state, parent.clone(), msg_log, is_empty, last_msg, last_status);
+    connects.push(connect_info.clone());
+
+    let accept_addr = None;
+    let session_info =
+        SessionInfo::new(session_id, name, is_empty, parent.clone(), connects, accept_addr);
+    sessions.push(session_info);
+
+    let node = NodeInfo::new(node_id.clone(), node_name.to_string(), sessions.clone(), None, true);
 
     update_node(model.clone(), node.clone(), node_id.clone()).await;
-    update_selectable_and_ids(model.clone(), None, node.clone()).await?;
+    update_selectable_and_ids(model.clone(), sessions, node.clone()).await?;
     Ok(())
 }
 
@@ -180,21 +205,21 @@ async fn parse_data(
     let ext_addr = parse_external_addr(addr).await?;
     let in_session = parse_inbound(inbound, &node_id).await?;
     let out_session = parse_outbound(outbound, &node_id).await?;
-    let man_session = parse_manual(manual, &node_id).await?;
+    //let man_session = parse_manual(manual, &node_id).await?;
 
     sessions.push(in_session.clone());
     sessions.push(out_session.clone());
-    sessions.push(man_session.clone());
+    //sessions.push(man_session.clone());
 
     let node =
-        NodeInfo::new(node_id.clone(), node_name.to_string(), Some(sessions.clone()), ext_addr);
+        NodeInfo::new(node_id.clone(), node_name.to_string(), sessions.clone(), ext_addr, false);
 
     update_node(model.clone(), node.clone(), node_id.clone()).await;
-    update_selectable_and_ids(model.clone(), Some(sessions.clone()), node.clone()).await?;
+    update_selectable_and_ids(model.clone(), sessions.clone(), node.clone()).await?;
     update_msgs(model.clone(), sessions.clone()).await?;
 
     //debug!("IDS: {:?}", model.ids.lock().await);
-    //debug!("INFOS: {:?}", model.infos.lock().await);
+    //debug!("INFOS: {:?}", model.nodes.lock().await);
 
     Ok(())
 }
@@ -232,22 +257,20 @@ async fn update_node(model: Arc<Model>, node: NodeInfo, id: String) {
 
 async fn update_selectable_and_ids(
     model: Arc<Model>,
-    sessions: Option<Vec<SessionInfo>>,
+    sessions: Vec<SessionInfo>,
     node: NodeInfo,
 ) -> DnetViewResult<()> {
     let node_obj = SelectableObject::Node(node.clone());
     model.selectables.lock().await.insert(node.id.clone(), node_obj);
     update_ids(model.clone(), node.id.clone()).await;
-    if sessions.is_some() {
-        for session in sessions.unwrap().clone() {
-            let session_obj = SelectableObject::Session(session.clone());
-            model.selectables.lock().await.insert(session.clone().id, session_obj);
-            update_ids(model.clone(), session.clone().id).await;
-            for connect in session.children {
-                let connect_obj = SelectableObject::Connect(connect.clone());
-                model.selectables.lock().await.insert(connect.clone().id, connect_obj);
-                update_ids(model.clone(), connect.clone().id).await;
-            }
+    for session in sessions {
+        let session_obj = SelectableObject::Session(session.clone());
+        model.selectables.lock().await.insert(session.clone().id, session_obj);
+        update_ids(model.clone(), session.clone().id).await;
+        for connect in session.children {
+            let connect_obj = SelectableObject::Connect(connect.clone());
+            model.selectables.lock().await.insert(connect.clone().id, connect_obj);
+            update_ids(model.clone(), connect.clone().id).await;
         }
     }
     Ok(())
@@ -280,6 +303,7 @@ async fn parse_inbound(inbound: &Value, node_id: &String) -> DnetViewResult<Sess
                     connect_count += 1;
                     // channel is empty. initialize with empty values
                     let id = make_empty_id(&node_id, &session_type, connect_count)?;
+                    //debug!("Make INBOUND EMPTY ID: {}", id);
                     let addr = "Null".to_string();
                     let state = "Null".to_string();
                     let parent = parent.clone();
@@ -318,6 +342,7 @@ async fn parse_inbound(inbound: &Value, node_id: &String) -> DnetViewResult<Sess
                         let info2 = info.unwrap().get(1);
                         let id = info2.unwrap().get("random_id").unwrap().as_u64().unwrap();
                         let id = make_connect_id(&id)?;
+                        //debug!("Made INBOUND connect ID: {}", id);
                         let state = "state".to_string();
                         let parent = parent.clone();
                         let msg_values = info2.unwrap().get("log").unwrap().as_array().unwrap();
@@ -378,8 +403,10 @@ async fn parse_manual(_manual: &Value, node_id: &String) -> DnetViewResult<Sessi
     let parent = node_id.to_string();
 
     let session_id = make_session_id(&parent, &session_type)?;
-    let id: u64 = 0;
-    let connect_id = make_connect_id(&id)?;
+    //let id: u64 = 0;
+    let connect_id = make_empty_id(&node_id, &session_type, 0)?;
+    //let connect_id = make_connect_id(&id)?;
+    //debug!("Made MANUAL connect ID: {}", id);
     let addr = "Null".to_string();
     let state = "Null".to_string();
     let msg_log = Vec::new();
@@ -415,6 +442,7 @@ async fn parse_outbound(outbound: &Value, node_id: &String) -> DnetViewResult<Se
                     true => {
                         // channel is empty. initialize with empty values
                         let id = make_empty_id(&node_id, &session_type, slot_count)?;
+                        //debug!("Make OUTBOUND EMPTY ID: {}", id);
                         let addr = "Null".to_string();
                         let state = &slot["state"];
                         let state = state.as_str().unwrap().to_string();
@@ -440,6 +468,7 @@ async fn parse_outbound(outbound: &Value, node_id: &String) -> DnetViewResult<Se
                         let channel = &slot["channel"];
                         let id = channel["random_id"].as_u64().unwrap();
                         let id = make_connect_id(&id)?;
+                        //debug!("Made OUTBOUND connect id {}", id);
                         let addr = &slot["addr"];
                         let addr = addr.as_str().unwrap().to_string();
                         let state = &slot["state"];

+ 6 - 3
bin/dnetview/src/model.rs

@@ -8,6 +8,7 @@ pub enum Session {
     Inbound,
     Outbound,
     Manual,
+    Offline,
 }
 
 #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
@@ -39,18 +40,20 @@ impl Model {
 pub struct NodeInfo {
     pub id: String,
     pub name: String,
-    pub children: Option<Vec<SessionInfo>>,
+    pub children: Vec<SessionInfo>,
     pub external_addr: Option<String>,
+    pub is_offline: bool,
 }
 
 impl NodeInfo {
     pub fn new(
         id: String,
         name: String,
-        children: Option<Vec<SessionInfo>>,
+        children: Vec<SessionInfo>,
         external_addr: Option<String>,
+        is_offline: bool,
     ) -> NodeInfo {
-        NodeInfo { id, name, children, external_addr }
+        NodeInfo { id, name, children, external_addr, is_offline }
     }
 }
 

+ 33 - 0
bin/dnetview/src/util.rs

@@ -1,7 +1,13 @@
 use crate::model::{ConnectInfo, Session};
 use darkfi::{util::serial, Result};
+use log::debug;
 
 pub fn make_node_id(node_name: &String) -> Result<String> {
+    match serial::serialize_hex(node_name).as_str() {
+        e => {
+            debug!("NODE {} IS NODE NAME {} ", e, node_name);
+        }
+    }
     Ok(serial::serialize_hex(node_name))
 }
 
@@ -24,20 +30,37 @@ pub fn make_session_id(node_id: &String, session: &Session) -> Result<String> {
                 num += i as u64;
             }
         }
+        Session::Offline => {
+            for i in ['o', 'f', 'f'] {
+                num += i as u64
+            }
+        }
     }
 
     for i in node_id.chars() {
         num += i as u64
     }
 
+    match serial::serialize_hex(&num).as_str() {
+        e => {
+            debug!("SESSION {} IS NODE ID {} SESSION {:?}", e, node_id, session);
+        }
+    }
     Ok(serial::serialize_hex(&num))
 }
 
 pub fn make_connect_id(id: &u64) -> Result<String> {
+    match serial::serialize_hex(id).as_str() {
+        e => {
+            debug!("CONNECT ID {} IS ID {}", e, id);
+        }
+    }
     Ok(serial::serialize_hex(id))
 }
 
 pub fn make_empty_id(node_id: &String, session: &Session, count: u64) -> Result<String> {
+    let count = count * 2;
+
     let mut num = 0_u64;
 
     match session {
@@ -56,6 +79,11 @@ pub fn make_empty_id(node_id: &String, session: &Session, count: u64) -> Result<
                 num += i as u64;
             }
         }
+        Session::Offline => {
+            for i in ['o', 'f', 'f'] {
+                num += i as u64
+            }
+        }
     }
 
     for i in node_id.chars() {
@@ -64,6 +92,11 @@ pub fn make_empty_id(node_id: &String, session: &Session, count: u64) -> Result<
 
     num += count;
 
+    match serial::serialize_hex(&num).as_str() {
+        e => {
+            debug!("EMPTY ID {} IS NODE ID {} SESSION {:?} COUNT {}", e, node_id, session, count);
+        }
+    }
     Ok(serial::serialize_hex(&num))
 }
 

+ 88 - 25
bin/dnetview/src/view.rs

@@ -62,14 +62,63 @@ impl View {
     }
 
     fn update_active_ids(&mut self) {
+        // this removes the empty ids from the offline node
+        // but doesn't remove the actual ids that were previously there
+        // we need to know what those ideas are in order to remove them
+        // need to keep track of ids somewhere in memory so we can remove them
         for info in self.nodes.infos.values() {
             self.active_ids.ids.insert(info.id.to_string());
-            if info.children.is_some() {
-                for child in info.children.as_ref().unwrap() {
-                    if !child.is_empty == true {
-                        self.active_ids.ids.insert(child.id.to_string());
-                        for child in &child.children {
-                            self.active_ids.ids.insert(child.id.to_string());
+            //debug!("INFO {:?}", info);
+            match info.is_offline {
+                true => {
+                    // get the corresponding selectable object
+
+                    // get the selectable that corresponds to node id
+                    let offline = self.selectables.get(&info.id.to_string());
+                    match offline {
+                        //debug!("NODE {} is offline", info.id.to_string());
+                        Some(SelectableObject::Node(node)) => {
+                            //self.active_ids.ids.remove(&node.id);
+                            for session in &node.children {
+                                debug!("REMOVED {}", session.id.to_string());
+                                self.active_ids.ids.remove(&session.id);
+                                for connect in &session.children {
+                                    debug!("REMOVED {}", connect.id.to_string());
+                                    self.active_ids.ids.remove(&connect.id);
+                                    //
+                                }
+                            }
+                        }
+                        Some(e) => {}
+                        //Some(SelectableObject::Session(session)) => {
+                        //    self.active_ids.ids.remove(&session.id);
+                        //}
+                        //Some(SelectableObject::Connect(connect)) => {
+                        //    self.active_ids.ids.remove(&connect.id);
+                        //}
+                        None => {}
+                    }
+
+                    //self.active_ids.ids.get(&info.id.to_string());
+                    //debug!("OFFLINE INFO {:?}", info);
+                    //debug!("NODE {} is offline", info.id.to_string());
+                    //for session in &info.children {
+                    //    debug!("FOUND SESSION ID {}", session.id.to_string());
+                    //    for connect in &session.children {
+                    //        debug!("FOUND CONNECT ID {}", connect.id.to_string());
+                    //        //self.active_ids.ids.remove(&connect.id.to_string());
+                    //    }
+                    //    //self.active_ids.ids.remove(&session.id.to_string());
+                    //}
+                }
+                false => {
+                    //debug!("ONLINE INFO {:?}", info);
+                    for session in &info.children {
+                        if !session.is_empty == true {
+                            self.active_ids.ids.insert(session.id.to_string());
+                            for connect in &session.children {
+                                self.active_ids.ids.insert(connect.id.to_string());
+                            }
                         }
                     }
                 }
@@ -96,11 +145,11 @@ impl View {
 
         let mut id_list = self.render_id_list(f, slice.clone())?;
 
-        // remove any duplicates
         id_list.dedup();
-
-        //debug!("ID LIST {:?}", id_list);
-        //debug!("ACTIVE ID LIST {:?}", self.active_ids.ids);
+        debug!("ACTIVE ID LIST {:?}", self.active_ids.ids);
+        debug!("ID LIST {:?}", id_list);
+        debug!("ID LIST LEN {:?}", id_list.len());
+        debug!("ACTIVE ID LIST LEN {:?}", self.active_ids.ids.len());
         if id_list.is_empty() {
             // we have not received any data
             Ok(())
@@ -127,22 +176,39 @@ impl View {
     ) -> DnetViewResult<Vec<String>> {
         let style = Style::default();
         let mut nodes = Vec::new();
+        let mut node_ids: Vec<String> = Vec::new();
+        let mut session_ids: Vec<String> = Vec::new();
+        let mut connect_ids: Vec<String> = Vec::new();
         let mut ids: Vec<String> = Vec::new();
 
         for info in self.nodes.infos.values() {
-            match &info.children {
-                Some(children) => {
+            match info.is_offline {
+                true => {
+                    let style = Style::default().fg(Color::Blue).add_modifier(Modifier::ITALIC);
+                    let mut name = String::new();
+                    name.push_str(&info.name);
+                    name.push_str("(Offline)");
+                    let name_span = Span::styled(name, style);
+                    let lines = vec![Spans::from(name_span)];
+                    let names = ListItem::new(lines);
+                    nodes.push(names);
+                    ids.push(info.id.clone());
+                    node_ids.push(info.id.clone());
+                }
+                false => {
                     let name_span = Span::raw(&info.name);
                     let lines = vec![Spans::from(name_span)];
                     let names = ListItem::new(lines);
                     nodes.push(names);
                     ids.push(info.id.clone());
-                    for session in children {
+                    node_ids.push(info.id.clone());
+                    for session in &info.children {
                         if !session.is_empty == true {
                             let name = Span::styled(format!("    {}", session.name), style);
                             let lines = vec![Spans::from(name)];
                             let names = ListItem::new(lines);
                             nodes.push(names);
+                            session_ids.push(session.id.clone());
                             ids.push(session.id.clone());
                             for connection in &session.children {
                                 let mut info = Vec::new();
@@ -177,24 +243,21 @@ impl View {
                                         return Err(DnetViewError::UnexpectedData(data.to_string()))
                                     }
                                 }
+
+                                let lines = vec![Spans::from(info)];
+                                let names = ListItem::new(lines);
+                                nodes.push(names);
+                                connect_ids.push(connection.id.clone());
+                                ids.push(connection.id.clone());
                             }
                         }
                     }
                 }
-                None => {
-                    let style = Style::default().fg(Color::Blue).add_modifier(Modifier::ITALIC);
-                    let mut name = String::new();
-                    name.push_str(&info.name);
-                    name.push_str("(Offline)");
-                    let name_span = Span::styled(name, style);
-                    let lines = vec![Spans::from(name_span)];
-                    let names = ListItem::new(lines);
-                    nodes.push(names);
-                    ids.push(info.id.clone());
-                }
             }
         }
-
+        //debug!("NODES: {:?}", node_ids);
+        //debug!("SESSIONS: {:?}", session_ids);
+        //debug!("CONNECTs : {:?}", connect_ids);
         let nodes =
             List::new(nodes).block(Block::default().borders(Borders::ALL)).highlight_symbol(">> ");