Fixed sync handling large forks
This commit is contained in:
parent
02b23d3deb
commit
d7e729a4ea
@ -843,8 +843,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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user