vinteumorg / Floresta

A fully-validating Bitcoin node powered by Utreexo, with an integrated Electrum Server
MIT License
151 stars 34 forks source link

bug fix: remove inflights of banned peers #203

Closed lla-dane closed 1 month ago

lla-dane commented 1 month ago

When we ban a peer, we also have to remove the inflight requests related to that peer and send those to a random_peer.

lla-dane commented 1 month ago

@Davidson-Souza, please take a look.

Davidson-Souza commented 1 month ago

I think we can migrate that code to hadle_disconnect and every time we get a disconnection from a peer that has inflight we redo the requests, like this:

+        let inflight = self
+            .inflight
+            .clone()
+            .into_iter()
+            .filter(|(_k, v)| v.0 == peer)
+            .collect::<Vec<_>>();
+
+        for req in inflight {
+            self.inflight.remove(&req.0);
+            self.redo_inflight_request(req.0.clone()).await?;
+        }
+
         self.peer_ids.retain(|&id| id != peer);
         for (_, v) in self.peer_by_service.iter_mut() {
             v.retain(|&id| id != peer);
@@ -265,6 +281,66 @@ where
         );
         Ok(())
     }
+
+    pub(crate) async fn redo_inflight_request(
+        &mut self,
+        req: InflightRequests,
+    ) -> Result<(), WireError> {
+        match req {
+            InflightRequests::Blocks(block) => {
+                let peer = self
+                    .send_to_random_peer(
+                        NodeRequest::GetBlock((vec![block], true)),
+                        ServiceFlags::UTREEXO,
+                    )
+                    .await?;
+                self.inflight
+                    .insert(InflightRequests::Blocks(block), (peer, Instant::now()));
+            }
+            InflightRequests::Headers => {
+                let peer = self
+                    .send_to_random_peer(NodeRequest::GetHeaders(vec![]), ServiceFlags::UTREEXO)
+                    .await?;
+                self.inflight
+                    .insert(InflightRequests::Headers, (peer, Instant::now()));
+            }
+            InflightRequests::UtreexoState(_) => {
+                let peer = self
+                    .send_to_random_peer(
+                        NodeRequest::GetUtreexoState((self.chain.get_block_hash(0).unwrap(), 0)),
+                        ServiceFlags::UTREEXO,
+                    )
+                    .await?;
+                self.inflight
+                    .insert(InflightRequests::UtreexoState(peer), (peer, Instant::now()));
+            }
+            InflightRequests::RescanBlock(block) => {
+                let peer = self
+                    .send_to_random_peer(
+                        NodeRequest::GetBlock((vec![block], false)),
+                        ServiceFlags::UTREEXO,
+                    )
+                    .await?;
+                self.inflight
+                    .insert(InflightRequests::RescanBlock(block), (peer, Instant::now()));
+            }
+            InflightRequests::GetFilters => {
+                let peer = self
+                    .send_to_random_peer(
+                        NodeRequest::GetFilter((self.chain.get_block_hash(0).unwrap(), 0)),
+                        ServiceFlags::COMPACT_FILTERS,
+                    )
+                    .await?;
+                self.inflight
+                    .insert(InflightRequests::GetFilters, (peer, Instant::now()));
+            }
+            InflightRequests::Connect(_) | InflightRequests::UserRequest(_) => {
+                // We don't need to do anything here
+            }
+        }
+        Ok(())
+    }
+
lla-dane commented 1 month ago

Sure, I will update the code

lla-dane commented 1 month ago

@Davidson-Souza, please take a look.