github.com/cosmos/cosmos-sdk@v0.50.10/x/authz/msgs_test.go (about)

     1  package authz_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/cosmos/gogoproto/proto"
    10  	"github.com/stretchr/testify/require"
    11  	"google.golang.org/protobuf/types/known/anypb"
    12  
    13  	txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
    14  	sdkmath "cosmossdk.io/math"
    15  	txsigning "cosmossdk.io/x/tx/signing"
    16  	"cosmossdk.io/x/tx/signing/aminojson"
    17  
    18  	"github.com/cosmos/cosmos-sdk/codec"
    19  	cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
    20  	sdk "github.com/cosmos/cosmos-sdk/types"
    21  	"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
    22  	"github.com/cosmos/cosmos-sdk/x/authz"
    23  	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
    24  	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
    25  )
    26  
    27  func TestMsgGrantGetAuthorization(t *testing.T) {
    28  	require := require.New(t)
    29  
    30  	m := authz.MsgGrant{}
    31  	require.Nil(m.GetAuthorization())
    32  
    33  	g := authz.GenericAuthorization{Msg: "some_type"}
    34  	var err error
    35  	m.Grant.Authorization, err = cdctypes.NewAnyWithValue(&g)
    36  	require.NoError(err)
    37  
    38  	a, err := m.GetAuthorization()
    39  	require.NoError(err)
    40  	require.Equal(a, &g)
    41  
    42  	g = authz.GenericAuthorization{Msg: "some_type2"}
    43  	m.SetAuthorization(&g)
    44  	a, err = m.GetAuthorization()
    45  	require.NoError(err)
    46  	require.Equal(a, &g)
    47  }
    48  
    49  func TestAminoJSON(t *testing.T) {
    50  	legacyAmino := codec.NewLegacyAmino()
    51  	authz.RegisterLegacyAminoCodec(legacyAmino)
    52  	banktypes.RegisterLegacyAminoCodec(legacyAmino)
    53  	stakingtypes.RegisterLegacyAminoCodec(legacyAmino)
    54  	legacytx.RegressionTestingAminoCodec = legacyAmino
    55  
    56  	aminoHandler := aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{
    57  		FileResolver: proto.HybridResolver,
    58  	})
    59  
    60  	tx := legacytx.StdTx{}
    61  	blockTime := time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC)
    62  	expiresAt := blockTime.Add(time.Hour)
    63  	msgSend := banktypes.MsgSend{FromAddress: "cosmos1ghi", ToAddress: "cosmos1jkl"}
    64  	typeURL := sdk.MsgTypeURL(&msgSend)
    65  	msgSendAny, err := cdctypes.NewAnyWithValue(&msgSend)
    66  	require.NoError(t, err)
    67  	grant, err := authz.NewGrant(blockTime, authz.NewGenericAuthorization(typeURL), &expiresAt)
    68  	require.NoError(t, err)
    69  	sendAuthz := banktypes.NewSendAuthorization(sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(1000))), nil)
    70  	sendGrant, err := authz.NewGrant(blockTime, sendAuthz, &expiresAt)
    71  	require.NoError(t, err)
    72  	valAddr, err := sdk.ValAddressFromBech32("cosmosvaloper1xcy3els9ua75kdm783c3qu0rfa2eples6eavqq")
    73  	require.NoError(t, err)
    74  	stakingAuth, err := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{valAddr}, nil, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &sdk.Coin{Denom: "stake", Amount: sdkmath.NewInt(1000)})
    75  	require.NoError(t, err)
    76  	delegateGrant, err := authz.NewGrant(blockTime, stakingAuth, nil)
    77  	require.NoError(t, err)
    78  
    79  	// Amino JSON encoding has changed in authz since v0.46.
    80  	// Before, it was outputting something like:
    81  	// `{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"grant":{"authorization":{"msg":"/cosmos.bank.v1beta1.MsgSend"},"expiration":"0001-01-01T02:01:01.000000001Z"},"grantee":"cosmos1def","granter":"cosmos1abc"}],"sequence":"1","timeout_height":"1"}`
    82  	//
    83  	// This was a bug. Now, it's as below, See how there's `type` & `value` fields.
    84  	// ref: https://github.com/cosmos/cosmos-sdk/issues/11190
    85  	// ref: https://github.com/cosmos/cosmjs/issues/1026
    86  	tests := []struct {
    87  		msg sdk.Msg
    88  		exp string
    89  	}{
    90  		{
    91  			msg: &authz.MsgGrant{Granter: "cosmos1abc", Grantee: "cosmos1def", Grant: grant},
    92  			exp: `{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgGrant","value":{"grant":{"authorization":{"type":"cosmos-sdk/GenericAuthorization","value":{"msg":"/cosmos.bank.v1beta1.MsgSend"}},"expiration":"0001-01-01T02:01:01.000000001Z"},"grantee":"cosmos1def","granter":"cosmos1abc"}}],"sequence":"1","timeout_height":"1"}`,
    93  		},
    94  		{
    95  			msg: &authz.MsgGrant{Granter: "cosmos1abc", Grantee: "cosmos1def", Grant: sendGrant},
    96  			exp: `{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgGrant","value":{"grant":{"authorization":{"type":"cosmos-sdk/SendAuthorization","value":{"spend_limit":[{"amount":"1000","denom":"stake"}]}},"expiration":"0001-01-01T02:01:01.000000001Z"},"grantee":"cosmos1def","granter":"cosmos1abc"}}],"sequence":"1","timeout_height":"1"}`,
    97  		},
    98  		{
    99  			msg: &authz.MsgGrant{Granter: "cosmos1abc", Grantee: "cosmos1def", Grant: delegateGrant},
   100  			exp: `{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgGrant","value":{"grant":{"authorization":{"type":"cosmos-sdk/StakeAuthorization","value":{"Validators":{"type":"cosmos-sdk/StakeAuthorization/AllowList","value":{"allow_list":{"address":["cosmosvaloper1xcy3els9ua75kdm783c3qu0rfa2eples6eavqq"]}}},"authorization_type":1,"max_tokens":{"amount":"1000","denom":"stake"}}}},"grantee":"cosmos1def","granter":"cosmos1abc"}}],"sequence":"1","timeout_height":"1"}`,
   101  		},
   102  		{
   103  			msg: &authz.MsgRevoke{Granter: "cosmos1abc", Grantee: "cosmos1def", MsgTypeUrl: typeURL},
   104  			exp: `{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgRevoke","value":{"grantee":"cosmos1def","granter":"cosmos1abc","msg_type_url":"/cosmos.bank.v1beta1.MsgSend"}}],"sequence":"1","timeout_height":"1"}`,
   105  		},
   106  		{
   107  			msg: &authz.MsgExec{Grantee: "cosmos1def", Msgs: []*cdctypes.Any{msgSendAny}},
   108  			exp: `{"account_number":"1","chain_id":"foo","fee":{"amount":[],"gas":"0"},"memo":"memo","msgs":[{"type":"cosmos-sdk/MsgExec","value":{"grantee":"cosmos1def","msgs":[{"type":"cosmos-sdk/MsgSend","value":{"amount":[],"from_address":"cosmos1ghi","to_address":"cosmos1jkl"}}]}}],"sequence":"1","timeout_height":"1"}`,
   109  		},
   110  	}
   111  	for i, tt := range tests {
   112  		t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
   113  			tx.Msgs = []sdk.Msg{tt.msg}
   114  			legacyJSON := string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{tt.msg}, "memo"))
   115  			require.Equal(t, tt.exp, legacyJSON)
   116  
   117  			legacyAny, err := cdctypes.NewAnyWithValue(tt.msg)
   118  			require.NoError(t, err)
   119  			anyMsg := &anypb.Any{
   120  				TypeUrl: legacyAny.TypeUrl,
   121  				Value:   legacyAny.Value,
   122  			}
   123  			aminoJSON, err := aminoHandler.GetSignBytes(
   124  				context.TODO(),
   125  				txsigning.SignerData{
   126  					Address:       "foo",
   127  					ChainID:       "foo",
   128  					AccountNumber: 1,
   129  					Sequence:      1,
   130  				},
   131  				txsigning.TxData{
   132  					Body: &txv1beta1.TxBody{
   133  						Memo:          "memo",
   134  						Messages:      []*anypb.Any{anyMsg},
   135  						TimeoutHeight: 1,
   136  					},
   137  					AuthInfo: &txv1beta1.AuthInfo{
   138  						Fee: &txv1beta1.Fee{},
   139  					},
   140  				},
   141  			)
   142  			require.NoError(t, err)
   143  			require.Equal(t, tt.exp, string(aminoJSON))
   144  		})
   145  	}
   146  }