github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/staking/delegator_test.go (about)

     1  package staking
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/fibonacci-chain/fbc/x/common"
     9  
    10  	"github.com/fibonacci-chain/fbc/x/staking/types"
    11  
    12  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    13  )
    14  
    15  func TestValidatorSMProxyDelegationSmoke(t *testing.T) {
    16  	common.InitConfig()
    17  	_, _, mk := CreateTestInput(t, false, SufficientInitPower)
    18  	params := DefaultParams()
    19  
    20  	originVaSet := addrVals[1:]
    21  	params.MaxValidators = uint16(len(originVaSet))
    22  	params.Epoch = 2
    23  	params.UnbondingTime = time.Millisecond * 300
    24  
    25  	startUpValidator := NewValidator(StartUpValidatorAddr, StartUpValidatorPubkey, Description{}, types.DefaultMinSelfDelegation)
    26  
    27  	startUpStatus := baseValidatorStatus{startUpValidator}
    28  
    29  	orgValsLen := len(originVaSet)
    30  	fullVaSet := make([]sdk.ValAddress, orgValsLen+1)
    31  	copy(fullVaSet, originVaSet)
    32  	copy(fullVaSet[orgValsLen:], []sdk.ValAddress{startUpStatus.getValidator().GetOperator()})
    33  
    34  	bAction := baseAction{mk}
    35  	proxyOriginTokens := MaxDelegatedToken
    36  	inputActions := []IAction{
    37  		createValidatorAction{bAction, nil},
    38  		delegatorDepositAction{bAction, ProxiedDelegator, proxyOriginTokens, sdk.DefaultBondDenom},
    39  		delegatorRegProxyAction{bAction, ProxiedDelegator, true},
    40  		proxyBindAction{bAction, ValidDelegator1, ProxiedDelegator},
    41  		proxyBindAction{bAction, ValidDelegator2, ProxiedDelegator},
    42  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ValidDelegator1}},
    43  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ProxiedDelegator}},
    44  		proxyUnBindAction{bAction, ValidDelegator1},
    45  
    46  		delegatorRegProxyAction{bAction, ProxiedDelegator, false},
    47  	}
    48  
    49  	expZeroDec := sdk.ZeroDec()
    50  	expProxiedToken1 := DelegatedToken1
    51  	expProxiedToken2 := expProxiedToken1.Add(DelegatedToken2)
    52  	prxBindChecker1 := andChecker{[]actResChecker{
    53  		queryDelegatorProxyCheck(ValidDelegator1, false, true, &expZeroDec, &ProxiedDelegator, nil),
    54  		queryDelegatorProxyCheck(ValidDelegator2, false, false, &expZeroDec, nil, nil),
    55  		queryDelegatorProxyCheck(ProxiedDelegator, true, false, &expProxiedToken1,
    56  			nil, []sdk.AccAddress{ValidDelegator1}),
    57  	}}
    58  
    59  	prxBindChecker2 := andChecker{[]actResChecker{
    60  		queryDelegatorProxyCheck(ValidDelegator1, false, true, &expZeroDec, &ProxiedDelegator, nil),
    61  		queryDelegatorProxyCheck(ValidDelegator2, false, true, &expZeroDec, &ProxiedDelegator, nil),
    62  		queryDelegatorProxyCheck(ProxiedDelegator, true, false, &expProxiedToken2,
    63  			nil, []sdk.AccAddress{ValidDelegator1, ValidDelegator2}),
    64  	}}
    65  
    66  	proxyAddSharesChecker3 := andChecker{[]actResChecker{
    67  		queryDelegatorProxyCheck(ValidDelegator1, false, true, &expZeroDec, &ProxiedDelegator, nil),
    68  		queryDelegatorProxyCheck(ValidDelegator2, false, true, &expZeroDec, &ProxiedDelegator, nil),
    69  		queryDelegatorProxyCheck(ProxiedDelegator, true, false, &expProxiedToken2, nil, nil),
    70  
    71  		queryDelegatorCheck(ValidDelegator1, true, []sdk.ValAddress{}, nil, &DelegatedToken1, nil),
    72  		queryDelegatorCheck(ProxiedDelegator, true, []sdk.ValAddress{startUpValidator.GetOperator()}, nil, &proxyOriginTokens, nil),
    73  		querySharesToCheck(startUpValidator.GetOperator(), 1, []sdk.AccAddress{ProxiedDelegator}),
    74  	}}
    75  
    76  	prxUnbindChecker4 := andChecker{[]actResChecker{
    77  		queryDelegatorProxyCheck(ValidDelegator1, false, false, &expZeroDec, nil, nil),
    78  		queryDelegatorProxyCheck(ProxiedDelegator, true, false, &DelegatedToken2, nil, nil),
    79  		validatorDelegatorShareIncreased(false),
    80  		delegatorAddSharesInvariantCheck(),
    81  		nonNegativePowerInvariantCustomCheck(),
    82  		positiveDelegatorInvariantCheck(),
    83  		moduleAccountInvariantsCustomCheck(),
    84  	}}
    85  
    86  	actionsAndChecker := []actResChecker{
    87  		nil,
    88  		queryDelegatorCheck(ProxiedDelegator, true, nil, &expZeroDec, &proxyOriginTokens, &expZeroDec),
    89  		queryDelegatorProxyCheck(ProxiedDelegator, true, false, &expZeroDec, nil, nil),
    90  		prxBindChecker1.GetChecker(),
    91  		prxBindChecker2.GetChecker(),
    92  		noErrorInHandlerResult(false),
    93  		proxyAddSharesChecker3.GetChecker(),
    94  		prxUnbindChecker4.GetChecker(),
    95  		queryDelegatorProxyCheck(ProxiedDelegator, false, false, &expZeroDec, nil, nil),
    96  	}
    97  
    98  	smTestCase := newValidatorSMTestCase(mk, params, startUpStatus, inputActions, actionsAndChecker, t)
    99  	smTestCase.SetupValidatorSetAndDelegatorSet(int(params.MaxValidators))
   100  	smTestCase.printParticipantSnapshot(t)
   101  	smTestCase.Run(t)
   102  }
   103  
   104  func TestDelegator(t *testing.T) {
   105  
   106  	common.InitConfig()
   107  	_, _, mk := CreateTestInput(t, false, SufficientInitPower)
   108  
   109  	params := DefaultParams()
   110  	params.MaxValidators = uint16(len(addrVals)) - 1
   111  	params.Epoch = 2
   112  	params.UnbondingTime = time.Millisecond * 300
   113  
   114  	startUpValidator := NewValidator(StartUpValidatorAddr, StartUpValidatorPubkey, Description{}, types.DefaultMinSelfDelegation)
   115  
   116  	startUpStatus := baseValidatorStatus{startUpValidator}
   117  
   118  	bAction := baseAction{mk}
   119  	zeroDec := sdk.ZeroDec()
   120  	tokenPerTime := sdk.NewDec(8000)
   121  	inputActions := []IAction{
   122  		createValidatorAction{bAction, nil},
   123  
   124  		// send delegate messages
   125  		delegatorDepositAction{bAction, ValidDelegator1, tokenPerTime, "testtoken"},
   126  		delegatorDepositAction{bAction, ValidDelegator1, tokenPerTime, sdk.DefaultBondDenom},
   127  		delegatorDepositAction{bAction, ValidDelegator1, tokenPerTime, sdk.DefaultBondDenom},
   128  		delegatorDepositAction{bAction, ValidDelegator1, tokenPerTime.MulInt64(10), sdk.DefaultBondDenom},
   129  		endBlockAction{bAction},
   130  
   131  		// send add shares messages
   132  		delegatorsAddSharesAction{bAction, false, false, 0, []sdk.AccAddress{ValidDelegator1}},
   133  		delegatorsAddSharesAction{bAction, false, false, 0, []sdk.AccAddress{ValidDelegator2}},
   134  		delegatorsAddSharesAction{bAction, false, false, 1, []sdk.AccAddress{ValidDelegator1}},
   135  		delegatorsAddSharesAction{bAction, false, false, int(params.MaxValsToAddShares) + 1, []sdk.AccAddress{ValidDelegator1}},
   136  		delegatorsAddSharesAction{bAction, true, false, 0, []sdk.AccAddress{ValidDelegator1}},
   137  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ValidDelegator1}},
   138  		// [E] repeat addshares to previous validator
   139  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ValidDelegator1}},
   140  		delegatorsAddSharesAction{bAction, false, true, 1, []sdk.AccAddress{ValidDelegator1}},
   141  		endBlockAction{bAction},
   142  
   143  		// send withdraw message
   144  		delegatorWithdrawAction{bAction, ValidDelegator2, sdk.ZeroDec(), "testtoken"},
   145  		delegatorWithdrawAction{bAction, ValidDelegator2, sdk.ZeroDec(), sdk.DefaultBondDenom},
   146  		delegatorWithdrawAction{bAction, ValidDelegator1, tokenPerTime.MulInt64(2), sdk.DefaultBondDenom},
   147  		delegatorWithdrawAction{bAction, ValidDelegator1, tokenPerTime.QuoInt64(2), sdk.DefaultBondDenom},
   148  		delegatorWithdrawAction{bAction, ValidDelegator1, tokenPerTime.QuoInt64(2), sdk.DefaultBondDenom},
   149  		waitUntilUnbondingTimeExpired{bAction},
   150  		endBlockAction{bAction},
   151  
   152  		// add shares after dlg.share == 0, expect failed
   153  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ValidDelegator1}},
   154  	}
   155  
   156  	actionsAndChecker := []actResChecker{
   157  		validatorStatusChecker(sdk.Unbonded.String()),
   158  		// check delegate response
   159  		noErrorInHandlerResult(false),
   160  		//  1. ValidDelegator1 delegate 8000 fibo, success
   161  		noErrorInHandlerResult(true),
   162  		//  2. ValidDelegator1 delegate 8000 fibo again, fail coz no balance
   163  		noErrorInHandlerResult(false),
   164  		noErrorInHandlerResult(false),
   165  		validatorStatusChecker(sdk.Bonded.String()),
   166  
   167  		// check adding shares response
   168  		noErrorInHandlerResult(false),
   169  		noErrorInHandlerResult(false),
   170  		noErrorInHandlerResult(false),
   171  		noErrorInHandlerResult(false),
   172  		noErrorInHandlerResult(false),
   173  		noErrorInHandlerResult(true),
   174  		// [E]
   175  		queryDelegatorCheck(ValidDelegator1, true, nil, nil, nil, nil),
   176  		noErrorInHandlerResult(false),
   177  		queryValidatorCheck(sdk.Bonded, false, nil, nil, nil),
   178  
   179  		// check withdraw response
   180  		noErrorInHandlerResult(false),
   181  		noErrorInHandlerResult(false),
   182  		noErrorInHandlerResult(false),
   183  		//   1. ValidDelegator1 UnBond 4000fibo, success
   184  		noErrorInHandlerResult(true),
   185  		//   2. ValidDelegator1 UnBond 4000fibo, success
   186  		noErrorInHandlerResult(true),
   187  		nil,
   188  		//   3. Check ValidDelegator1's not exists any more
   189  		queryDelegatorCheck(ValidDelegator1, false, []sdk.ValAddress{}, &zeroDec, &zeroDec, nil),
   190  
   191  		// check adding shares after dlg.share == 0
   192  		noErrorInHandlerResult(false),
   193  	}
   194  
   195  	smTestCase := newValidatorSMTestCase(mk, params, startUpStatus, inputActions, actionsAndChecker, t)
   196  	smTestCase.Run(t)
   197  
   198  }
   199  
   200  func TestProxy(t *testing.T) {
   201  	common.InitConfig()
   202  	_, _, mk := CreateTestInput(t, false, SufficientInitPower)
   203  	params := DefaultParams()
   204  
   205  	originVaSet := addrVals[1:]
   206  	params.MaxValidators = uint16(len(originVaSet))
   207  	params.Epoch = 2
   208  	params.UnbondingTime = time.Millisecond * 300
   209  
   210  	startUpValidator := NewValidator(StartUpValidatorAddr, StartUpValidatorPubkey, Description{}, types.DefaultMinSelfDelegation)
   211  
   212  	startUpStatus := baseValidatorStatus{startUpValidator}
   213  
   214  	orgValsLen := len(originVaSet)
   215  	fullVaSet := make([]sdk.ValAddress, orgValsLen+1)
   216  	copy(fullVaSet, originVaSet)
   217  	copy(fullVaSet[orgValsLen:], []sdk.ValAddress{startUpStatus.getValidator().GetOperator()})
   218  
   219  	bAction := baseAction{mk}
   220  	proxyOriginTokens := MaxDelegatedToken
   221  	inputActions := []IAction{
   222  		createValidatorAction{bAction, nil},
   223  		endBlockAction{bAction},
   224  
   225  		// failed to register & unregister
   226  		delegatorRegProxyAction{bAction, ProxiedDelegator, true},
   227  		delegatorRegProxyAction{bAction, ProxiedDelegator, false},
   228  		delegatorDepositAction{bAction, ProxiedDelegator, proxyOriginTokens, sdk.DefaultBondDenom},
   229  
   230  		// successfully regiester
   231  		// delegate again
   232  		delegatorDepositAction{bAction, ProxiedDelegator, MaxDelegatedToken, sdk.DefaultBondDenom},
   233  		delegatorRegProxyAction{bAction, ProxiedDelegator, true},
   234  		delegatorRegProxyAction{bAction, ProxiedDelegator, true},
   235  
   236  		// bind
   237  		proxyBindAction{bAction, ValidDelegator1, InvalidDelegator},
   238  		proxyBindAction{bAction, ValidDelegator1, ValidDelegator2},
   239  		proxyBindAction{bAction, InvalidDelegator, ProxiedDelegator},
   240  		proxyBindAction{bAction, ProxiedDelegator, ProxiedDelegator},
   241  		proxyBindAction{bAction, ValidDelegator1, ProxiedDelegator},
   242  		proxyBindAction{bAction, ValidDelegator2, ProxiedDelegator},
   243  
   244  		// [E] delegator bind the same proxy again
   245  		proxyBindAction{bAction, ValidDelegator2, ProxiedDelegator},
   246  
   247  		// add shares
   248  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ValidDelegator1}},
   249  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ProxiedDelegator}},
   250  		delegatorsAddSharesAction{bAction, true, true, 0, []sdk.AccAddress{ProxiedDelegator}},
   251  
   252  		// [E] delegator add shares to the same validator again
   253  		delegatorsAddSharesAction{bAction, true, true, 0, []sdk.AccAddress{ProxiedDelegator}},
   254  
   255  		// redeposit & rewithdraw
   256  		delegatorDepositAction{bAction, ValidDelegator1, DelegatedToken1, sdk.DefaultBondDenom},
   257  		delegatorWithdrawAction{bAction, ValidDelegator2, DelegatedToken2, sdk.DefaultBondDenom},
   258  
   259  		// unbind
   260  		proxyUnBindAction{bAction, InvalidDelegator},
   261  		proxyUnBindAction{bAction, ProxiedDelegator},
   262  		proxyUnBindAction{bAction, ValidDelegator1},
   263  
   264  		// [E] ProxiedDelegator unbind again
   265  		proxyUnBindAction{bAction, ValidDelegator1},
   266  
   267  		// unregister
   268  		delegatorRegProxyAction{bAction, ValidDelegator1, false},
   269  		delegatorRegProxyAction{bAction, ProxiedDelegator, false},
   270  	}
   271  
   272  	delegatorsChecker := andChecker{[]actResChecker{
   273  		queryDelegatorCheck(ValidDelegator1, true, nil, nil, nil, nil),
   274  		queryDelegatorCheck(ValidDelegator2, true, nil, nil, nil, nil),
   275  		queryDelegatorCheck(ProxiedDelegator, true, nil, nil, nil, nil),
   276  	}}
   277  
   278  	actionsAndChecker := []actResChecker{
   279  		nil,
   280  		validatorStatusChecker(sdk.Unbonded.String()),
   281  		noErrorInHandlerResult(false),
   282  		noErrorInHandlerResult(false),
   283  		noErrorInHandlerResult(true),
   284  
   285  		// register result
   286  		noErrorInHandlerResult(true),
   287  		noErrorInHandlerResult(true),
   288  		noErrorInHandlerResult(false),
   289  
   290  		// bind
   291  		noErrorInHandlerResult(false),
   292  		noErrorInHandlerResult(false),
   293  		noErrorInHandlerResult(false),
   294  		noErrorInHandlerResult(false),
   295  		noErrorInHandlerResult(true),
   296  		noErrorInHandlerResult(true),
   297  
   298  		// [E] bind
   299  		delegatorsChecker.GetChecker(),
   300  
   301  		// add shares
   302  		noErrorInHandlerResult(false),
   303  		noErrorInHandlerResult(true),
   304  		noErrorInHandlerResult(true),
   305  
   306  		// [E] add shares
   307  		delegatorsChecker.GetChecker(),
   308  
   309  		// redeposit & rewithdraw
   310  		queryDelegatorCheck(ValidDelegator1, true, nil, nil, nil, nil),
   311  		queryDelegatorCheck(ValidDelegator2, false, nil, nil, nil, nil),
   312  
   313  		// unbind
   314  		noErrorInHandlerResult(false),
   315  		noErrorInHandlerResult(false),
   316  		noErrorInHandlerResult(true),
   317  
   318  		// [E] unbind
   319  		noErrorInHandlerResult(false),
   320  
   321  		// unregister result
   322  		noErrorInHandlerResult(false),
   323  		noErrorInHandlerResult(true),
   324  	}
   325  
   326  	smTestCase := newValidatorSMTestCase(mk, params, startUpStatus, inputActions, actionsAndChecker, t)
   327  	smTestCase.SetupValidatorSetAndDelegatorSet(int(params.MaxValidators))
   328  	smTestCase.printParticipantSnapshot(t)
   329  	smTestCase.Run(t)
   330  }
   331  
   332  func TestRebindProxy(t *testing.T) {
   333  	common.InitConfig()
   334  	_, _, mk := CreateTestInput(t, false, SufficientInitPower)
   335  	params := DefaultParams()
   336  
   337  	originVaSet := addrVals[1:]
   338  	params.MaxValidators = uint16(len(originVaSet))
   339  	params.Epoch = 2
   340  	params.UnbondingTime = time.Millisecond * 300
   341  
   342  	startUpValidator := NewValidator(StartUpValidatorAddr, StartUpValidatorPubkey, Description{}, types.DefaultMinSelfDelegation)
   343  
   344  	startUpStatus := baseValidatorStatus{startUpValidator}
   345  
   346  	orgValsLen := len(originVaSet)
   347  	fullVaSet := make([]sdk.ValAddress, orgValsLen+1)
   348  	copy(fullVaSet, originVaSet)
   349  	copy(fullVaSet[orgValsLen:], []sdk.ValAddress{startUpStatus.getValidator().GetOperator()})
   350  
   351  	bAction := baseAction{mk}
   352  	proxyOriginTokens := MaxDelegatedToken
   353  	ProxiedDelegatorAlternative := ValidDelegator2
   354  	zeroDec := sdk.ZeroDec()
   355  	inputActions := []IAction{
   356  		createValidatorAction{bAction, nil},
   357  		endBlockAction{bAction},
   358  
   359  		// register proxy
   360  		delegatorDepositAction{bAction, ProxiedDelegator, proxyOriginTokens, sdk.DefaultBondDenom},
   361  		delegatorRegProxyAction{bAction, ProxiedDelegator, true},
   362  
   363  		// register another proxy
   364  		delegatorDepositAction{bAction, ProxiedDelegatorAlternative, proxyOriginTokens, sdk.DefaultBondDenom},
   365  		delegatorRegProxyAction{bAction, ProxiedDelegatorAlternative, true},
   366  		endBlockAction{bAction},
   367  
   368  		// bind proxy
   369  		proxyBindAction{bAction, ValidDelegator1, ProxiedDelegator},
   370  
   371  		// vote validator
   372  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ProxiedDelegator}},
   373  		endBlockAction{bAction},
   374  
   375  		// rebind to an alternative proxy
   376  		proxyBindAction{bAction, ValidDelegator1, ProxiedDelegatorAlternative},
   377  		endBlockAction{bAction},
   378  		proxyBindAction{bAction, ValidDelegator1, ProxiedDelegatorAlternative},
   379  	}
   380  
   381  	ProxyChecker1 := andChecker{[]actResChecker{
   382  		noErrorInHandlerResult(true),
   383  		queryDelegatorProxyCheck(ProxiedDelegator, true, false,
   384  			&DelegatedToken1, nil, []sdk.AccAddress{ValidDelegator1}),
   385  		queryDelegatorProxyCheck(ProxiedDelegatorAlternative, true, false,
   386  			&zeroDec, nil, nil),
   387  	}}
   388  
   389  	voteActionChecker := andChecker{checkers: []actResChecker{
   390  		noErrorInHandlerResult(true),
   391  		queryDelegatorProxyCheck(ProxiedDelegator, true, false,
   392  			&DelegatedToken1, nil, []sdk.AccAddress{ValidDelegator1}),
   393  		queryDelegatorProxyCheck(ProxiedDelegatorAlternative, true, false,
   394  			&zeroDec, nil, nil),
   395  		validatorDelegatorShareIncreased(true),
   396  	}}
   397  
   398  	ProxyChecker2 := andChecker{[]actResChecker{
   399  		noErrorInHandlerResult(true),
   400  		queryProxyCheck(ProxiedDelegator, true, sdk.ZeroDec()),
   401  		queryProxyCheck(ProxiedDelegatorAlternative, true, DelegatedToken1),
   402  
   403  		queryDelegatorProxyCheck(ProxiedDelegator, true, false,
   404  			&zeroDec, nil, nil),
   405  		queryDelegatorProxyCheck(ProxiedDelegatorAlternative, true, false,
   406  			&DelegatedToken1, nil, nil),
   407  
   408  		validatorDelegatorShareIncreased(false),
   409  	}}
   410  
   411  	actionsAndChecker := []actResChecker{
   412  		nil,
   413  		validatorStatusChecker(sdk.Unbonded.String()),
   414  		// register proxy
   415  		noErrorInHandlerResult(true),
   416  		noErrorInHandlerResult(true),
   417  
   418  		// register another proxy
   419  		noErrorInHandlerResult(true),
   420  		noErrorInHandlerResult(true),
   421  		nil,
   422  
   423  		// bind proxy
   424  		ProxyChecker1.GetChecker(),
   425  
   426  		// vote check
   427  		voteActionChecker.GetChecker(),
   428  		nil,
   429  
   430  		// rebind to an alternative proxy
   431  		ProxyChecker2.GetChecker(),
   432  		nil,
   433  		// rebind ProxiedDelegatorAlternative
   434  		queryDelegatorProxyCheck(ProxiedDelegatorAlternative, true, false,
   435  			&DelegatedToken1, nil, nil),
   436  	}
   437  
   438  	smTestCase := newValidatorSMTestCase(mk, params, startUpStatus, inputActions, actionsAndChecker, t)
   439  	smTestCase.SetupValidatorSetAndDelegatorSet(int(params.MaxValidators))
   440  	smTestCase.printParticipantSnapshot(t)
   441  	smTestCase.Run(t)
   442  }
   443  
   444  func TestLimitedProxy(t *testing.T) {
   445  	common.InitConfig()
   446  	_, _, mk := CreateTestInput(t, false, SufficientInitPower)
   447  	params := DefaultParams()
   448  
   449  	originVaSet := addrVals[1:]
   450  	params.MaxValidators = uint16(len(originVaSet))
   451  	params.Epoch = 2
   452  	params.UnbondingTime = time.Millisecond * 300
   453  
   454  	startUpValidator := NewValidator(StartUpValidatorAddr, StartUpValidatorPubkey, Description{}, types.DefaultMinSelfDelegation)
   455  
   456  	startUpStatus := baseValidatorStatus{startUpValidator}
   457  
   458  	orgValsLen := len(originVaSet)
   459  	fullVaSet := make([]sdk.ValAddress, orgValsLen+1)
   460  	copy(fullVaSet, originVaSet)
   461  	copy(fullVaSet[orgValsLen:], []sdk.ValAddress{startUpStatus.getValidator().GetOperator()})
   462  
   463  	bAction := baseAction{mk}
   464  	proxyOriginTokens := MaxDelegatedToken
   465  	inputActions := []IAction{
   466  		createValidatorAction{bAction, nil},
   467  		endBlockAction{bAction},
   468  
   469  		// register proxy
   470  		delegatorDepositAction{bAction, ProxiedDelegator, proxyOriginTokens, sdk.DefaultBondDenom},
   471  		delegatorRegProxyAction{bAction, ProxiedDelegator, true},
   472  
   473  		// bind proxy
   474  		proxyBindAction{bAction, ValidDelegator1, ProxiedDelegator},
   475  
   476  		// register proxy without unbinding
   477  		delegatorRegProxyAction{bAction, ValidDelegator1, true},
   478  	}
   479  
   480  	actionsAndChecker := []actResChecker{
   481  		nil,
   482  		validatorStatusChecker(sdk.Unbonded.String()),
   483  		// register proxy
   484  		noErrorInHandlerResult(true),
   485  		noErrorInHandlerResult(true),
   486  		// bind proxy
   487  		noErrorInHandlerResult(true),
   488  		// register proxy without unbinding (failed)
   489  		noErrorInHandlerResult(false),
   490  	}
   491  
   492  	smTestCase := newValidatorSMTestCase(mk, params, startUpStatus, inputActions, actionsAndChecker, t)
   493  	smTestCase.SetupValidatorSetAndDelegatorSet(int(params.MaxValidators))
   494  	smTestCase.printParticipantSnapshot(t)
   495  	smTestCase.Run(t)
   496  
   497  }
   498  
   499  // Context: create 2 delegator(d1,d2) + 1 proxy(p) + 1 validator(v)
   500  // Operation Group:
   501  //
   502  //	         setup: v(create), p(deposit), d2(addShares to v)
   503  //	         step1: p  5(regProxy, addShare(v), bind(p), unbind(p), withdrawSome)
   504  //				step2: d1 4(bind(p), addShare(v), unbind(p), withdrawSome)
   505  //				step3: d1 4(deposit, bind(p), unbind(p), withdrawSome)
   506  //	         step4: p  5(regProxy, addShare(v), bind(p), unbind(p), withdrawSome)
   507  //	         teardown: p(unReg), v(destroy)
   508  //	         case possibilities: 1 * 1 * 5 * 5 * 4 * 4 = 400
   509  //	         iterate all the possibilities to run delegatorConstraintCheck and validatorConstrainCheck
   510  func TestDelegatorProxyValidatorConstraints4Steps(t *testing.T) {
   511  	common.InitConfig()
   512  	params := DefaultParams()
   513  
   514  	originVaSet := addrVals[1:]
   515  	params.MaxValidators = uint16(len(originVaSet))
   516  	params.Epoch = 2
   517  	params.UnbondingTime = time.Millisecond * 300
   518  	startUpValidator := NewValidator(StartUpValidatorAddr, StartUpValidatorPubkey, Description{}, types.DefaultMinSelfDelegation)
   519  	startUpStatus := baseValidatorStatus{startUpValidator}
   520  	orgValsLen := len(originVaSet)
   521  	fullVaSet := make([]sdk.ValAddress, orgValsLen+1)
   522  	copy(fullVaSet, originVaSet)
   523  	copy(fullVaSet[orgValsLen:], []sdk.ValAddress{startUpStatus.getValidator().GetOperator()})
   524  
   525  	bAction := baseAction{}
   526  
   527  	step1Actions := IActions{
   528  		delegatorRegProxyAction{bAction, ProxiedDelegator, true},
   529  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ProxiedDelegator}},
   530  		delegatorWithdrawAction{bAction, ProxiedDelegator, sdk.OneDec(), sdk.DefaultBondDenom},
   531  		proxyBindAction{bAction, ProxiedDelegator, ProxiedDelegator},
   532  		proxyUnBindAction{bAction, ProxiedDelegator},
   533  	}
   534  
   535  	step2Actions := IActions{
   536  		delegatorDepositAction{bAction, ValidDelegator1, DelegatedToken1, sdk.DefaultBondDenom},
   537  		proxyBindAction{bAction, ValidDelegator1, ProxiedDelegator},
   538  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ValidDelegator1}},
   539  		proxyUnBindAction{bAction, ValidDelegator1},
   540  		delegatorWithdrawAction{bAction, ValidDelegator1, sdk.OneDec(), sdk.DefaultBondDenom},
   541  	}
   542  
   543  	step3Actions := IActions{
   544  		delegatorDepositAction{bAction, ValidDelegator1, DelegatedToken1, sdk.DefaultBondDenom},
   545  		proxyBindAction{bAction, ValidDelegator1, ProxiedDelegator},
   546  		proxyUnBindAction{bAction, ValidDelegator1},
   547  		delegatorWithdrawAction{bAction, ValidDelegator1, sdk.OneDec(), sdk.DefaultBondDenom},
   548  	}
   549  
   550  	step4Actions := IActions{
   551  		delegatorRegProxyAction{bAction, ProxiedDelegator, true},
   552  		delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ProxiedDelegator}},
   553  		proxyBindAction{bAction, ProxiedDelegator, ProxiedDelegator},
   554  		proxyUnBindAction{bAction, ProxiedDelegator},
   555  		delegatorWithdrawAction{bAction, ProxiedDelegator, sdk.OneDec(), sdk.DefaultBondDenom},
   556  	}
   557  
   558  	for s1 := 0; s1 < len(step1Actions); s1++ {
   559  		for s2 := 0; s2 < len(step2Actions); s2++ {
   560  			for s3 := 0; s3 < len(step3Actions); s3++ {
   561  				for s4 := 0; s4 < len(step4Actions); s4++ {
   562  					inputActions := []IAction{
   563  						createValidatorAction{bAction, nil},
   564  						delegatorsAddSharesAction{bAction, false, true, 0, []sdk.AccAddress{ValidDelegator2}},
   565  						delegatorDepositAction{bAction, ProxiedDelegator, MaxDelegatedToken, sdk.DefaultBondDenom},
   566  						step1Actions[s1],
   567  						step2Actions[s2],
   568  						step3Actions[s3],
   569  						step4Actions[s4],
   570  						delegatorRegProxyAction{bAction, ProxiedDelegator, false},
   571  						destroyValidatorAction{bAction},
   572  					}
   573  
   574  					actionsAndChecker, caseName := generateActionsAndCheckers(inputActions, 3)
   575  
   576  					t.Logf("============================================== indexes:[%d,%d,%d,%d]  %s ==============================================", s1, s2, s3, s4, caseName)
   577  					_, _, mk := CreateTestInput(t, false, SufficientInitPower)
   578  					smTestCase := newValidatorSMTestCase(mk, params, startUpStatus, inputActions, actionsAndChecker, t)
   579  					smTestCase.SetupValidatorSetAndDelegatorSet(int(params.MaxValidators))
   580  					smTestCase.printParticipantSnapshot(t)
   581  					smTestCase.Run(t)
   582  					t.Log("============================================================================================")
   583  				}
   584  
   585  			}
   586  		}
   587  	}
   588  }
   589  
   590  type IActions []IAction
   591  type ResCheckers []actResChecker
   592  
   593  func defaultConstraintChecker(checkVa bool, checkD2 bool) actResChecker {
   594  
   595  	var checkerGroup ResCheckers
   596  	checkerGroup = []actResChecker{
   597  		queryDelegatorCheck(ValidDelegator1, true, nil, nil, nil, nil),
   598  		queryDelegatorCheck(ProxiedDelegator, true, nil, nil, nil, nil),
   599  	}
   600  
   601  	if checkD2 {
   602  		checkerGroup = append(checkerGroup, queryDelegatorCheck(ValidDelegator2, true, nil, nil, nil, nil))
   603  	}
   604  	if checkVa {
   605  		checkerGroup = append(checkerGroup, validatorCheck(StartUpValidatorAddr))
   606  	}
   607  
   608  	checker := andChecker{checkerGroup}
   609  	return checker.GetChecker()
   610  }
   611  
   612  func generateActionsAndCheckers(stepActions IActions, skipActCnt int) (ResCheckers, string) {
   613  	checkers := ResCheckers{}
   614  	caseName := ""
   615  	for i := 0; i < len(stepActions); i++ {
   616  		a := stepActions[i]
   617  		caseName = caseName + fmt.Sprintf("step_%d_%s#$", i, a.desc())
   618  		if i >= skipActCnt {
   619  			checkVa := a.desc() != "destroyVa"
   620  			checkD2 := a.desc() != "dlg2WithdrawAll"
   621  			checkers = append(checkers, defaultConstraintChecker(checkVa, checkD2))
   622  
   623  		} else {
   624  			checkers = append(checkers, nil)
   625  		}
   626  	}
   627  	return checkers, caseName
   628  }
   629  
   630  // Context: create 1 delegator(d) + 1 proxy(p) + 1 validator(v)
   631  // Operation Group:
   632  //
   633  //	         step1: v 1(create)
   634  //	         step2: p 7(deposit, regProxy, unregProxy, bind(p), unbind(p), addShare, withdraw)
   635  //				step3: d 5(deposit, bind(p), unbind(p), addShare(v), withdraw)
   636  //	         step4: v 2(nil, destroy)
   637  //	         step5: d 5(nil, deposit, withdraw, bind, unbind)
   638  //	         step6: p 5(nil, deposit, withdraw, bind, unbind)
   639  //	         step7: v 2(nil, destroy)
   640  //	         possibilities: 1 * 5 * 7 * 2 * 5 * 5 * 2 = 3500
   641  //	         iterate all the possibilities an run delegatorConstraintCheck and validatorConstrainCheck
   642  func TestDelegatorProxyValidatorShares7Steps(t *testing.T) {
   643  
   644  }