Handle failing case for update account cache in require (#9989)
This commit is contained in:
parent
869fa399b1
commit
60691d03e0
@ -960,7 +960,7 @@ impl<B: Backend> State<B> {
|
|||||||
#[cfg(feature="to-pod-full")]
|
#[cfg(feature="to-pod-full")]
|
||||||
/// Populate a PodAccount map from this state.
|
/// Populate a PodAccount map from this state.
|
||||||
/// Warning this is not for real time use.
|
/// Warning this is not for real time use.
|
||||||
/// Use of this method requires FatDB mode to be able
|
/// Use of this method requires FatDB mode to be able
|
||||||
/// to iterate on accounts.
|
/// to iterate on accounts.
|
||||||
pub fn to_pod_full(&self) -> Result<PodState, Error> {
|
pub fn to_pod_full(&self) -> Result<PodState, Error> {
|
||||||
|
|
||||||
@ -971,7 +971,7 @@ impl<B: Backend> State<B> {
|
|||||||
|
|
||||||
let trie = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?;
|
let trie = self.factories.trie.readonly(self.db.as_hashdb(), &self.root)?;
|
||||||
|
|
||||||
// put trie in cache
|
// put trie in cache
|
||||||
for item in trie.iter()? {
|
for item in trie.iter()? {
|
||||||
if let Ok((addr, _dbval)) = item {
|
if let Ok((addr, _dbval)) = item {
|
||||||
let address = Address::from_slice(&addr);
|
let address = Address::from_slice(&addr);
|
||||||
@ -1194,7 +1194,7 @@ impl<B: Backend> State<B> {
|
|||||||
self.note_cache(a);
|
self.note_cache(a);
|
||||||
|
|
||||||
// at this point the entry is guaranteed to be in the cache.
|
// 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");
|
let entry = c.get_mut(a).expect("entry known to exist in the cache; qed");
|
||||||
|
|
||||||
match &mut entry.account {
|
match &mut entry.account {
|
||||||
@ -1204,20 +1204,19 @@ impl<B: Backend> State<B> {
|
|||||||
|
|
||||||
// set the dirty flag after changing account data.
|
// set the dirty flag after changing account data.
|
||||||
entry.state = AccountState::Dirty;
|
entry.state = AccountState::Dirty;
|
||||||
match entry.account {
|
entry.account.as_mut().expect("Required account must always exist; qed")
|
||||||
Some(ref mut account) => {
|
});
|
||||||
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.
|
if require_code {
|
||||||
Self::update_account_cache(RequireCache::Code, account, &self.db, accountdb.as_hashdb());
|
let addr_hash = account.address_hash(a);
|
||||||
}
|
let accountdb = self.factories.accountdb.readonly(self.db.as_hashdb(), addr_hash);
|
||||||
account
|
|
||||||
},
|
if !Self::update_account_cache(RequireCache::Code, &mut account, &self.db, accountdb.as_hashdb()) {
|
||||||
_ => panic!("Required account must always exist; qed"),
|
return Err(Box::new(TrieError::IncompleteDatabase(H256::from(a))))
|
||||||
}
|
}
|
||||||
}))
|
}
|
||||||
|
|
||||||
|
Ok(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace account code and storage. Creates account if it does not exist.
|
/// Replace account code and storage. Creates account if it does not exist.
|
||||||
|
Loading…
Reference in New Issue
Block a user