Fix reentrancy of FrozenBalance::died hook (#10473)

* assets: execute `died` hook outside of mutate

Signed-off-by: Oliver Tale-Yazdi <oliver@tasty.limo>

* assets: extend tests for `died` hook

Signed-off-by: Oliver Tale-Yazdi <oliver@tasty.limo>

* assets: update doc of FrozenBalance::died

Signed-off-by: Oliver Tale-Yazdi <oliver@tasty.limo>

* assets: review fixes

- fix cases where `died` should not have been called
- use `Option<DeadConsequence>` instead of `DeadConsequence`

Signed-off-by: Oliver Tale-Yazdi <oliver@tasty.limo>

* assets: update comment in mock.rs

Signed-off-by: Oliver Tale-Yazdi <oliver@tasty.limo>

* assets: return `Remove` in dead_account

The return value is ignored in the only case that it is produced
by a call, but having it this way makes it more understandable.

Signed-off-by: Oliver Tale-Yazdi <oliver@tasty.limo>
This commit is contained in:
Oliver Tale-Yazdi
2022-02-11 14:17:38 +01:00
committed by GitHub
parent e026077505
commit b932e27e5b
4 changed files with 147 additions and 52 deletions
+10
View File
@@ -120,19 +120,27 @@ impl FrozenBalance<u32, u64, u64> for TestFreezer {
fn died(asset: u32, who: &u64) {
HOOKS.with(|h| h.borrow_mut().push(Hook::Died(asset, who.clone())));
// Sanity check: dead accounts have no balance.
assert!(Assets::balance(asset, *who).is_zero());
}
}
pub(crate) fn set_frozen_balance(asset: u32, who: u64, amount: u64) {
FROZEN.with(|f| f.borrow_mut().insert((asset, who), amount));
}
pub(crate) fn clear_frozen_balance(asset: u32, who: u64) {
FROZEN.with(|f| f.borrow_mut().remove(&(asset, who)));
}
pub(crate) fn hooks() -> Vec<Hook> {
HOOKS.with(|h| h.borrow().clone())
}
pub(crate) fn take_hooks() -> Vec<Hook> {
HOOKS.with(|h| h.take())
}
pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
let mut storage = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
@@ -154,6 +162,8 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
config.assimilate_storage(&mut storage).unwrap();
let mut ext: sp_io::TestExternalities = storage.into();
// Clear thread local vars for https://github.com/paritytech/substrate/issues/10479.
ext.execute_with(|| take_hooks());
ext.execute_with(|| System::set_block_number(1));
ext
}