1

The following test can be used in the test suite of pallet-balances:

#[test]
fn reap_fails_but_account_gets_dusted() {
    ExtBuilder::default()
        .existential_deposit(2)
        .monied(true)
        .build()
        .execute_with(|| {
            assert_eq!(System::inc_providers(&1), frame_system::IncRefStatus::Existed);
            assert_eq!(System::providers(&1), 2);
            assert_eq!(Balances::free_balance(1), 20);
            assert_ok!(<Balances as Currency<_>>::transfer(&1, &2, 19, AllowDeath));
            assert!(System::account_exists(&1));
            assert_eq!(Balances::free_balance(1), 0);
            assert_eq!(System::providers(&1), 1);
        });
}

What we see here is that the account is not reaped in the sense that it still exists, but it does get dusted. This seems to contradict info I got on GitHub, but maybe I'm just reading this wrong (https://github.com/paritytech/polkadot-sdk/issues/227). The docs also say that reference counters prevent the account from being reaped. So I'm starting to get the impression that reaping and dusting are two completely separate processes.

The questions are:

  1. Is the behavior above expected or is this a bug?
  2. Are reaping and dusting separate processes?
  3. How can I whitelist an account in pallet-balances to prevent it from getting dusted?

Edit. I may have misread some of the docs. So apparently we can use consumers to make the transfer error. Doesn't answer any of the questions though.

3
  • Which line in the test are you confused about? Sep 4 at 8:39
  • assert_eq!(Balances::free_balance(1), 0); According to the claim on GitHub, this should fail.
    – mkl
    Sep 4 at 12:51
  • I think he means reaped in stead of dusted. Sep 5 at 10:18

1 Answer 1

2
+50

Are reaping and dusting separate processes?

Yes, this made it clear to me:

  • dusting: removing remaining balance (e.g. after a transfer) if it is lower than the ED.
  • reaping: removing an account from storage.

How can I whitelist an account in pallet-balances to prevent it from getting dusted?

I don't think that is currently possible. There is no way to prevent this other than setting no ED or having free_balance + reserved_balance > ED(ref). However, if you call transfer with Preservation::Preserve in stead of Preservation::Expendable, it will fail (ref).

Is the behavior above expected or is this a bug?

From reading the README:

No account should ever have a total balance that is strictly between 0 and the existential deposit (exclusive). If this ever happens, it indicates either a bug in this module or an erroneous raw mutation of storage.

Which in the test case you did, you increased the providers. So I think it is the expected behaviour.

4
  • Increasing providers is an erroneous raw mutation? Why? Also, the first link you provide seems to suggest that if there is a provider, the account won't get dusted. Is that correct?
    – mkl
    Sep 5 at 10:46
  • 1. Well why are you increasing it to two? 2. If Preserve the balance transfer will fail if the amount gets below the ED. Sep 5 at 11:09
  • I concede that increasing it is unnecessary, but why is it not allowed?
    – mkl
    Sep 5 at 11:18
  • That would require a deeper look into the pallet and a separate question. Sep 5 at 11:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.