-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(bank/v2): Add MsgSend handler #21736
Changes from all commits
41f7632
1eb5c65
845510c
37cc625
f0187dc
f50fc0d
f1edd6e
1f005a4
f04ba3d
d0ff17c
5e5fb05
9bf855d
36d8752
f774b20
cadfdbe
2167d51
3e9a53d
29c9a8f
3778b6f
1645d00
44c3faa
76e89cc
3aafcb0
0b5d9f3
8e8297a
1fa11c9
829c03c
f9fe061
60485a0
d94ccad
b82b96c
6581309
2e312e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ import ( | |
"cosmossdk.io/server/v2/cometbft" | ||
"cosmossdk.io/server/v2/store" | ||
banktypes "cosmossdk.io/x/bank/types" | ||
bankv2types "cosmossdk.io/x/bank/v2/types" | ||
stakingtypes "cosmossdk.io/x/staking/types" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
|
@@ -402,6 +403,13 @@ func initGenFiles[T transaction.Tx]( | |
} | ||
appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState) | ||
|
||
var bankV2GenState bankv2types.GenesisState | ||
clientCtx.Codec.MustUnmarshalJSON(appGenState[bankv2types.ModuleName], &bankV2GenState) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why we need this step as you are assigning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes should remove it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the fallback tbh for now, maybe we should check |
||
if len(bankV2GenState.Balances) == 0 { | ||
bankV2GenState = getBankV2GenesisFromV1(bankGenState) | ||
} | ||
appGenState[bankv2types.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankV2GenState) | ||
|
||
appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ") | ||
if err != nil { | ||
return err | ||
|
@@ -504,3 +512,16 @@ func writeFile(name, dir string, contents []byte) error { | |
|
||
return os.WriteFile(file, contents, 0o600) | ||
} | ||
|
||
// getBankV2GenesisFromV1 clones bank/v1 state to bank/v2 | ||
// since we not migrate yet | ||
// TODO: Remove | ||
func getBankV2GenesisFromV1(v1GenesisState banktypes.GenesisState) bankv2types.GenesisState { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's add a comment on the rationale of doing this (basically, to be deleted after genesis migration command addition) |
||
var v2GenesisState bankv2types.GenesisState | ||
for _, balance := range v1GenesisState.Balances { | ||
v2Balance := bankv2types.Balance(balance) | ||
v2GenesisState.Balances = append(v2GenesisState.Balances, v2Balance) | ||
v2GenesisState.Supply = v2GenesisState.Supply.Add(balance.Coins...) | ||
} | ||
return v2GenesisState | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
//go:build system_test | ||
|
||
package systemtests | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"github.com/tidwall/gjson" | ||
) | ||
|
||
func TestBankV2SendTxCmd(t *testing.T) { | ||
// Currently only run with app v2 | ||
if !isV2() { | ||
t.Skip() | ||
} | ||
// scenario: test bank send command | ||
// given a running chain | ||
|
||
sut.ResetChain(t) | ||
cli := NewCLIWrapper(t, sut, verbose) | ||
|
||
// get validator address | ||
valAddr := gjson.Get(cli.Keys("keys", "list"), "1.address").String() | ||
require.NotEmpty(t, valAddr) | ||
|
||
// add new key | ||
receiverAddr := cli.AddKey("account1") | ||
denom := "stake" | ||
sut.StartChain(t) | ||
|
||
// query validator balance and make sure it has enough balance | ||
var transferAmount int64 = 1000 | ||
raw := cli.CustomQuery("q", "bankv2", "balance", valAddr, denom) | ||
valBalance := gjson.Get(raw, "balance.amount").Int() | ||
|
||
require.Greater(t, valBalance, transferAmount, "not enough balance found with validator") | ||
|
||
bankSendCmdArgs := []string{"tx", "bankv2", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom)} | ||
|
||
// test valid transaction | ||
rsp := cli.Run(append(bankSendCmdArgs, "--fees=1stake")...) | ||
txResult, found := cli.AwaitTxCommitted(rsp) | ||
require.True(t, found) | ||
RequireTxSuccess(t, txResult) | ||
hieuvubk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Check balance after send | ||
valRaw := cli.CustomQuery("q", "bankv2", "balance", valAddr, denom) | ||
valBalanceAfer := gjson.Get(valRaw, "balance.amount").Int() | ||
|
||
// TODO: Make DeductFee ante handler work with bank/v2 | ||
require.Equal(t, valBalanceAfer, valBalance - transferAmount) | ||
|
||
receiverRaw := cli.CustomQuery("q", "bankv2", "balance", receiverAddr, denom) | ||
receiverBalance := gjson.Get(receiverRaw, "balance.amount").Int() | ||
require.Equal(t, receiverBalance, transferAmount) | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package cli | ||
|
||
import ( | ||
"errors" | ||
|
||
gogoproto "github.com/cosmos/gogoproto/proto" | ||
"github.com/spf13/cobra" | ||
|
||
"cosmossdk.io/x/bank/v2/types" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
const ( | ||
FlagDenom = "denom" | ||
) | ||
|
||
// GetQueryCmd returns the parent command for all x/bank CLi query commands. The | ||
// provided clientCtx should have, at a minimum, a verifier, Tendermint RPC client, | ||
// and marshaler set. | ||
func GetQueryCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: types.ModuleName, | ||
Short: "Querying commands for the bank module", | ||
DisableFlagParsing: true, | ||
SuggestionsMinimumDistance: 2, | ||
RunE: client.ValidateCmd, | ||
} | ||
|
||
cmd.AddCommand( | ||
GetBalanceCmd(), | ||
) | ||
|
||
return cmd | ||
} | ||
|
||
func GetBalanceCmd() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "balance [address] [denom]", | ||
Short: "Query an account balance by address and denom", | ||
Args: cobra.ExactArgs(2), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
clientCtx, err := client.GetClientQueryContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
denom := args[1] | ||
if denom == "" { | ||
return errors.New("empty denom") | ||
} | ||
|
||
addr, err := sdk.AccAddressFromBech32(args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ctx := cmd.Context() | ||
|
||
req := types.NewQueryBalanceRequest(addr.String(), denom) | ||
out := new(types.QueryBalanceResponse) | ||
|
||
err = clientCtx.Invoke(ctx, gogoproto.MessageName(&types.QueryBalanceRequest{}), req, out) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return clientCtx.PrintProto(out) | ||
}, | ||
} | ||
|
||
cmd.Flags().String(FlagDenom, "", "The specific balance denomination to query for") | ||
flags.AddQueryFlagsToCmd(cmd) | ||
flags.AddPaginationFlagsToCmd(cmd, "all balances") | ||
|
||
return cmd | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning