[balances] Safeguard against consumer ref underflow (#3865)

There are some accounts that do not have a consumer ref while having a
reserve.
This adds a fail-safe mechanism to trigger in the case that
`does_consume` is true, but the assumption of `consumer>0` is not.

This should prevent those accounts from loosing balance and the TI from
getting messed up even more, but is not an "ideal" fix. TBH an ideal fix
is not possible, since on-chain data is in an invalid state.

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Oliver Tale-Yazdi
2024-04-26 11:16:03 +03:00
committed by GitHub
parent 8f8c49deff
commit e8f7c81db6
6 changed files with 150 additions and 2 deletions
+19 -1
View File
@@ -19,7 +19,7 @@
#![cfg(test)]
use crate::{self as pallet_balances, AccountData, Config, CreditOf, Error, Pallet};
use crate::{self as pallet_balances, AccountData, Config, CreditOf, Error, Pallet, TotalIssuance};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
assert_err, assert_noop, assert_ok, assert_storage_noop, derive_impl,
@@ -47,6 +47,7 @@ mod currency_tests;
mod dispatchable_tests;
mod fungible_conformance_tests;
mod fungible_tests;
mod general_tests;
mod reentrancy_tests;
type Block = frame_system::mocking::MockBlock<Test>;
@@ -278,6 +279,23 @@ pub fn info_from_weight(w: Weight) -> DispatchInfo {
DispatchInfo { weight: w, ..Default::default() }
}
/// Check that the total-issuance matches the sum of all accounts' total balances.
pub fn ensure_ti_valid() {
let mut sum = 0;
for acc in frame_system::Account::<Test>::iter_keys() {
if UseSystem::get() {
let data = frame_system::Pallet::<Test>::account(acc);
sum += data.data.total();
} else {
let data = crate::Account::<Test>::get(acc);
sum += data.total();
}
}
assert_eq!(TotalIssuance::<Test>::get(), sum, "Total Issuance wrong");
}
#[test]
fn weights_sane() {
let info = crate::Call::<Test>::transfer_allow_death { dest: 10, value: 4 }.get_dispatch_info();