Handle failing case for update account cache in require (#9989)

This commit is contained in:
Wei Tang 2018-12-03 23:26:39 +08:00 committed by GitHub
parent 869fa399b1
commit 60691d03e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1194,7 +1194,7 @@ impl<B: Backend> State<B> {
self.note_cache(a);
// at this point the entry is guaranteed to be in the cache.
Ok(RefMut::map(self.cache.borrow_mut(), |c| {
let mut account = RefMut::map(self.cache.borrow_mut(), |c| {
let entry = c.get_mut(a).expect("entry known to exist in the cache; qed");
match &mut entry.account {
@ -1204,20 +1204,19 @@ impl<B: Backend> State<B> {
// set the dirty flag after changing account data.
entry.state = AccountState::Dirty;
match entry.account {
Some(ref mut account) => {
entry.account.as_mut().expect("Required account must always exist; qed")
});
if require_code {
let addr_hash = account.address_hash(a);
let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), addr_hash);
// FIXME (Issue #9838): update_account_cache can fail in rare cases, but we cannot return error in RefMut wrapper.
Self::update_account_cache(RequireCache::Code, account, &self.db, accountdb.as_hashdb());
if !Self::update_account_cache(RequireCache::Code, &mut account, &self.db, accountdb.as_hashdb()) {
return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a))))
}
account
},
_ => panic!("Required account must always exist; qed"),
}
}))
Ok(account)
}
/// Replace account code and storage. Creates account if it does not exist.