github.com/cosmos/cosmos-sdk@v0.50.10/x/staking/types/authz_test.go (about)

     1  package types_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	coreheader "cosmossdk.io/core/header"
     9  	storetypes "cosmossdk.io/store/types"
    10  
    11  	"github.com/cosmos/cosmos-sdk/testutil"
    12  	sdk "github.com/cosmos/cosmos-sdk/types"
    13  	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
    14  )
    15  
    16  var (
    17  	coin100 = sdk.NewInt64Coin("steak", 100)
    18  	coin150 = sdk.NewInt64Coin("steak", 150)
    19  	coin50  = sdk.NewInt64Coin("steak", 50)
    20  	delAddr = sdk.AccAddress("_____delegator _____")
    21  	val1    = sdk.ValAddress("_____validator1_____")
    22  	val2    = sdk.ValAddress("_____validator2_____")
    23  	val3    = sdk.ValAddress("_____validator3_____")
    24  )
    25  
    26  func TestAuthzAuthorizations(t *testing.T) {
    27  	key := storetypes.NewKVStoreKey(stakingtypes.StoreKey)
    28  	testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
    29  	ctx := testCtx.Ctx.WithHeaderInfo(coreheader.Info{})
    30  
    31  	// verify ValidateBasic returns error for the AUTHORIZATION_TYPE_UNSPECIFIED authorization type
    32  	delAuth, err := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNSPECIFIED, &coin100)
    33  	require.NoError(t, err)
    34  	require.Error(t, delAuth.ValidateBasic())
    35  
    36  	// verify MethodName
    37  	delAuth, err = stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100)
    38  	require.NoError(t, err)
    39  	require.Equal(t, delAuth.MsgTypeURL(), sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}))
    40  
    41  	// error both allow & deny list
    42  	_, err = stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{val1}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, &coin100)
    43  	require.Error(t, err)
    44  
    45  	// verify MethodName
    46  	undelAuth, _ := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE, &coin100)
    47  	require.Equal(t, undelAuth.MsgTypeURL(), sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{}))
    48  
    49  	// verify MethodName
    50  	beginRedelAuth, _ := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE, &coin100)
    51  	require.Equal(t, beginRedelAuth.MsgTypeURL(), sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{}))
    52  
    53  	// verify MethodName for CancelUnbondingDelegation
    54  	cancelUnbondAuth, _ := stakingtypes.NewStakeAuthorization([]sdk.ValAddress{val1, val2}, []sdk.ValAddress{}, stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION, &coin100)
    55  	require.Equal(t, cancelUnbondAuth.MsgTypeURL(), sdk.MsgTypeURL(&stakingtypes.MsgCancelUnbondingDelegation{}))
    56  
    57  	validators1_2 := []string{val1.String(), val2.String()}
    58  
    59  	testCases := []struct {
    60  		msg                  string
    61  		allowed              []sdk.ValAddress
    62  		denied               []sdk.ValAddress
    63  		msgType              stakingtypes.AuthorizationType
    64  		limit                *sdk.Coin
    65  		srvMsg               sdk.Msg
    66  		expectErr            bool
    67  		isDelete             bool
    68  		updatedAuthorization *stakingtypes.StakeAuthorization
    69  	}{
    70  		{
    71  			"delegate: expect 0 remaining coins",
    72  			[]sdk.ValAddress{val1, val2},
    73  			[]sdk.ValAddress{},
    74  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
    75  			&coin100,
    76  			stakingtypes.NewMsgDelegate(delAddr.String(), val1.String(), coin100),
    77  			false,
    78  			true,
    79  			nil,
    80  		},
    81  		{
    82  			"delegate: coins more than allowed",
    83  			[]sdk.ValAddress{val1, val2},
    84  			[]sdk.ValAddress{},
    85  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
    86  			&coin100,
    87  			stakingtypes.NewMsgDelegate(delAddr.String(), val1.String(), coin150),
    88  			true,
    89  			false,
    90  			nil,
    91  		},
    92  		{
    93  			"delegate: verify remaining coins",
    94  			[]sdk.ValAddress{val1, val2},
    95  			[]sdk.ValAddress{},
    96  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
    97  			&coin100,
    98  			stakingtypes.NewMsgDelegate(delAddr.String(), val1.String(), coin50),
    99  			false,
   100  			false,
   101  			&stakingtypes.StakeAuthorization{
   102  				Validators: &stakingtypes.StakeAuthorization_AllowList{
   103  					AllowList: &stakingtypes.StakeAuthorization_Validators{Address: validators1_2},
   104  				}, MaxTokens: &coin50, AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
   105  			},
   106  		},
   107  		{
   108  			"delegate: testing with invalid validator",
   109  			[]sdk.ValAddress{val1, val2},
   110  			[]sdk.ValAddress{},
   111  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
   112  			&coin100,
   113  			stakingtypes.NewMsgDelegate(delAddr.String(), val3.String(), coin100),
   114  			true,
   115  			false,
   116  			nil,
   117  		},
   118  		{
   119  			"delegate: testing delegate without spent limit",
   120  			[]sdk.ValAddress{val1, val2},
   121  			[]sdk.ValAddress{},
   122  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
   123  			nil,
   124  			stakingtypes.NewMsgDelegate(delAddr.String(), val2.String(), coin100),
   125  			false,
   126  			false,
   127  			&stakingtypes.StakeAuthorization{
   128  				Validators: &stakingtypes.StakeAuthorization_AllowList{
   129  					AllowList: &stakingtypes.StakeAuthorization_Validators{Address: validators1_2},
   130  				}, MaxTokens: nil, AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
   131  			},
   132  		},
   133  		{
   134  			"delegate: fail validator denied",
   135  			[]sdk.ValAddress{},
   136  			[]sdk.ValAddress{val1},
   137  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
   138  			nil,
   139  			stakingtypes.NewMsgDelegate(delAddr.String(), val1.String(), coin100),
   140  			true,
   141  			false,
   142  			nil,
   143  		},
   144  		{
   145  			"delegate: testing with a validator out of denylist",
   146  			[]sdk.ValAddress{},
   147  			[]sdk.ValAddress{val1},
   148  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
   149  			nil,
   150  			stakingtypes.NewMsgDelegate(delAddr.String(), val2.String(), coin100),
   151  			false,
   152  			false,
   153  			&stakingtypes.StakeAuthorization{
   154  				Validators: &stakingtypes.StakeAuthorization_DenyList{
   155  					DenyList: &stakingtypes.StakeAuthorization_Validators{Address: []string{val1.String()}},
   156  				}, MaxTokens: nil, AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
   157  			},
   158  		},
   159  		{
   160  			"undelegate: expect 0 remaining coins",
   161  			[]sdk.ValAddress{val1, val2},
   162  			[]sdk.ValAddress{},
   163  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
   164  			&coin100,
   165  			stakingtypes.NewMsgUndelegate(delAddr.String(), val1.String(), coin100),
   166  			false,
   167  			true,
   168  			nil,
   169  		},
   170  		{
   171  			"undelegate: verify remaining coins",
   172  			[]sdk.ValAddress{val1, val2},
   173  			[]sdk.ValAddress{},
   174  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
   175  			&coin100,
   176  			stakingtypes.NewMsgUndelegate(delAddr.String(), val1.String(), coin50),
   177  			false,
   178  			false,
   179  			&stakingtypes.StakeAuthorization{
   180  				Validators: &stakingtypes.StakeAuthorization_AllowList{
   181  					AllowList: &stakingtypes.StakeAuthorization_Validators{Address: validators1_2},
   182  				}, MaxTokens: &coin50, AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
   183  			},
   184  		},
   185  		{
   186  			"undelegate: testing with invalid validator",
   187  			[]sdk.ValAddress{val1, val2},
   188  			[]sdk.ValAddress{},
   189  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
   190  			&coin100,
   191  			stakingtypes.NewMsgUndelegate(delAddr.String(), val3.String(), coin100),
   192  			true,
   193  			false,
   194  			nil,
   195  		},
   196  		{
   197  			"undelegate: testing delegate without spent limit",
   198  			[]sdk.ValAddress{val1, val2},
   199  			[]sdk.ValAddress{},
   200  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
   201  			nil,
   202  			stakingtypes.NewMsgUndelegate(delAddr.String(), val2.String(), coin100),
   203  			false,
   204  			false,
   205  			&stakingtypes.StakeAuthorization{
   206  				Validators: &stakingtypes.StakeAuthorization_AllowList{
   207  					AllowList: &stakingtypes.StakeAuthorization_Validators{Address: validators1_2},
   208  				}, MaxTokens: nil, AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
   209  			},
   210  		},
   211  		{
   212  			"undelegate: fail cannot undelegate, permission denied",
   213  			[]sdk.ValAddress{},
   214  			[]sdk.ValAddress{val1},
   215  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
   216  			&coin100,
   217  			stakingtypes.NewMsgUndelegate(delAddr.String(), val1.String(), coin100),
   218  			true,
   219  			false,
   220  			nil,
   221  		},
   222  
   223  		{
   224  			"redelegate: expect 0 remaining coins",
   225  			[]sdk.ValAddress{val1, val2},
   226  			[]sdk.ValAddress{},
   227  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE,
   228  			&coin100,
   229  			stakingtypes.NewMsgUndelegate(delAddr.String(), val1.String(), coin100),
   230  			false,
   231  			true,
   232  			nil,
   233  		},
   234  		{
   235  			"redelegate: verify remaining coins",
   236  			[]sdk.ValAddress{val1, val2},
   237  			[]sdk.ValAddress{},
   238  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE,
   239  			&coin100,
   240  			stakingtypes.NewMsgBeginRedelegate(delAddr.String(), val1.String(), val1.String(), coin50),
   241  			false,
   242  			false,
   243  			&stakingtypes.StakeAuthorization{
   244  				Validators: &stakingtypes.StakeAuthorization_AllowList{
   245  					AllowList: &stakingtypes.StakeAuthorization_Validators{Address: validators1_2},
   246  				}, MaxTokens: &coin50, AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE,
   247  			},
   248  		},
   249  		{
   250  			"redelegate: testing with invalid validator",
   251  			[]sdk.ValAddress{val1, val2},
   252  			[]sdk.ValAddress{},
   253  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE,
   254  			&coin100,
   255  			stakingtypes.NewMsgBeginRedelegate(delAddr.String(), val3.String(), val3.String(), coin100),
   256  			true,
   257  			false,
   258  			nil,
   259  		},
   260  		{
   261  			"redelegate: testing delegate without spent limit",
   262  			[]sdk.ValAddress{val1, val2},
   263  			[]sdk.ValAddress{},
   264  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE,
   265  			nil,
   266  			stakingtypes.NewMsgBeginRedelegate(delAddr.String(), val2.String(), val2.String(), coin100),
   267  			false,
   268  			false,
   269  			&stakingtypes.StakeAuthorization{
   270  				Validators: &stakingtypes.StakeAuthorization_AllowList{
   271  					AllowList: &stakingtypes.StakeAuthorization_Validators{Address: validators1_2},
   272  				}, MaxTokens: nil, AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE,
   273  			},
   274  		},
   275  		{
   276  			"redelegate: fail cannot undelegate, permission denied",
   277  			[]sdk.ValAddress{},
   278  			[]sdk.ValAddress{val1},
   279  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE,
   280  			&coin100,
   281  			stakingtypes.NewMsgBeginRedelegate(delAddr.String(), val1.String(), val1.String(), coin100),
   282  			true,
   283  			false,
   284  			nil,
   285  		},
   286  		{
   287  			"cancel unbonding delegation: expect 0 remaining coins",
   288  			[]sdk.ValAddress{val1},
   289  			[]sdk.ValAddress{},
   290  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION,
   291  			&coin100,
   292  			stakingtypes.NewMsgCancelUnbondingDelegation(delAddr.String(), val1.String(), ctx.HeaderInfo().Height, coin100),
   293  			false,
   294  			true,
   295  			nil,
   296  		},
   297  		{
   298  			"cancel unbonding delegation: verify remaining coins",
   299  			[]sdk.ValAddress{val1},
   300  			[]sdk.ValAddress{},
   301  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION,
   302  			&coin100,
   303  			stakingtypes.NewMsgCancelUnbondingDelegation(delAddr.String(), val1.String(), ctx.HeaderInfo().Height, coin50),
   304  			false,
   305  			false,
   306  			&stakingtypes.StakeAuthorization{
   307  				Validators: &stakingtypes.StakeAuthorization_AllowList{
   308  					AllowList: &stakingtypes.StakeAuthorization_Validators{Address: []string{val1.String()}},
   309  				},
   310  				MaxTokens:         &coin50,
   311  				AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION,
   312  			},
   313  		},
   314  		{
   315  			"cancel unbonding delegation: testing with invalid validator",
   316  			[]sdk.ValAddress{val1, val2},
   317  			[]sdk.ValAddress{},
   318  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION,
   319  			&coin100,
   320  			stakingtypes.NewMsgCancelUnbondingDelegation(delAddr.String(), val3.String(), ctx.HeaderInfo().Height, coin50),
   321  			true,
   322  			false,
   323  			nil,
   324  		},
   325  		{
   326  			"cancel unbonding delegation: testing delegate without spent limit",
   327  			[]sdk.ValAddress{val1, val2},
   328  			[]sdk.ValAddress{},
   329  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION,
   330  			nil,
   331  			stakingtypes.NewMsgCancelUnbondingDelegation(delAddr.String(), val2.String(), ctx.HeaderInfo().Height, coin100),
   332  			false,
   333  			false,
   334  			&stakingtypes.StakeAuthorization{
   335  				Validators: &stakingtypes.StakeAuthorization_AllowList{
   336  					AllowList: &stakingtypes.StakeAuthorization_Validators{Address: validators1_2},
   337  				},
   338  				MaxTokens:         nil,
   339  				AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION,
   340  			},
   341  		},
   342  		{
   343  			"cancel unbonding delegation: fail cannot undelegate, permission denied",
   344  			[]sdk.ValAddress{},
   345  			[]sdk.ValAddress{val1},
   346  			stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION,
   347  			&coin100,
   348  			stakingtypes.NewMsgCancelUnbondingDelegation(delAddr.String(), val1.String(), ctx.HeaderInfo().Height, coin100),
   349  			true,
   350  			false,
   351  			nil,
   352  		},
   353  	}
   354  
   355  	for _, tc := range testCases {
   356  		tc := tc
   357  		t.Run(tc.msg, func(t *testing.T) {
   358  			delAuth, err := stakingtypes.NewStakeAuthorization(tc.allowed, tc.denied, tc.msgType, tc.limit)
   359  			require.NoError(t, err)
   360  			resp, err := delAuth.Accept(ctx, tc.srvMsg)
   361  			require.Equal(t, tc.isDelete, resp.Delete)
   362  			if tc.expectErr {
   363  				require.Error(t, err)
   364  			} else {
   365  				require.NoError(t, err)
   366  				if tc.updatedAuthorization != nil {
   367  					require.Equal(t, tc.updatedAuthorization.String(), resp.Updated.String())
   368  				}
   369  			}
   370  		})
   371  	}
   372  }