Skip to content

Commit

Permalink
[14124]: Change InputOutputCoins to accept only a single input since …
Browse files Browse the repository at this point in the history
…the MsgMultiSend can now only contain a single input (#12610 and #12670).
  • Loading branch information
SpicyLemon committed Dec 8, 2022
1 parent 1648159 commit 66b2b93
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 75 deletions.
26 changes: 9 additions & 17 deletions tests/integration/bank/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,14 +392,12 @@ func (suite *IntegrationTestSuite) TestInputOutputNewAccount() {
suite.Require().Nil(suite.accountKeeper.GetAccount(ctx, addr2))
suite.Require().Empty(suite.bankKeeper.GetAllBalances(ctx, addr2))

inputs := []types.Input{
{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
}
input := types.Input{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))}
outputs := []types.Output{
{Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
}

suite.Require().NoError(suite.bankKeeper.InputOutputCoins(ctx, inputs, outputs))
suite.Require().NoError(suite.bankKeeper.InputOutputCoins(ctx, input, outputs))

expected := sdk.NewCoins(newFooCoin(30), newBarCoin(10))
acc2Balances := suite.bankKeeper.GetAllBalances(ctx, addr2)
Expand All @@ -423,9 +421,7 @@ func (suite *IntegrationTestSuite) TestInputOutputCoins() {
acc3 := suite.accountKeeper.NewAccountWithAddress(ctx, addr3)
suite.accountKeeper.SetAccount(ctx, acc3)

input := []types.Input{
{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(60), newBarCoin(20))},
}
input := types.Input{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(60), newBarCoin(20))}
outputs := []types.Output{
{Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
{Address: addr3.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
Expand All @@ -436,11 +432,9 @@ func (suite *IntegrationTestSuite) TestInputOutputCoins() {

suite.Require().NoError(testutil.FundAccount(suite.bankKeeper, ctx, addr1, balances))

insufficientInput := []types.Input{
{
Address: addr1.String(),
Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100)),
},
insufficientInput := types.Input{
Address: addr1.String(),
Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100)),
}
insufficientOutputs := []types.Output{
{Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))},
Expand Down Expand Up @@ -664,11 +658,9 @@ func (suite *IntegrationTestSuite) TestMsgMultiSendEvents() {
coins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50), sdk.NewInt64Coin(barDenom, 100))
newCoins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))
newCoins2 := sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100))
input := []types.Input{
{
Address: addr.String(),
Coins: coins,
},
input := types.Input{
Address: addr.String(),
Coins: coins,
}
outputs := []types.Output{
{Address: addr3.String(), Coins: newCoins},
Expand Down
40 changes: 16 additions & 24 deletions x/bank/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,14 +467,12 @@ func (suite *KeeperTestSuite) TestInputOutputNewAccount() {
require.Empty(suite.bankKeeper.GetAllBalances(ctx, accAddrs[1]))

suite.mockInputOutputCoins([]authtypes.AccountI{authtypes.NewBaseAccountWithAddress(accAddrs[0])}, []sdk.AccAddress{accAddrs[1]})
inputs := []banktypes.Input{
{Address: accAddrs[0].String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
}
input := banktypes.Input{Address: accAddrs[0].String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))}
outputs := []banktypes.Output{
{Address: accAddrs[1].String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
}

require.NoError(suite.bankKeeper.InputOutputCoins(ctx, inputs, outputs))
require.NoError(suite.bankKeeper.InputOutputCoins(ctx, input, outputs))

expected := sdk.NewCoins(newFooCoin(30), newBarCoin(10))
acc2Balances := suite.bankKeeper.GetAllBalances(ctx, accAddrs[1])
Expand All @@ -487,37 +485,33 @@ func (suite *KeeperTestSuite) TestInputOutputCoins() {
balances := sdk.NewCoins(newFooCoin(90), newBarCoin(30))

acc0 := authtypes.NewBaseAccountWithAddress(accAddrs[0])
inputs := []banktypes.Input{
{Address: accAddrs[0].String(), Coins: sdk.NewCoins(newFooCoin(60), newBarCoin(20))},
}
input := banktypes.Input{Address: accAddrs[0].String(), Coins: sdk.NewCoins(newFooCoin(60), newBarCoin(20))}
outputs := []banktypes.Output{
{Address: accAddrs[1].String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
{Address: accAddrs[2].String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
}

require.Error(suite.bankKeeper.InputOutputCoins(ctx, inputs, []banktypes.Output{}))
require.Error(suite.bankKeeper.InputOutputCoins(ctx, input, []banktypes.Output{}))

suite.authKeeper.EXPECT().GetAccount(suite.ctx, accAddrs[0]).Return(acc0)
require.Error(suite.bankKeeper.InputOutputCoins(ctx, inputs, outputs))
require.Error(suite.bankKeeper.InputOutputCoins(ctx, input, outputs))

suite.mockFundAccount(accAddrs[0])
require.NoError(banktestutil.FundAccount(suite.bankKeeper, ctx, accAddrs[0], balances))

insufficientInputs := []banktypes.Input{
{
Address: accAddrs[0].String(),
Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100)),
},
insufficientInput := banktypes.Input{
Address: accAddrs[0].String(),
Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100)),
}
insufficientOutputs := []banktypes.Output{
{Address: accAddrs[1].String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))},
{Address: accAddrs[2].String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))},
}

require.Error(suite.bankKeeper.InputOutputCoins(ctx, insufficientInputs, insufficientOutputs))
require.Error(suite.bankKeeper.InputOutputCoins(ctx, insufficientInput, insufficientOutputs))

suite.mockInputOutputCoins([]authtypes.AccountI{acc0}, accAddrs[1:3])
require.NoError(suite.bankKeeper.InputOutputCoins(ctx, inputs, outputs))
require.NoError(suite.bankKeeper.InputOutputCoins(ctx, input, outputs))

acc1Balances := suite.bankKeeper.GetAllBalances(ctx, accAddrs[0])
expected := sdk.NewCoins(newFooCoin(30), newBarCoin(10))
Expand Down Expand Up @@ -725,19 +719,17 @@ func (suite *KeeperTestSuite) TestMsgMultiSendEvents() {
coins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50), sdk.NewInt64Coin(barDenom, 100))
newCoins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))
newCoins2 := sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100))
inputs := []banktypes.Input{
{
Address: accAddrs[0].String(),
Coins: coins,
},
input := banktypes.Input{
Address: accAddrs[0].String(),
Coins: coins,
}
outputs := []banktypes.Output{
{Address: accAddrs[2].String(), Coins: newCoins},
{Address: accAddrs[3].String(), Coins: newCoins2},
}

suite.authKeeper.EXPECT().GetAccount(suite.ctx, accAddrs[0]).Return(acc0)
require.Error(suite.bankKeeper.InputOutputCoins(ctx, inputs, outputs))
require.Error(suite.bankKeeper.InputOutputCoins(ctx, input, outputs))

events := ctx.EventManager().ABCIEvents()
require.Equal(0, len(events))
Expand All @@ -747,7 +739,7 @@ func (suite *KeeperTestSuite) TestMsgMultiSendEvents() {
require.NoError(banktestutil.FundAccount(suite.bankKeeper, ctx, accAddrs[0], sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50), sdk.NewInt64Coin(barDenom, 100))))

suite.mockInputOutputCoins([]authtypes.AccountI{acc0}, accAddrs[2:4])
require.NoError(suite.bankKeeper.InputOutputCoins(ctx, inputs, outputs))
require.NoError(suite.bankKeeper.InputOutputCoins(ctx, input, outputs))

events = ctx.EventManager().ABCIEvents()
require.Equal(12, len(events)) // 12 events because account funding causes extra minting + coin_spent + coin_recv events
Expand All @@ -772,7 +764,7 @@ func (suite *KeeperTestSuite) TestMsgMultiSendEvents() {
newCoins2 = sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100))

suite.mockInputOutputCoins([]authtypes.AccountI{acc0}, accAddrs[2:4])
require.NoError(suite.bankKeeper.InputOutputCoins(ctx, inputs, outputs))
require.NoError(suite.bankKeeper.InputOutputCoins(ctx, input, outputs))

events = ctx.EventManager().ABCIEvents()
require.Equal(30, len(events)) // 27 due to account funding + coin_spent + coin_recv events
Expand Down
2 changes: 1 addition & 1 deletion x/bank/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (k msgServer) MultiSend(goCtx context.Context, msg *types.MsgMultiSend) (*t
}
}

err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs)
err := k.InputOutputCoins(ctx, msg.Inputs[0], msg.Outputs)
if err != nil {
return nil, err
}
Expand Down
40 changes: 19 additions & 21 deletions x/bank/keeper/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
type SendKeeper interface {
ViewKeeper

InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error
InputOutputCoins(ctx sdk.Context, input types.Input, outputs []types.Output) error
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error

GetParams(ctx sdk.Context) types.Params
Expand Down Expand Up @@ -119,33 +119,31 @@ func (k BaseSendKeeper) SetParams(ctx sdk.Context, params types.Params) error {
return nil
}

// InputOutputCoins performs multi-send functionality. It accepts a series of
// inputs that correspond to a series of outputs. It returns an error if the
// inputs and outputs don't line up or if any single transfer of tokens fails.
func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error {
// InputOutputCoins performs multi-send functionality. It accepts an
// input that corresponds to a series of outputs. It returns an error if the
// input and outputs don't line up or if any single transfer of tokens fails.
func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, input types.Input, outputs []types.Output) error {
// Safety check ensuring that when sending coins the keeper must maintain the
// Check supply invariant and validity of Coins.
if err := types.ValidateInputsOutputs(inputs, outputs); err != nil {
if err := types.ValidateInputOutputs(input, outputs); err != nil {
return err
}

for _, in := range inputs {
inAddress, err := sdk.AccAddressFromBech32(in.Address)
if err != nil {
return err
}
inAddress, err := sdk.AccAddressFromBech32(input.Address)
if err != nil {
return err
}

err = k.subUnlockedCoins(ctx, inAddress, in.Coins)
if err != nil {
return err
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(types.AttributeKeySender, in.Address),
),
)
err = k.subUnlockedCoins(ctx, inAddress, input.Coins)
if err != nil {
return err
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(types.AttributeKeySender, input.Address),
),
)

for _, out := range outputs {
outAddress, err := sdk.AccAddressFromBech32(out.Address)
Expand Down
14 changes: 6 additions & 8 deletions x/bank/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (msg MsgMultiSend) ValidateBasic() error {
return ErrNoOutputs
}

return ValidateInputsOutputs(msg.Inputs, msg.Outputs)
return ValidateInputOutputs(msg.Inputs[0], msg.Outputs)
}

// GetSignBytes Implements Msg.
Expand Down Expand Up @@ -165,17 +165,15 @@ func NewOutput(addr sdk.AccAddress, coins sdk.Coins) Output {
}
}

// ValidateInputsOutputs validates that each respective input and output is
// ValidateInputOutputs validates that each respective input and output is
// valid and that the sum of inputs is equal to the sum of outputs.
func ValidateInputsOutputs(inputs []Input, outputs []Output) error {
func ValidateInputOutputs(input Input, outputs []Output) error {
var totalIn, totalOut sdk.Coins

for _, in := range inputs {
if err := in.ValidateBasic(); err != nil {
return err
}
totalIn = totalIn.Add(in.Coins...)
if err := input.ValidateBasic(); err != nil {
return err
}
totalIn = input.Coins

for _, out := range outputs {
if err := out.ValidateBasic(); err != nil {
Expand Down
8 changes: 4 additions & 4 deletions x/gov/testutil/expected_keepers_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 66b2b93

Please sign in to comment.