From 864c6214711a3e57b35666180928a3a30038551c Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 10 Jul 2020 16:19:56 +0200 Subject: [PATCH] Save account for multi sending (#6674) Include changes from PR #6283 Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Alessio Treglia --- CHANGELOG.md | 2 +- x/bank/internal/keeper/keeper.go | 9 ++++++++ x/bank/internal/keeper/keeper_test.go | 32 +++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a9e68962ab1..829887e9e95c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -355,7 +355,7 @@ to detail this new feature and how state transitions occur. now exists a single `Params` type with a getter and setter along with a getter for each individual parameter. ### Bug Fixes - +* (x/bank) [\#6674](https://github.com/cosmos/cosmos-sdk/pull/6674) Create account if recipient does not exist on handing `MsgMultiSend`. * (rest) [\#5508](https://github.com/cosmos/cosmos-sdk/pull/5508) Fix `x/distribution` endpoints to properly return height in the response. * (x/genutil) [\#5499](https://github.com/cosmos/cosmos-sdk/pull/) Ensure `DefaultGenesis` returns valid and non-nil default genesis state. * (client) [\#5303](https://github.com/cosmos/cosmos-sdk/issues/5303) Fix ignored error in tx generate only mode. diff --git a/x/bank/internal/keeper/keeper.go b/x/bank/internal/keeper/keeper.go index 8e5f5faa5c8d..5f0dfed2b221 100644 --- a/x/bank/internal/keeper/keeper.go +++ b/x/bank/internal/keeper/keeper.go @@ -211,6 +211,15 @@ func (keeper BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.In sdk.NewAttribute(sdk.AttributeKeyAmount, out.Coins.String()), ), ) + + // Create account if recipient does not exist. + // + // NOTE: This should ultimately be removed in favor a more flexible approach + // such as delegated fee messages. + acc := keeper.ak.GetAccount(ctx, out.Address) + if acc == nil { + keeper.ak.SetAccount(ctx, keeper.ak.NewAccountWithAddress(ctx, out.Address)) + } } return nil diff --git a/x/bank/internal/keeper/keeper_test.go b/x/bank/internal/keeper/keeper_test.go index 1f8b38ab5723..e248df4b7698 100644 --- a/x/bank/internal/keeper/keeper_test.go +++ b/x/bank/internal/keeper/keeper_test.go @@ -149,6 +149,38 @@ func TestSendKeeper(t *testing.T) { require.Error(t, err) } +func TestInputOutputNewAccount(t *testing.T) { + app, ctx := createTestApp(false) + balances := sdk.NewCoins(sdk.NewInt64Coin("foo", 100), sdk.NewInt64Coin("bar", 50)) + addr1 := sdk.AccAddress([]byte("addr1")) + acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) + + app.AccountKeeper.SetAccount(ctx, acc1) + require.NoError(t, app.BankKeeper.SetCoins(ctx, addr1, balances)) + + acc1Balances := app.BankKeeper.GetCoins(ctx, addr1) + require.Equal(t, balances, acc1Balances) + + addr2 := sdk.AccAddress([]byte("addr2")) + + require.Nil(t, app.AccountKeeper.GetAccount(ctx, addr2)) + require.Empty(t, app.BankKeeper.GetCoins(ctx, addr2)) + + inputs := []types.Input{ + {Address: addr1, Coins: sdk.NewCoins(sdk.NewInt64Coin("foo", 30), sdk.NewInt64Coin("bar", 10))}, + } + outputs := []types.Output{ + {Address: addr2, Coins: sdk.NewCoins(sdk.NewInt64Coin("foo", 30), sdk.NewInt64Coin("bar", 10))}, + } + + require.NoError(t, app.BankKeeper.InputOutputCoins(ctx, inputs, outputs)) + + expected := sdk.NewCoins(sdk.NewInt64Coin("foo", 30), sdk.NewInt64Coin("bar", 10)) + acc2Balances := app.BankKeeper.GetCoins(ctx, addr2) + require.Equal(t, expected, acc2Balances) + require.NotNil(t, app.AccountKeeper.GetAccount(ctx, addr2)) +} + func TestMsgSendEvents(t *testing.T) { app, ctx := createTestApp(false)