Roots are added out of order to the accounts index (#4051)

* fix root race

* assert root order

* fixup! assert root order

* last root test

* update

* fix tests
This commit is contained in:
anatoly yakovenko 2019-04-28 10:27:37 -07:00 committed by GitHub
parent 3e14af5033
commit acba1d6f9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 7 deletions

View File

@ -66,9 +66,11 @@ impl<T: Clone> AccountsIndex<T> {
self.roots.contains(&fork) self.roots.contains(&fork)
} }
pub fn add_root(&mut self, fork: Fork) { pub fn add_root(&mut self, fork: Fork) {
if fork > self.last_root { assert!(
self.last_root = fork; (self.last_root == 0 && fork == 0) || (fork > self.last_root),
} "new roots must be increasing"
);
self.last_root = fork;
self.roots.insert(fork); self.roots.insert(fork);
} }
/// Remove the fork when the storage for the fork is freed /// Remove the fork when the storage for the fork is freed
@ -156,15 +158,22 @@ mod tests {
fn test_max_last_root() { fn test_max_last_root() {
let mut index = AccountsIndex::<bool>::default(); let mut index = AccountsIndex::<bool>::default();
index.add_root(1); index.add_root(1);
index.add_root(0);
assert_eq!(index.last_root, 1); assert_eq!(index.last_root, 1);
} }
#[test]
#[should_panic]
fn test_max_last_root_old() {
let mut index = AccountsIndex::<bool>::default();
index.add_root(1);
index.add_root(0);
}
#[test] #[test]
fn test_cleanup_first() { fn test_cleanup_first() {
let mut index = AccountsIndex::<bool>::default(); let mut index = AccountsIndex::<bool>::default();
index.add_root(1);
index.add_root(0); index.add_root(0);
index.add_root(1);
index.cleanup_dead_fork(0); index.cleanup_dead_fork(0);
assert!(index.is_root(1)); assert!(index.is_root(1));
assert!(!index.is_root(0)); assert!(!index.is_root(0));
@ -174,8 +183,8 @@ mod tests {
fn test_cleanup_last() { fn test_cleanup_last() {
//this behavior might be undefined, clean up should only occur on older forks //this behavior might be undefined, clean up should only occur on older forks
let mut index = AccountsIndex::<bool>::default(); let mut index = AccountsIndex::<bool>::default();
index.add_root(1);
index.add_root(0); index.add_root(0);
index.add_root(1);
index.cleanup_dead_fork(1); index.cleanup_dead_fork(1);
assert!(!index.is_root(1)); assert!(!index.is_root(1));
assert!(index.is_root(0)); assert!(index.is_root(0));

View File

@ -293,7 +293,7 @@ impl Bank {
*self.parent.write().unwrap() = None; *self.parent.write().unwrap() = None;
let squash_accounts_start = Instant::now(); let squash_accounts_start = Instant::now();
for p in &parents { for p in parents.iter().rev() {
// root forks cannot be purged // root forks cannot be purged
self.accounts.add_root(p.slot()); self.accounts.add_root(p.slot());
} }