If the first ExtendTips hash is bad, discard it and re-check
@@ -284,14 +284,41 @@ where
match res.map_err::<Report, _>(|e| eyre!(e)) {
Ok(zn::Response::BlockHashes(hashes)) => {
tracing::debug!(first = ?hashes.first(), len = ?hashes.len());
+ tracing::trace!(?hashes);
- let unknown_hashes = match hashes.split_first() {
- None => continue,
- Some((expected_hash, rest)) if expected_hash == &tip.expected_next => {
+ // zcashd sometimes appends an unrelated hash at the
+ // start or end of its response. Check the first hash
+ // against the previous response, and discard mismatches.
+ let unknown_hashes = match hashes.as_slice() {
+ [expected_hash, rest @ ..] if expected_hash == &tip.expected_next => {
+ rest
+ }
+ // If the first hash doesn't match, retry with the second.
+ [first_hash, expected_hash, rest @ ..]
+ if expected_hash == &tip.expected_next =>
+ {
+ tracing::debug!(?first_hash,
+ ?tip.expected_next,
+ ?tip.tip,
+ "unexpected first hash, but the second matches: using the hashes after the match");
rest
}
- Some((other_hash, _rest)) => {
- tracing::debug!(?other_hash, ?tip.expected_next, "discarding response with unexpected next hash");
+ // We ignore these responses
+ [] => continue,
+ [single_hash] => {
+ tracing::debug!(?single_hash,
+ ?tip.expected_next,
+ ?tip.tip,
+ "discarding response containing a single unexpected hash");
+ continue;
+ }
+ [first_hash, second_hash, rest @ ..] => {
+ tracing::debug!(?first_hash,
+ ?second_hash,
+ rest_len = ?rest.len(),
+ ?tip.expected_next,
+ ?tip.tip,
+ "discarding response that starts with two unexpected hashes");
continue;
}
};
