From 50a2c96c3bda2024c1a4c1ef550e6377606f0b2b Mon Sep 17 00:00:00 2001 From: Brandon Weng <18161326+BrandonWeng@users.noreply.github.com> Date: Fri, 28 Oct 2022 00:40:09 -0400 Subject: [PATCH 1/2] Fix Unit test --- x/bank/keeper/keeper.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index eaa8d1a95..06fa0581c 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -357,15 +357,19 @@ func (k BaseKeeper) DeferredSendCoinsFromModuleToAccount( return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", recipientAddr) } - // Branch Context for validation and fail if the module doesn't have enough coins - // but don't write this to the underlying store - validationContext, _ := ctx.CacheContext() - err := k.subUnlockedCoins(validationContext, moduleAddr, amount) - if err != nil { - return err + // Subtract from any pending sends fist + ok := ctx.ContextMemCache().SafeSubDeferredSends(moduleAccount, amount) + if !ok { + // Branch Context for validation and fail if the module doesn't have enough coins + // but don't write this to the underlying store + validationContext, _ := ctx.CacheContext() + err := k.subUnlockedCoins(validationContext, moduleAddr, amount) + if err != nil { + return err + } } - err = k.addCoins(ctx, recipientAddr, amount) + err := k.addCoins(ctx, recipientAddr, amount) if err != nil { return err } From 5c3941e396f497fac23ad84ff3591d9b92f81932 Mon Sep 17 00:00:00 2001 From: Brandon Weng <18161326+BrandonWeng@users.noreply.github.com> Date: Fri, 28 Oct 2022 09:25:06 -0400 Subject: [PATCH 2/2] Fix Unit test --- x/bank/keeper/keeper.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index 06fa0581c..8af28ed44 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -623,6 +623,14 @@ func (k BaseKeeper) destroyCoins(ctx sdk.Context, moduleName string, amounts sdk // It will panic if the module account does not exist or is unauthorized. func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amounts sdk.Coins) error { subFn := func(ctx sdk.Context, moduleName string, amounts sdk.Coins) error { + + // Try subtract from the in mem var first, prevents the condition where + // the module may have a pending deposit that would be enough to pay for this send + ok := ctx.ContextMemCache().SafeSubDeferredSends(moduleName, amounts) + if ok { + return nil + } + acc := k.ak.GetModuleAccount(ctx, moduleName) return k.subUnlockedCoins(ctx, acc.GetAddress(), amounts) } @@ -646,8 +654,16 @@ func (k BaseKeeper) DeferredBurnCoins(ctx sdk.Context, moduleName string, amount // Branch Context for validation and fail if the module doesn't have enough coins // but don't write this to the underlying store validationContext, _ := ctx.CacheContext() - acc := k.ak.GetModuleAccount(ctx, moduleName) - err := k.subUnlockedCoins(validationContext, acc.GetAddress(), amounts) + moduleAcc := k.ak.GetModuleAccount(ctx, moduleName) + + // Try subtract from the in mem var first, prevents the condition where + // the module may have a pending deposit that would be enough to pay for this send + ok := ctx.ContextMemCache().SafeSubDeferredSends(moduleName, amounts) + if ok { + return nil + } + + err := k.subUnlockedCoins(validationContext, moduleAcc.GetAddress(), amounts) if err != nil { return err }