From 4c960c4e6df05a7ecbc4fb0c5e9f2f0c2a531459 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Sat, 24 Oct 2020 17:31:41 -0700 Subject: [PATCH] zebrad: treat duplicate downloads as an error We should error if we notice that we're attempting to download the same blocks multiple times, because that indicates that peers reported bad information to us, or we got confused trying to interpret their responses. --- zebrad/src/components/sync.rs | 5 +---- zebrad/src/components/sync/downloads.rs | 9 +++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/zebrad/src/components/sync.rs b/zebrad/src/components/sync.rs index 70965575f..4850d32e0 100644 --- a/zebrad/src/components/sync.rs +++ b/zebrad/src/components/sync.rs @@ -544,10 +544,7 @@ where async fn request_blocks(&mut self, hashes: HashSet) -> Result<(), Report> { tracing::debug!(hashes.len = hashes.len(), "requesting blocks"); for hash in hashes.into_iter() { - self.downloads - .download_and_verify(hash) - .await - .map_err(|e| eyre!(e))?; + self.downloads.download_and_verify(hash).await?; } Ok(()) diff --git a/zebrad/src/components/sync/downloads.rs b/zebrad/src/components/sync/downloads.rs index fe5b983cb..9bda7744e 100644 --- a/zebrad/src/components/sync/downloads.rs +++ b/zebrad/src/components/sync/downloads.rs @@ -5,6 +5,7 @@ use std::{ task::{Context, Poll}, }; +use color_eyre::eyre::{eyre, Report}; use futures::{ future::TryFutureExt, ready, @@ -110,10 +111,9 @@ where /// only if the network service fails. It returns immediately after queuing /// the request. #[instrument(skip(self))] - pub async fn download_and_verify(&mut self, hash: block::Hash) -> Result<(), BoxError> { + pub async fn download_and_verify(&mut self, hash: block::Hash) -> Result<(), Report> { if self.cancel_handles.contains_key(&hash) { - tracing::debug!("skipping hash already queued for download"); - return Ok(()); + return Err(eyre!("duplicate hash queued for download")); } // We construct the block requests sequentially, waiting for the peer @@ -127,7 +127,8 @@ where let block_req = self .network .ready_and() - .await? + .await + .map_err(|e| eyre!(e))? .call(zn::Request::BlocksByHash(std::iter::once(hash).collect())); tracing::debug!("requested block");