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 }