diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index c6a2252df610..32f98e775fc9 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -908,6 +908,16 @@ pub mod pallet { pub(crate) fn try_mutate_account>( who: &T::AccountId, f: impl FnOnce(&mut AccountData, bool) -> Result, + ) -> Result<(R, Option), E> { + frame_support::storage::transactional::with_storage_layer(|| { + Self::try_mutate_account_inner(who, f) + }) + } + + /// Implementation of [`Self::try_mutate_account`]. + fn try_mutate_account_inner>( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData, bool) -> Result, ) -> Result<(R, Option), E> { Self::ensure_upgraded(who); let result = T::AccountStore::try_mutate_exists(who, |maybe_account| { diff --git a/substrate/frame/balances/src/tests/dispatchable_tests.rs b/substrate/frame/balances/src/tests/dispatchable_tests.rs index 8f625a189446..703ec250f423 100644 --- a/substrate/frame/balances/src/tests/dispatchable_tests.rs +++ b/substrate/frame/balances/src/tests/dispatchable_tests.rs @@ -222,3 +222,23 @@ fn upgrade_accounts_should_work() { assert_eq!(System::consumers(&7), 0); }); } + +#[test] +fn withdraw_error_does_not_modify_issuance() { + use frame_support::traits::{Currency, ExistenceRequirement::AllowDeath, WithdrawReasons}; + + ExtBuilder::default().existential_deposit(10).build_and_execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + System::inc_consumers(&1).unwrap(); + + assert_noop!( + >::withdraw( + &1, + 95, + WithdrawReasons::TRANSFER, + AllowDeath + ), + DispatchError::ConsumerRemaining, + ); + }); +}