github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/gov/keeper/tally_test.go (about)

     1  package keeper
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     9  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/types"
    10  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking"
    11  )
    12  
    13  func TestTallyNoOneVotes(t *testing.T) {
    14  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
    15  	createValidators(ctx, sk, []int64{5, 5, 5})
    16  
    17  	tp := TestProposal
    18  	proposal, err := keeper.SubmitProposal(ctx, tp)
    19  	require.NoError(t, err)
    20  	proposalID := proposal.ProposalID
    21  	proposal.Status = types.StatusVotingPeriod
    22  	keeper.SetProposal(ctx, proposal)
    23  
    24  	proposal, ok := keeper.GetProposal(ctx, proposalID)
    25  	require.True(t, ok)
    26  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
    27  
    28  	require.False(t, passes)
    29  	require.True(t, burnDeposits)
    30  	require.True(t, tallyResults.Equals(types.EmptyTallyResult()))
    31  }
    32  
    33  func TestTallyNoQuorum(t *testing.T) {
    34  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
    35  	createValidators(ctx, sk, []int64{2, 5, 0})
    36  
    37  	tp := TestProposal
    38  	proposal, err := keeper.SubmitProposal(ctx, tp)
    39  	require.NoError(t, err)
    40  	proposalID := proposal.ProposalID
    41  	proposal.Status = types.StatusVotingPeriod
    42  	keeper.SetProposal(ctx, proposal)
    43  
    44  	err = keeper.AddVote(ctx, proposalID, TestAddrs[0], types.OptionYes)
    45  	require.Nil(t, err)
    46  
    47  	proposal, ok := keeper.GetProposal(ctx, proposalID)
    48  	require.True(t, ok)
    49  	passes, burnDeposits, _ := keeper.Tally(ctx, proposal)
    50  	require.False(t, passes)
    51  	require.True(t, burnDeposits)
    52  }
    53  
    54  func TestTallyOnlyValidatorsAllYes(t *testing.T) {
    55  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
    56  	createValidators(ctx, sk, []int64{5, 5, 5})
    57  
    58  	tp := TestProposal
    59  	proposal, err := keeper.SubmitProposal(ctx, tp)
    60  	require.NoError(t, err)
    61  	proposalID := proposal.ProposalID
    62  	proposal.Status = types.StatusVotingPeriod
    63  	keeper.SetProposal(ctx, proposal)
    64  
    65  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
    66  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionYes))
    67  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionYes))
    68  
    69  	proposal, ok := keeper.GetProposal(ctx, proposalID)
    70  	require.True(t, ok)
    71  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
    72  
    73  	require.True(t, passes)
    74  	require.False(t, burnDeposits)
    75  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
    76  }
    77  
    78  func TestTallyOnlyValidators51No(t *testing.T) {
    79  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
    80  	createValidators(ctx, sk, []int64{5, 6, 0})
    81  
    82  	tp := TestProposal
    83  	proposal, err := keeper.SubmitProposal(ctx, tp)
    84  	require.NoError(t, err)
    85  	proposalID := proposal.ProposalID
    86  	proposal.Status = types.StatusVotingPeriod
    87  	keeper.SetProposal(ctx, proposal)
    88  
    89  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
    90  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionNo))
    91  
    92  	proposal, ok := keeper.GetProposal(ctx, proposalID)
    93  	require.True(t, ok)
    94  	passes, burnDeposits, _ := keeper.Tally(ctx, proposal)
    95  
    96  	require.False(t, passes)
    97  	require.False(t, burnDeposits)
    98  }
    99  
   100  func TestTallyOnlyValidators51Yes(t *testing.T) {
   101  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   102  	createValidators(ctx, sk, []int64{5, 6, 0})
   103  
   104  	tp := TestProposal
   105  	proposal, err := keeper.SubmitProposal(ctx, tp)
   106  	require.NoError(t, err)
   107  	proposalID := proposal.ProposalID
   108  	proposal.Status = types.StatusVotingPeriod
   109  	keeper.SetProposal(ctx, proposal)
   110  
   111  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionNo))
   112  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionYes))
   113  
   114  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   115  	require.True(t, ok)
   116  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   117  
   118  	require.True(t, passes)
   119  	require.False(t, burnDeposits)
   120  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   121  }
   122  
   123  func TestTallyOnlyValidatorsVetoed(t *testing.T) {
   124  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   125  	createValidators(ctx, sk, []int64{6, 6, 7})
   126  
   127  	tp := TestProposal
   128  	proposal, err := keeper.SubmitProposal(ctx, tp)
   129  	require.NoError(t, err)
   130  	proposalID := proposal.ProposalID
   131  	proposal.Status = types.StatusVotingPeriod
   132  	keeper.SetProposal(ctx, proposal)
   133  
   134  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
   135  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionYes))
   136  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionNoWithVeto))
   137  
   138  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   139  	require.True(t, ok)
   140  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   141  
   142  	require.False(t, passes)
   143  	require.True(t, burnDeposits)
   144  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   145  
   146  }
   147  
   148  func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) {
   149  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   150  	createValidators(ctx, sk, []int64{6, 6, 7})
   151  
   152  	tp := TestProposal
   153  	proposal, err := keeper.SubmitProposal(ctx, tp)
   154  	require.NoError(t, err)
   155  	proposalID := proposal.ProposalID
   156  	proposal.Status = types.StatusVotingPeriod
   157  	keeper.SetProposal(ctx, proposal)
   158  
   159  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionAbstain))
   160  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionNo))
   161  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionYes))
   162  
   163  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   164  	require.True(t, ok)
   165  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   166  
   167  	require.True(t, passes)
   168  	require.False(t, burnDeposits)
   169  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   170  }
   171  
   172  func TestTallyOnlyValidatorsAbstainFails(t *testing.T) {
   173  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   174  	createValidators(ctx, sk, []int64{6, 6, 7})
   175  
   176  	tp := TestProposal
   177  	proposal, err := keeper.SubmitProposal(ctx, tp)
   178  	require.NoError(t, err)
   179  	proposalID := proposal.ProposalID
   180  	proposal.Status = types.StatusVotingPeriod
   181  	keeper.SetProposal(ctx, proposal)
   182  
   183  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionAbstain))
   184  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionYes))
   185  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionNo))
   186  
   187  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   188  	require.True(t, ok)
   189  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   190  
   191  	require.False(t, passes)
   192  	require.False(t, burnDeposits)
   193  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   194  }
   195  
   196  func TestTallyOnlyValidatorsNonVoter(t *testing.T) {
   197  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   198  	createValidators(ctx, sk, []int64{5, 6, 7})
   199  
   200  	tp := TestProposal
   201  	proposal, err := keeper.SubmitProposal(ctx, tp)
   202  	require.NoError(t, err)
   203  	proposalID := proposal.ProposalID
   204  	proposal.Status = types.StatusVotingPeriod
   205  	keeper.SetProposal(ctx, proposal)
   206  
   207  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
   208  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionNo))
   209  
   210  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   211  	require.True(t, ok)
   212  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   213  
   214  	require.False(t, passes)
   215  	require.False(t, burnDeposits)
   216  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   217  }
   218  
   219  func TestTallyDelgatorOverride(t *testing.T) {
   220  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   221  	createValidators(ctx, sk, []int64{5, 6, 7})
   222  
   223  	delTokens := sdk.TokensFromConsensusPower(30)
   224  	val1, found := sk.GetValidator(ctx, valOpAddr1)
   225  	require.True(t, found)
   226  
   227  	_, err := sk.Delegate(ctx, TestAddrs[0], sdk.NewDecFromInt(delTokens), sdk.Unbonded, val1, true)
   228  	require.NoError(t, err)
   229  
   230  	_ = staking.EndBlocker(ctx, sk)
   231  
   232  	tp := TestProposal
   233  	proposal, err := keeper.SubmitProposal(ctx, tp)
   234  	require.NoError(t, err)
   235  	proposalID := proposal.ProposalID
   236  	proposal.Status = types.StatusVotingPeriod
   237  	keeper.SetProposal(ctx, proposal)
   238  
   239  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
   240  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionYes))
   241  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionYes))
   242  	require.NoError(t, keeper.AddVote(ctx, proposalID, TestAddrs[0], types.OptionNo))
   243  
   244  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   245  	require.True(t, ok)
   246  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   247  
   248  	require.False(t, passes)
   249  	require.False(t, burnDeposits)
   250  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   251  }
   252  
   253  func TestTallyDelgatorInherit(t *testing.T) {
   254  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   255  	createValidators(ctx, sk, []int64{5, 6, 7})
   256  
   257  	delTokens := sdk.TokensFromConsensusPower(30)
   258  	val3, found := sk.GetValidator(ctx, valOpAddr3)
   259  	require.True(t, found)
   260  
   261  	_, err := sk.Delegate(ctx, TestAddrs[0], sdk.NewDecFromInt(delTokens), sdk.Unbonded, val3, true)
   262  	require.NoError(t, err)
   263  
   264  	_ = staking.EndBlocker(ctx, sk)
   265  
   266  	tp := TestProposal
   267  	proposal, err := keeper.SubmitProposal(ctx, tp)
   268  	require.NoError(t, err)
   269  	proposalID := proposal.ProposalID
   270  	proposal.Status = types.StatusVotingPeriod
   271  	keeper.SetProposal(ctx, proposal)
   272  
   273  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionNo))
   274  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionNo))
   275  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionYes))
   276  
   277  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   278  	require.True(t, ok)
   279  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   280  
   281  	require.True(t, passes)
   282  	require.False(t, burnDeposits)
   283  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   284  }
   285  
   286  func TestTallyDelgatorMultipleOverride(t *testing.T) {
   287  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   288  	createValidators(ctx, sk, []int64{5, 6, 7})
   289  
   290  	delTokens := sdk.TokensFromConsensusPower(10)
   291  	val1, found := sk.GetValidator(ctx, valOpAddr1)
   292  	require.True(t, found)
   293  	val2, found := sk.GetValidator(ctx, valOpAddr2)
   294  	require.True(t, found)
   295  
   296  	_, err := sk.Delegate(ctx, TestAddrs[0], sdk.NewDecFromInt(delTokens), sdk.Unbonded, val1, true)
   297  	require.NoError(t, err)
   298  	_, err = sk.Delegate(ctx, TestAddrs[0], sdk.NewDecFromInt(delTokens), sdk.Unbonded, val2, true)
   299  	require.NoError(t, err)
   300  
   301  	_ = staking.EndBlocker(ctx, sk)
   302  
   303  	tp := TestProposal
   304  	proposal, err := keeper.SubmitProposal(ctx, tp)
   305  	require.NoError(t, err)
   306  	proposalID := proposal.ProposalID
   307  	proposal.Status = types.StatusVotingPeriod
   308  	keeper.SetProposal(ctx, proposal)
   309  
   310  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
   311  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionYes))
   312  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionYes))
   313  	require.NoError(t, keeper.AddVote(ctx, proposalID, TestAddrs[0], types.OptionNo))
   314  
   315  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   316  	require.True(t, ok)
   317  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   318  
   319  	require.False(t, passes)
   320  	require.False(t, burnDeposits)
   321  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   322  }
   323  
   324  func TestTallyDelgatorMultipleInherit(t *testing.T) {
   325  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   326  	createValidators(ctx, sk, []int64{25, 6, 7})
   327  
   328  	delTokens := sdk.TokensFromConsensusPower(10)
   329  	val2, found := sk.GetValidator(ctx, valOpAddr2)
   330  	require.True(t, found)
   331  	val3, found := sk.GetValidator(ctx, valOpAddr3)
   332  	require.True(t, found)
   333  
   334  	_, err := sk.Delegate(ctx, TestAddrs[0], sdk.NewDecFromInt(delTokens), sdk.Unbonded, val2, true)
   335  	require.NoError(t, err)
   336  	_, err = sk.Delegate(ctx, TestAddrs[0], sdk.NewDecFromInt(delTokens), sdk.Unbonded, val3, true)
   337  	require.NoError(t, err)
   338  
   339  	_ = staking.EndBlocker(ctx, sk)
   340  
   341  	tp := TestProposal
   342  	proposal, err := keeper.SubmitProposal(ctx, tp)
   343  	require.NoError(t, err)
   344  	proposalID := proposal.ProposalID
   345  	proposal.Status = types.StatusVotingPeriod
   346  	keeper.SetProposal(ctx, proposal)
   347  
   348  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
   349  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionNo))
   350  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionNo))
   351  
   352  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   353  	require.True(t, ok)
   354  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   355  
   356  	require.False(t, passes)
   357  	require.False(t, burnDeposits)
   358  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   359  }
   360  
   361  func TestTallyJailedValidator(t *testing.T) {
   362  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   363  	createValidators(ctx, sk, []int64{25, 6, 7})
   364  
   365  	delTokens := sdk.TokensFromConsensusPower(10)
   366  	val2, found := sk.GetValidator(ctx, valOpAddr2)
   367  	require.True(t, found)
   368  	val3, found := sk.GetValidator(ctx, valOpAddr3)
   369  	require.True(t, found)
   370  
   371  	_, err := sk.Delegate(ctx, TestAddrs[0], sdk.NewDecFromInt(delTokens), sdk.Unbonded, val2, true)
   372  	require.NoError(t, err)
   373  	_, err = sk.Delegate(ctx, TestAddrs[0], sdk.NewDecFromInt(delTokens), sdk.Unbonded, val3, true)
   374  	require.NoError(t, err)
   375  
   376  	_ = staking.EndBlocker(ctx, sk)
   377  
   378  	sk.Jail(ctx, sdk.ConsAddress(val2.ConsPubKey.Address()))
   379  
   380  	tp := TestProposal
   381  	proposal, err := keeper.SubmitProposal(ctx, tp)
   382  	require.NoError(t, err)
   383  	proposalID := proposal.ProposalID
   384  	proposal.Status = types.StatusVotingPeriod
   385  	keeper.SetProposal(ctx, proposal)
   386  
   387  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
   388  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionNo))
   389  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionNo))
   390  
   391  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   392  	require.True(t, ok)
   393  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   394  
   395  	require.True(t, passes)
   396  	require.False(t, burnDeposits)
   397  	require.False(t, tallyResults.Equals(types.EmptyTallyResult()))
   398  }
   399  
   400  func TestTallyValidatorMultipleDelegations(t *testing.T) {
   401  	ctx, _, keeper, sk, _ := createTestInput(t, false, 100)
   402  	createValidators(ctx, sk, []int64{10, 10, 10})
   403  
   404  	delTokens := sdk.TokensFromConsensusPower(10)
   405  	val2, found := sk.GetValidator(ctx, valOpAddr2)
   406  	require.True(t, found)
   407  
   408  	_, err := sk.Delegate(ctx, valAccAddr1, sdk.NewDecFromInt(delTokens), sdk.Unbonded, val2, true)
   409  	require.NoError(t, err)
   410  
   411  	tp := TestProposal
   412  	proposal, err := keeper.SubmitProposal(ctx, tp)
   413  	require.NoError(t, err)
   414  	proposalID := proposal.ProposalID
   415  	proposal.Status = types.StatusVotingPeriod
   416  	keeper.SetProposal(ctx, proposal)
   417  
   418  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr1, types.OptionYes))
   419  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr2, types.OptionNo))
   420  	require.NoError(t, keeper.AddVote(ctx, proposalID, valAccAddr3, types.OptionYes))
   421  
   422  	proposal, ok := keeper.GetProposal(ctx, proposalID)
   423  	require.True(t, ok)
   424  	passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal)
   425  
   426  	require.True(t, passes)
   427  	require.False(t, burnDeposits)
   428  
   429  	expectedYes := sdk.TokensFromConsensusPower(30)
   430  	expectedAbstain := sdk.TokensFromConsensusPower(0)
   431  	expectedNo := sdk.TokensFromConsensusPower(10)
   432  	expectedNoWithVeto := sdk.TokensFromConsensusPower(0)
   433  	expectedTallyResult := types.NewTallyResult(expectedYes, expectedAbstain, expectedNo, expectedNoWithVeto)
   434  
   435  	require.True(t, tallyResults.Equals(expectedTallyResult))
   436  }