From cc283992e51b02d5f87ebdcf3403fb58d8cf1bb0 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Tue, 24 Jan 2023 09:03:11 +0100 Subject: [PATCH] Better to sdk coin convertion (#1164) * Better to sdk coin convertion * Review feedback (cherry picked from commit a925a9ed61752c335c66964ec4241dac5cb0ff70) --- x/wasm/keeper/handler_plugin.go | 3 + x/wasm/keeper/handler_plugin_encoders.go | 5 +- x/wasm/keeper/handler_plugin_encoders_test.go | 82 +++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/x/wasm/keeper/handler_plugin.go b/x/wasm/keeper/handler_plugin.go index 62fa51d53c..3f89612e3b 100644 --- a/x/wasm/keeper/handler_plugin.go +++ b/x/wasm/keeper/handler_plugin.go @@ -190,6 +190,9 @@ func NewBurnCoinMessageHandler(burner types.Burner) MessageHandlerFunc { if err != nil { return nil, nil, err } + if coins.IsZero() { + return nil, nil, types.ErrEmpty.Wrap("amount") + } if err := burner.SendCoinsFromAccountToModule(ctx, contractAddr, types.ModuleName, coins); err != nil { return nil, nil, sdkerrors.Wrap(err, "transfer to module") } diff --git a/x/wasm/keeper/handler_plugin_encoders.go b/x/wasm/keeper/handler_plugin_encoders.go index ed9a9eb9f3..123c80b5b2 100644 --- a/x/wasm/keeper/handler_plugin_encoders.go +++ b/x/wasm/keeper/handler_plugin_encoders.go @@ -330,10 +330,9 @@ func ConvertWasmCoinsToSdkCoins(coins []wasmvmtypes.Coin) (sdk.Coins, error) { if err != nil { return nil, err } - toSend = append(toSend, c) + toSend = toSend.Add(c) } - toSend.Sort() - return toSend, nil + return toSend.Sort(), nil } // ConvertWasmCoinToSdkCoin converts a wasm vm type coin to sdk type coin diff --git a/x/wasm/keeper/handler_plugin_encoders_test.go b/x/wasm/keeper/handler_plugin_encoders_test.go index 61f8ea0fb1..f82d668fda 100644 --- a/x/wasm/keeper/handler_plugin_encoders_test.go +++ b/x/wasm/keeper/handler_plugin_encoders_test.go @@ -635,3 +635,85 @@ func TestConvertWasmCoinToSdkCoin(t *testing.T) { }) } } + +func TestConvertWasmCoinsToSdkCoins(t *testing.T) { + specs := map[string]struct { + src []wasmvmtypes.Coin + exp sdk.Coins + expErr bool + }{ + "empty": { + src: []wasmvmtypes.Coin{}, + exp: nil, + }, + "single coin": { + src: []wasmvmtypes.Coin{{Denom: "foo", Amount: "1"}}, + exp: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1))), + }, + "multiple coins": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "1"}, + {Denom: "bar", Amount: "2"}, + }, + exp: sdk.NewCoins( + sdk.NewCoin("bar", sdk.NewInt(2)), + sdk.NewCoin("foo", sdk.NewInt(1)), + ), + }, + "sorted": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "1"}, + {Denom: "other", Amount: "1"}, + {Denom: "bar", Amount: "1"}, + }, + exp: []sdk.Coin{ + sdk.NewCoin("bar", sdk.NewInt(1)), + sdk.NewCoin("foo", sdk.NewInt(1)), + sdk.NewCoin("other", sdk.NewInt(1)), + }, + }, + "zero amounts dropped": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "1"}, + {Denom: "bar", Amount: "0"}, + }, + exp: sdk.NewCoins( + sdk.NewCoin("foo", sdk.NewInt(1)), + ), + }, + "duplicate denoms merged": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "1"}, + {Denom: "foo", Amount: "1"}, + }, + exp: []sdk.Coin{sdk.NewCoin("foo", sdk.NewInt(2))}, + }, + "duplicate denoms with one 0 amount does not fail": { + src: []wasmvmtypes.Coin{ + {Denom: "foo", Amount: "0"}, + {Denom: "foo", Amount: "1"}, + }, + exp: []sdk.Coin{sdk.NewCoin("foo", sdk.NewInt(1))}, + }, + "empty denom rejected": { + src: []wasmvmtypes.Coin{{Denom: "", Amount: "1"}}, + expErr: true, + }, + "invalid denom rejected": { + src: []wasmvmtypes.Coin{{Denom: "!%&", Amount: "1"}}, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + gotCoins, gotErr := ConvertWasmCoinsToSdkCoins(spec.src) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.exp, gotCoins) + assert.NoError(t, gotCoins.Validate()) + }) + } +}