Merge pull request #5874 from paritytech/track-bad-snapshot-hashes

blacklist bad snapshot manifest hashes upon failure
This commit is contained in:
Robert Habermeier 2017-06-19 17:57:06 +02:00 committed by GitHub
commit c8e176b2e3
2 changed files with 33 additions and 2 deletions

View File

@ -521,7 +521,8 @@ impl ChainSync {
sn > fork_block && sn > fork_block &&
self.highest_block.map_or(true, |highest| highest >= sn && (highest - sn) <= SNAPSHOT_RESTORE_THRESHOLD) self.highest_block.map_or(true, |highest| highest >= sn && (highest - sn) <= SNAPSHOT_RESTORE_THRESHOLD)
)) ))
.filter_map(|(p, peer)| peer.snapshot_hash.map(|hash| (p, hash.clone()))); .filter_map(|(p, peer)| peer.snapshot_hash.map(|hash| (p, hash.clone())))
.filter(|&(_, ref hash)| !self.snapshot.is_known_bad(hash));
let mut snapshot_peers = HashMap::new(); let mut snapshot_peers = HashMap::new();
let mut max_peers: usize = 0; let mut max_peers: usize = 0;
@ -1075,10 +1076,18 @@ impl ChainSync {
} }
// check service status // check service status
match io.snapshot_service().status() { let status = io.snapshot_service().status();
match status {
RestorationStatus::Inactive | RestorationStatus::Failed => { RestorationStatus::Inactive | RestorationStatus::Failed => {
trace!(target: "sync", "{}: Snapshot restoration aborted", peer_id); trace!(target: "sync", "{}: Snapshot restoration aborted", peer_id);
self.state = SyncState::WaitingPeers; self.state = SyncState::WaitingPeers;
// only note bad if restoration failed.
if let (Some(hash), RestorationStatus::Failed) = (self.snapshot.snapshot_hash(), status) {
trace!(target: "sync", "Noting snapshot hash {} as bad", hash);
self.snapshot.note_bad(hash);
}
self.snapshot.clear(); self.snapshot.clear();
self.continue_sync(io); self.continue_sync(io);
return Ok(()); return Ok(());

View File

@ -31,6 +31,7 @@ pub struct Snapshot {
downloading_chunks: HashSet<H256>, downloading_chunks: HashSet<H256>,
completed_chunks: HashSet<H256>, completed_chunks: HashSet<H256>,
snapshot_hash: Option<H256>, snapshot_hash: Option<H256>,
bad_hashes: HashSet<H256>,
} }
impl Snapshot { impl Snapshot {
@ -42,6 +43,7 @@ impl Snapshot {
downloading_chunks: HashSet::new(), downloading_chunks: HashSet::new(),
completed_chunks: HashSet::new(), completed_chunks: HashSet::new(),
snapshot_hash: None, snapshot_hash: None,
bad_hashes: HashSet::new(),
} }
} }
@ -109,6 +111,16 @@ impl Snapshot {
self.downloading_chunks.remove(hash); self.downloading_chunks.remove(hash);
} }
// note snapshot hash as bad.
pub fn note_bad(&mut self, hash: H256) {
self.bad_hashes.insert(hash);
}
// whether snapshot hash is known to be bad.
pub fn is_known_bad(&self, hash: &H256) -> bool {
self.bad_hashes.contains(hash)
}
pub fn snapshot_hash(&self) -> Option<H256> { pub fn snapshot_hash(&self) -> Option<H256> {
self.snapshot_hash self.snapshot_hash
} }
@ -205,5 +217,15 @@ mod test {
assert_eq!(snapshot.done_chunks(), snapshot.total_chunks()); assert_eq!(snapshot.done_chunks(), snapshot.total_chunks());
assert_eq!(snapshot.snapshot_hash(), Some(manifest.into_rlp().sha3())); assert_eq!(snapshot.snapshot_hash(), Some(manifest.into_rlp().sha3()));
} }
#[test]
fn tracks_known_bad() {
let mut snapshot = Snapshot::new();
let hash = H256::random();
assert_eq!(snapshot.is_known_bad(&hash), false);
snapshot.note_bad(hash);
assert_eq!(snapshot.is_known_bad(&hash), true);
}
} }