Merge pull request #647 from ethcore/sync

Fixed sync handling large forks
This commit is contained in:
Gav Wood 2016-03-10 00:53:20 +01:00
commit 2ecad23fab
2 changed files with 38 additions and 2 deletions

View File

@ -850,8 +850,8 @@ impl ChainSync {
self.downloading_bodies.remove(&n); self.downloading_bodies.remove(&n);
self.downloading_headers.remove(&n); self.downloading_headers.remove(&n);
} }
self.headers.remove_tail(&start); self.headers.remove_from(&start);
self.bodies.remove_tail(&start); self.bodies.remove_from(&start);
} }
/// Request headers from a peer by block hash /// Request headers from a peer by block hash

View File

@ -42,6 +42,8 @@ pub trait RangeCollection<K, V> {
fn remove_head(&mut self, start: &K); fn remove_head(&mut self, start: &K);
/// Remove all elements >= `start` in the range that contains `start` /// Remove all elements >= `start` in the range that contains `start`
fn remove_tail(&mut self, start: &K); fn remove_tail(&mut self, start: &K);
/// Remove all elements >= `start`
fn remove_from(&mut self, start: &K);
/// Remove all elements >= `tail` /// Remove all elements >= `tail`
fn insert_item(&mut self, key: K, value: V); fn insert_item(&mut self, key: K, value: V);
/// Get an iterator over ranges /// Get an iterator over ranges
@ -137,6 +139,28 @@ impl<K, V> RangeCollection<K, V> for Vec<(K, Vec<V>)> where K: Ord + PartialEq +
} }
} }
/// Remove the element and all following it.
fn remove_from(&mut self, key: &K) {
match self.binary_search_by(|&(k, _)| k.cmp(key).reverse()) {
Ok(index) => { self.drain(.. index + 1); },
Err(index) =>{
let mut empty = false;
match self.get_mut(index) {
Some(&mut (ref k, ref mut v)) if k <= key && (*k + FromUsize::from_usize(v.len())) > *key => {
v.truncate((*key - *k).to_usize());
empty = v.is_empty();
}
_ => {}
}
if empty {
self.drain(.. index + 1);
} else {
self.drain(.. index);
}
},
}
}
/// Remove range elements up to key /// Remove range elements up to key
fn remove_head(&mut self, key: &K) { fn remove_head(&mut self, key: &K) {
if *key == FromUsize::from_usize(0) { if *key == FromUsize::from_usize(0) {
@ -272,5 +296,17 @@ fn test_range() {
assert_eq!(r.range_iter().cmp(vec![(2, &['b'][..])]), Ordering::Equal); assert_eq!(r.range_iter().cmp(vec![(2, &['b'][..])]), Ordering::Equal);
r.remove_tail(&2); r.remove_tail(&2);
assert_eq!(r.range_iter().next(), None); assert_eq!(r.range_iter().next(), None);
let mut r = ranges.clone();
r.remove_from(&20);
assert_eq!(r.range_iter().cmp(vec![(2, &['b', 'c', 'd'][..]), (16, &['p', 'q', 'r'][..])]), Ordering::Equal);
r.remove_from(&17);
assert_eq!(r.range_iter().cmp(vec![(2, &['b', 'c', 'd'][..]), (16, &['p'][..])]), Ordering::Equal);
r.remove_from(&15);
assert_eq!(r.range_iter().cmp(vec![(2, &['b', 'c', 'd'][..])]), Ordering::Equal);
r.remove_from(&3);
assert_eq!(r.range_iter().cmp(vec![(2, &['b'][..])]), Ordering::Equal);
r.remove_from(&2);
assert_eq!(r.range_iter().next(), None);
} }