2 Commits 434db88375 ... 7519de7db0

Auteur SHA1 Message Date
  x 7519de7db0 darkfid/task/sync: error out if sync is incomplete and all peers are failing so node can keep retrying and doesn't consider its state synced il y a 1 semaine
  x 5cf6780469 darkfid/task/sync: verify sync response matches request before procesing il y a 1 semaine
1 fichiers modifiés avec 27 ajouts et 2 suppressions
  1. 27 2
      bin/darkfid/src/task/sync.rs

+ 27 - 2
bin/darkfid/src/task/sync.rs

@@ -497,6 +497,10 @@ async fn retrieve_blocks(
         }
         if count == peer_subs.len() {
             debug!(target: "darkfid::task::sync::retrieve_blocks", "All peer connections failed.");
+            // Check if sync completed
+            if !validator.blockchain.headers.is_empty_sync()? {
+                return Err(Error::NetworkOperationFailed)
+            }
             break
         }
 
@@ -545,6 +549,22 @@ async fn retrieve_blocks(
                 continue
             };
 
+            // Verify response contains all requested blocks
+            if response.blocks.len() != headers_hashes.len() {
+                debug!(target: "darkfid::task::sync::retrieve_blocks", "Invalid blocks length of `SyncResponse` from peer: {peer:?}");
+                *failed = true;
+                continue
+            }
+
+            // Verify response sequence matches request
+            for (i, block) in response.blocks.iter().enumerate() {
+                if block.hash() != headers_hashes[i] {
+                    debug!(target: "darkfid::task::sync::retrieve_blocks", "Invalid header in `SyncResponse` from peer: {peer:?}");
+                    *failed = true;
+                    continue
+                }
+            }
+
             // Verify and store retrieved blocks
             debug!(target: "darkfid::task::sync::retrieve_blocks", "Processing received blocks");
             received_blocks += response.blocks.len();
@@ -556,9 +576,14 @@ async fn retrieve_blocks(
                     continue
                 };
             } else {
-                for block in &response.blocks {
+                for (i, block) in response.blocks.iter().enumerate() {
+                    // We manualy build the proposal struct here so we
+                    // don't rehash the block header.
                     match validator
-                        .append_proposal(&Proposal::new(block.clone()), timestamps_bound)
+                        .append_proposal(
+                            &Proposal { hash: headers_hashes[i], block: block.clone() },
+                            timestamps_bound,
+                        )
                         .await
                     {
                         Ok(()) | Err(Error::ProposalAlreadyExists) => continue,