Lots of chain sync and block validation fixes

* Fix for the chain pipeline partly relying on an outdated head,
leading to not properly recognizing a fork and inconsistent sum
tree state.
* Do not drop block requests during sync that don't get satisfied,
retry enough time to get them and avoid stall.
* Always validate header, even in sync where we may have validated
it already. We don't want a block coming from a peer that could
squeeze through with an invalid header.
* When syncing, do not mark blocks that were errored by the chain
as received (typical case: orphan). Keep retrying.
* Improved chain state dump for debugging.
* Do not add to orphans blocks too far in the future.
* Better error reporting on db errors.
* Related sync test fixes.

TODO figure out why syncing peers timeout so often, very useful
to test but not that great for a fast sync experience.
This commit is contained in:
Ignotus Peverell
2017-10-22 07:11:45 +00:00
parent f12559f53b
commit f1488f9529
11 changed files with 183 additions and 143 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ use global;
use keychain;
/// Errors thrown by Block validation
#[derive(Debug, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
/// The sum of output minus input commitments does not match the sum of
/// kernel commitments
+23 -16
View File
@@ -41,6 +41,7 @@ use std::ops::{self, Deref};
use core::hash::{Hash, Hashed};
use ser::{self, Readable, Reader, Writeable, Writer};
use util::LOGGER;
/// Trait for an element of the tree that has a well-defined sum and hash that
/// the tree can sum over
@@ -355,25 +356,31 @@ where
self.last_pos
}
/// Debugging utility to print information about the MMRs.
pub fn dump(&self) {
/// Debugging utility to print information about the MMRs. Short version
/// only prints the last 8 nodes.
pub fn dump(&self, short: bool) {
let sz = self.unpruned_size();
if sz > 25 {
if sz > 600 {
return;
}
println!("UXTO set, size: {}", sz);
for n in 0..sz {
print!("{:>8} ", n + 1);
}
println!("");
for n in 1..(sz + 1) {
let ohs = self.get(n);
match ohs {
Some(hs) => print!("{} ", hs.hash),
None => print!("{:>8} ", "??"),
}
}
println!("");
let start = if short && sz > 7 { sz/8 - 1 } else { 0 };
for n in start..(sz/8+1) {
let mut idx = "".to_owned();
let mut hashes = "".to_owned();
for m in (n*8)..(n+1)*8 {
if m >= sz {
break;
}
idx.push_str(&format!("{:>8} ", m + 1));
let ohs = self.get(m+1);
match ohs {
Some(hs) => hashes.push_str(&format!("{} ", hs.hash)),
None => hashes.push_str(&format!("{:>8} ", "??")),
}
}
debug!(LOGGER, "{}", idx);
debug!(LOGGER, "{}", hashes);
}
}
}