fix(headers-stage): do not exit stage on downloader error (#439)

* fix: return ctrl to pipeline on header dl error

* chore: adjust log levels

* ecies: improve tag check error granularity

* chore: instrument read_ack/read_auth

Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me>
This commit is contained in:
Georgios Konstantopoulos
2022-12-14 16:25:54 +02:00
committed by GitHub
parent 28121a4504
commit d5d876b286
3 changed files with 19 additions and 10 deletions

View File

@ -225,7 +225,7 @@ impl ECIES {
let check_tag = hmac_sha256(mac_key.as_ref(), &[iv, encrypted_data], auth_data);
if check_tag != tag {
return Err(ECIESErrorImpl::TagCheckFailed.into())
return Err(ECIESErrorImpl::TagCheckDecryptFailed.into())
}
let decrypted_data = encrypted_data;
@ -325,6 +325,7 @@ impl ECIES {
}
/// Read and verify an auth message from the input data.
#[tracing::instrument(skip_all)]
pub fn read_auth(&mut self, data: &mut [u8]) -> Result<(), ECIESError> {
self.remote_init_msg = Some(Bytes::copy_from_slice(data));
let unencrypted = self.decrypt_message(data)?;
@ -389,6 +390,7 @@ impl ECIES {
}
/// Read and verify an ack message from the input data.
#[tracing::instrument(skip_all)]
pub fn read_ack(&mut self, data: &mut [u8]) -> Result<(), ECIESError> {
self.remote_init_msg = Some(Bytes::copy_from_slice(data));
let unencrypted = self.decrypt_message(data)?;
@ -476,7 +478,7 @@ impl ECIES {
self.ingress_mac.as_mut().unwrap().update_header(header);
let check_mac = self.ingress_mac.as_mut().unwrap().digest();
if check_mac != mac {
return Err(ECIESErrorImpl::TagCheckFailed.into())
return Err(ECIESErrorImpl::TagCheckHeaderFailed.into())
}
self.ingress_aes.as_mut().unwrap().apply_keystream(header);
@ -528,7 +530,7 @@ impl ECIES {
self.ingress_mac.as_mut().unwrap().update_body(body);
let check_mac = self.ingress_mac.as_mut().unwrap().digest();
if check_mac != mac {
return Err(ECIESErrorImpl::TagCheckFailed.into())
return Err(ECIESErrorImpl::TagCheckBodyFailed.into())
}
let size = self.body_size.unwrap();

View File

@ -40,9 +40,15 @@ pub enum ECIESErrorImpl {
/// Error during IO
#[error("IO error")]
IO(std::io::Error),
/// Error when checking the HMAC tag against the tag on the data
#[error("tag check failure")]
TagCheckFailed,
/// Error when checking the HMAC tag against the tag on the message being decrypted
#[error("tag check failure in read_header")]
TagCheckDecryptFailed,
/// Error when checking the HMAC tag against the tag on the header
#[error("tag check failure in read_header")]
TagCheckHeaderFailed,
/// Error when checking the HMAC tag against the tag on the body
#[error("tag check failure in read_body")]
TagCheckBodyFailed,
/// Error when parsing AUTH data
#[error("invalid auth data")]
InvalidAuthData,

View File

@ -95,9 +95,10 @@ impl<DB: Database, D: HeaderDownloader, C: Consensus, H: HeadersClient> Stage<DB
// in descending order starting from the tip down to
// the local head (latest block in db)
while let Some(headers) = stream.next().await {
trace!(len = headers.len(), "Received headers");
match headers.into_iter().collect::<Result<Vec<_>, _>>() {
Ok(res) => {
info!(len = res.len(), "Received headers");
// Perform basic response validation
self.validate_header_response(&res)?;
let write_progress =
@ -111,12 +112,12 @@ impl<DB: Database, D: HeaderDownloader, C: Consensus, H: HeadersClient> Stage<DB
return Ok(ExecOutput { stage_progress, reached_tip: false, done: false })
}
DownloadError::HeaderValidation { hash, error } => {
warn!("Validation error for header {hash}: {error}");
error!("Validation error for header {hash}: {error}");
return Err(StageError::Validation { block: stage_progress, error })
}
error => {
warn!("Unexpected error occurred: {error}");
return Err(StageError::Download(error.to_string()))
error!(?error, "An unexpected error occurred");
return Ok(ExecOutput { stage_progress, reached_tip: false, done: false })
}
},
}