github.com/KiraCore/sekai@v0.3.43/x/gov/abci_test.go (about)

     1  package gov_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	simapp "github.com/KiraCore/sekai/app"
     8  	"github.com/KiraCore/sekai/x/gov"
     9  	"github.com/KiraCore/sekai/x/gov/types"
    10  	stakingtypes "github.com/KiraCore/sekai/x/staking/types"
    11  	tokenstypes "github.com/KiraCore/sekai/x/tokens/types"
    12  	tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
    13  	sdk "github.com/cosmos/cosmos-sdk/types"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestEndBlocker_ActiveProposal(t *testing.T) {
    18  	tests := []struct {
    19  		name              string
    20  		prepareScenario   func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress
    21  		validateScenario  func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress)
    22  		blockHeightChange int64
    23  	}{
    24  		{
    25  			name: "proposal passes: min block height for proposal voting time not reached",
    26  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
    27  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
    28  
    29  				proposalID := uint64(1234)
    30  				proposal, err := types.NewProposal(
    31  					proposalID,
    32  					"title",
    33  					"some desc",
    34  					types.NewWhitelistAccountPermissionProposal(
    35  						addrs[0],
    36  						types.PermSetPermissions,
    37  					),
    38  					time.Now(),
    39  					time.Now().Add(10*time.Second),
    40  					time.Now().Add(20*time.Second),
    41  					ctx.BlockHeight()+2,
    42  					ctx.BlockHeight()+3,
    43  				)
    44  				require.NoError(t, err)
    45  
    46  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
    47  				require.NoError(t, err)
    48  				app.CustomGovKeeper.AddToActiveProposals(ctx, proposal)
    49  
    50  				// We set permissions to Vote The proposal to all the actors. 10 in total.
    51  				for i, addr := range addrs {
    52  					actor := types.NewDefaultActor(addr)
    53  					err := app.CustomGovKeeper.AddWhitelistPermission(ctx, actor, types.PermVoteWhitelistAccountPermissionProposal)
    54  					require.NoError(t, err)
    55  
    56  					// Only 4 first users vote yes. We reach quorum but not half of the votes are yes.
    57  					if i < 4 {
    58  						vote := types.NewVote(proposalID, addr, types.OptionYes, sdk.ZeroDec())
    59  						app.CustomGovKeeper.SaveVote(ctx, vote)
    60  					}
    61  				}
    62  
    63  				iterator := app.CustomGovKeeper.GetActiveProposalsWithFinishedVotingEndTimeIterator(ctx, time.Now().Add(10*time.Second))
    64  				requireIteratorCount(t, iterator, 1)
    65  
    66  				iterator = app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
    67  				requireIteratorCount(t, iterator, 0)
    68  
    69  				return addrs
    70  			},
    71  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
    72  				actor, found := app.CustomGovKeeper.GetNetworkActorByAddress(ctx, addrs[0])
    73  				require.True(t, found)
    74  				require.False(t, actor.Permissions.IsWhitelisted(types.PermSetPermissions))
    75  
    76  				// We check that is not in the ActiveProposals
    77  				iterator := app.CustomGovKeeper.GetActiveProposalsWithFinishedVotingEndTimeIterator(ctx, time.Now().Add(15*time.Second))
    78  				requireIteratorCount(t, iterator, 1)
    79  
    80  				// And it is in the EnactmentProposals
    81  				iterator = app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
    82  				requireIteratorCount(t, iterator, 0)
    83  
    84  				proposal, found := app.CustomGovKeeper.GetProposal(ctx, 1234)
    85  				require.True(t, found)
    86  				require.Equal(t, types.Pending, proposal.Result)
    87  			},
    88  			blockHeightChange: 1,
    89  		},
    90  		{
    91  			name: "proposal passes: quorum not reached",
    92  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
    93  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
    94  
    95  				proposalID := uint64(1234)
    96  				proposal, err := types.NewProposal(
    97  					proposalID,
    98  					"title",
    99  					"some desc",
   100  					types.NewWhitelistAccountPermissionProposal(
   101  						addrs[0],
   102  						types.PermSetPermissions,
   103  					),
   104  					time.Now(),
   105  					time.Now(),
   106  					time.Now(),
   107  					ctx.BlockHeight()+2,
   108  					ctx.BlockHeight()+3,
   109  				)
   110  				require.NoError(t, err)
   111  
   112  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   113  				app.CustomGovKeeper.AddToActiveProposals(ctx, proposal)
   114  
   115  				// We set permissions to Vote The proposal to all the actors. 10 in total.
   116  				for i, addr := range addrs {
   117  					actor := types.NewDefaultActor(addr)
   118  					err := app.CustomGovKeeper.AddWhitelistPermission(ctx, actor, types.PermVoteWhitelistAccountPermissionProposal)
   119  					require.NoError(t, err)
   120  
   121  					// Only 3 first users vote yes. We dont reach Quorum.
   122  					if i < 3 {
   123  						vote := types.NewVote(proposalID, addr, types.OptionYes, sdk.ZeroDec())
   124  						app.CustomGovKeeper.SaveVote(ctx, vote)
   125  					}
   126  				}
   127  
   128  				return addrs
   129  			},
   130  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   131  				actor, found := app.CustomGovKeeper.GetNetworkActorByAddress(ctx, addrs[0])
   132  				require.True(t, found)
   133  				require.False(t, actor.Permissions.IsWhitelisted(types.PermSetPermissions))
   134  
   135  				// We check that is not in the ActiveProposals
   136  				iterator := app.CustomGovKeeper.GetActiveProposalsWithFinishedVotingEndTimeIterator(ctx, time.Now().Add(15*time.Second))
   137  				requireIteratorCount(t, iterator, 0)
   138  
   139  				// And it is in the EnactmentProposals
   140  				iterator = app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   141  				requireIteratorCount(t, iterator, 1)
   142  
   143  				proposal, found := app.CustomGovKeeper.GetProposal(ctx, 1234)
   144  				require.True(t, found)
   145  				require.Equal(t, types.QuorumNotReached, proposal.Result)
   146  			},
   147  			blockHeightChange: 3,
   148  		},
   149  		{
   150  			name: "proposal passes and joins Enactment place",
   151  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   152  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
   153  
   154  				proposalID := uint64(1234)
   155  				proposal, err := types.NewProposal(
   156  					proposalID,
   157  					"title",
   158  					"some desc",
   159  					types.NewWhitelistAccountPermissionProposal(
   160  						addrs[0],
   161  						types.PermSetPermissions,
   162  					),
   163  					time.Now(),
   164  					time.Now().Add(10*time.Second),
   165  					time.Now().Add(20*time.Second),
   166  					ctx.BlockHeight()+2,
   167  					ctx.BlockHeight()+3,
   168  				)
   169  				require.NoError(t, err)
   170  
   171  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   172  				require.NoError(t, err)
   173  				app.CustomGovKeeper.AddToActiveProposals(ctx, proposal)
   174  
   175  				// We set permissions to Vote The proposal to all the actors. 10 in total.
   176  				for i, addr := range addrs {
   177  					actor := types.NewDefaultActor(addr)
   178  					err := app.CustomGovKeeper.AddWhitelistPermission(ctx, actor, types.PermVoteWhitelistAccountPermissionProposal)
   179  					require.NoError(t, err)
   180  
   181  					// Only 4 first users vote yes. We reach quorum but not half of the votes are yes.
   182  					if i < 4 {
   183  						vote := types.NewVote(proposalID, addr, types.OptionYes, sdk.ZeroDec())
   184  						app.CustomGovKeeper.SaveVote(ctx, vote)
   185  					}
   186  				}
   187  
   188  				iterator := app.CustomGovKeeper.GetActiveProposalsWithFinishedVotingEndTimeIterator(ctx, time.Now().Add(10*time.Second))
   189  				requireIteratorCount(t, iterator, 1)
   190  
   191  				iterator = app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   192  				requireIteratorCount(t, iterator, 0)
   193  
   194  				return addrs
   195  			},
   196  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   197  				actor, found := app.CustomGovKeeper.GetNetworkActorByAddress(ctx, addrs[0])
   198  				require.True(t, found)
   199  				require.False(t, actor.Permissions.IsWhitelisted(types.PermSetPermissions))
   200  
   201  				// We check that is not in the ActiveProposals
   202  				iterator := app.CustomGovKeeper.GetActiveProposalsWithFinishedVotingEndTimeIterator(ctx, time.Now().Add(15*time.Second))
   203  				requireIteratorCount(t, iterator, 0)
   204  
   205  				// And it is in the EnactmentProposals
   206  				iterator = app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   207  				requireIteratorCount(t, iterator, 1)
   208  
   209  				proposal, found := app.CustomGovKeeper.GetProposal(ctx, 1234)
   210  				require.True(t, found)
   211  				require.Equal(t, types.Enactment, proposal.Result)
   212  			},
   213  			blockHeightChange: 3,
   214  		},
   215  		{
   216  			name: "Passed proposal in enactment is applied and min block height for enactment not reached",
   217  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   218  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
   219  
   220  				actor := types.NewDefaultActor(addrs[0])
   221  				app.CustomGovKeeper.SaveNetworkActor(ctx, actor)
   222  
   223  				proposalID := uint64(1234)
   224  				proposal, err := types.NewProposal(
   225  					proposalID,
   226  					"title",
   227  					"some desc",
   228  					types.NewWhitelistAccountPermissionProposal(
   229  						addrs[0],
   230  						types.PermSetPermissions,
   231  					),
   232  					time.Now(),
   233  					time.Now().Add(10*time.Second),
   234  					time.Now().Add(20*time.Second),
   235  					ctx.BlockHeight()+2,
   236  					ctx.BlockHeight()+3,
   237  				)
   238  				require.NoError(t, err)
   239  
   240  				proposal.Result = types.Enactment
   241  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   242  
   243  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   244  
   245  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   246  				requireIteratorCount(t, iterator, 1)
   247  
   248  				return addrs
   249  			},
   250  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   251  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   252  				requireIteratorCount(t, iterator, 1)
   253  			},
   254  			blockHeightChange: 0,
   255  		},
   256  		{
   257  			name: "Passed proposal in enactment is applied and removed from enactment list: Assign permission",
   258  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   259  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
   260  
   261  				actor := types.NewDefaultActor(addrs[0])
   262  				app.CustomGovKeeper.SaveNetworkActor(ctx, actor)
   263  
   264  				proposalID := uint64(1234)
   265  				proposal, err := types.NewProposal(
   266  					proposalID,
   267  					"title",
   268  					"some desc",
   269  					types.NewWhitelistAccountPermissionProposal(
   270  						addrs[0],
   271  						types.PermSetPermissions,
   272  					),
   273  					time.Now(),
   274  					time.Now().Add(10*time.Second),
   275  					time.Now().Add(20*time.Second),
   276  					ctx.BlockHeight()+2,
   277  					ctx.BlockHeight()+3,
   278  				)
   279  				require.NoError(t, err)
   280  
   281  				proposal.Result = types.Enactment
   282  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   283  
   284  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   285  
   286  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   287  				requireIteratorCount(t, iterator, 1)
   288  
   289  				return addrs
   290  			},
   291  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   292  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   293  				requireIteratorCount(t, iterator, 0)
   294  
   295  				actor, found := app.CustomGovKeeper.GetNetworkActorByAddress(ctx, addrs[0])
   296  				require.True(t, found)
   297  
   298  				require.True(t, actor.Permissions.IsWhitelisted(types.PermSetPermissions))
   299  			},
   300  			blockHeightChange: 3,
   301  		},
   302  		{
   303  			name: "Passed proposal in enactment is applied and removed from enactment list, actor does not exist",
   304  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   305  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
   306  
   307  				proposalID := uint64(1234)
   308  				proposal, err := types.NewProposal(
   309  					proposalID,
   310  					"title",
   311  					"some desc",
   312  					types.NewWhitelistAccountPermissionProposal(
   313  						addrs[0],
   314  						types.PermSetPermissions,
   315  					),
   316  					time.Now(),
   317  					time.Now().Add(10*time.Second),
   318  					time.Now().Add(20*time.Second),
   319  					ctx.BlockHeight()+2,
   320  					ctx.BlockHeight()+3,
   321  				)
   322  				require.NoError(t, err)
   323  
   324  				proposal.Result = types.Enactment
   325  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   326  
   327  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   328  
   329  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   330  				requireIteratorCount(t, iterator, 1)
   331  
   332  				return addrs
   333  			},
   334  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   335  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   336  				requireIteratorCount(t, iterator, 0)
   337  
   338  				actor, found := app.CustomGovKeeper.GetNetworkActorByAddress(ctx, addrs[0])
   339  				require.True(t, found)
   340  
   341  				require.True(t, actor.Permissions.IsWhitelisted(types.PermSetPermissions))
   342  			},
   343  			blockHeightChange: 3,
   344  		},
   345  		{
   346  			name: "Passed proposal in enactment is applied and removed from enactment list: Upsert Data Registry",
   347  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   348  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
   349  
   350  				actor := types.NewDefaultActor(addrs[0])
   351  				app.CustomGovKeeper.SaveNetworkActor(ctx, actor)
   352  
   353  				proposalID := uint64(1234)
   354  				proposal, err := types.NewProposal(
   355  					proposalID,
   356  					"title",
   357  					"some desc",
   358  					types.NewUpsertDataRegistryProposal(
   359  						"theKey",
   360  						"theHash",
   361  						"theReference",
   362  						"theEncoding",
   363  						1234,
   364  					),
   365  					time.Now(),
   366  					time.Now().Add(10*time.Second),
   367  					time.Now().Add(20*time.Second),
   368  					ctx.BlockHeight()+2,
   369  					ctx.BlockHeight()+3,
   370  				)
   371  				require.NoError(t, err)
   372  
   373  				proposal.Result = types.Enactment
   374  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   375  
   376  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   377  
   378  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   379  				requireIteratorCount(t, iterator, 1)
   380  
   381  				return addrs
   382  			},
   383  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   384  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   385  				requireIteratorCount(t, iterator, 0)
   386  
   387  				entry, found := app.CustomGovKeeper.GetDataRegistryEntry(ctx, "theKey")
   388  				require.True(t, found)
   389  
   390  				require.Equal(t, "theHash", entry.Hash)
   391  				require.Equal(t, "theEncoding", entry.Encoding)
   392  				require.Equal(t, "theReference", entry.Reference)
   393  				require.Equal(t, uint64(1234), entry.Size_)
   394  			},
   395  			blockHeightChange: 3,
   396  		},
   397  		{
   398  			name: "Passed proposal in enactment is applied and removed from enactment list: Set Network Property",
   399  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   400  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
   401  
   402  				actor := types.NewDefaultActor(addrs[0])
   403  				app.CustomGovKeeper.SaveNetworkActor(ctx, actor)
   404  
   405  				proposalID := uint64(1234)
   406  				proposal, err := types.NewProposal(
   407  					proposalID,
   408  					"title",
   409  					"some desc",
   410  					types.NewSetNetworkPropertyProposal(
   411  						types.MinTxFee,
   412  						types.NetworkPropertyValue{Value: 300},
   413  					),
   414  					time.Now(),
   415  					time.Now().Add(10*time.Second),
   416  					time.Now().Add(20*time.Second),
   417  					ctx.BlockHeight()+2,
   418  					ctx.BlockHeight()+3,
   419  				)
   420  				require.NoError(t, err)
   421  
   422  				proposal.Result = types.Enactment
   423  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   424  
   425  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   426  
   427  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   428  				requireIteratorCount(t, iterator, 1)
   429  
   430  				return addrs
   431  			},
   432  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   433  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   434  				requireIteratorCount(t, iterator, 0)
   435  
   436  				minTxFee, err := app.CustomGovKeeper.GetNetworkProperty(ctx, types.MinTxFee)
   437  				require.NoError(t, err)
   438  
   439  				require.Equal(t, uint64(300), minTxFee.Value)
   440  			},
   441  			blockHeightChange: 3,
   442  		},
   443  		{
   444  			name: "Passed proposal in enactment is applied and removed from enactment list: Set Token Alias",
   445  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   446  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
   447  
   448  				actor := types.NewDefaultActor(addrs[0])
   449  				app.CustomGovKeeper.SaveNetworkActor(ctx, actor)
   450  
   451  				proposalID := uint64(1234)
   452  				proposal, err := types.NewProposal(
   453  					proposalID,
   454  					"title",
   455  					"some desc",
   456  					tokenstypes.NewUpsertTokenAliasProposal(
   457  						"EUR",
   458  						"Euro",
   459  						"http://www.google.es",
   460  						12,
   461  						[]string{
   462  							"eur",
   463  							"€",
   464  						},
   465  						false,
   466  					),
   467  					time.Now(),
   468  					time.Now().Add(10*time.Second),
   469  					time.Now().Add(20*time.Second),
   470  					ctx.BlockHeight()+2,
   471  					ctx.BlockHeight()+3,
   472  				)
   473  				require.NoError(t, err)
   474  
   475  				proposal.Result = types.Enactment
   476  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   477  
   478  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   479  
   480  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   481  				requireIteratorCount(t, iterator, 1)
   482  
   483  				return addrs
   484  			},
   485  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   486  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   487  				requireIteratorCount(t, iterator, 0)
   488  
   489  				token := app.TokensKeeper.GetTokenAlias(ctx, "EUR")
   490  				require.Equal(t, "Euro", token.Name)
   491  			},
   492  			blockHeightChange: 3,
   493  		},
   494  		{
   495  			name: "Passed proposal in enactment is applied and removed from enactment list: Set Token Rates",
   496  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   497  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 10, sdk.NewInt(100))
   498  
   499  				actor := types.NewDefaultActor(addrs[0])
   500  				app.CustomGovKeeper.SaveNetworkActor(ctx, actor)
   501  
   502  				proposalID := uint64(1234)
   503  				proposal, err := types.NewProposal(
   504  					proposalID,
   505  					"title",
   506  					"some desc",
   507  					tokenstypes.NewUpsertTokenRatesProposal(
   508  						"btc",
   509  						sdk.NewDec(1234),
   510  						false,
   511  						sdk.ZeroDec(),
   512  						sdk.ZeroInt(),
   513  						false,
   514  						false,
   515  					),
   516  					time.Now(),
   517  					time.Now().Add(10*time.Second),
   518  					time.Now().Add(20*time.Second),
   519  					ctx.BlockHeight()+2,
   520  					ctx.BlockHeight()+3,
   521  				)
   522  				require.NoError(t, err)
   523  
   524  				proposal.Result = types.Enactment
   525  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   526  
   527  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   528  
   529  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   530  				requireIteratorCount(t, iterator, 1)
   531  
   532  				return addrs
   533  			},
   534  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   535  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   536  				requireIteratorCount(t, iterator, 0)
   537  
   538  				token := app.TokensKeeper.GetTokenRate(ctx, "btc")
   539  				require.Equal(t, sdk.NewDec(1234), token.FeeRate)
   540  				require.Equal(t, "btc", token.Denom)
   541  				require.Equal(t, false, token.FeePayments)
   542  			},
   543  			blockHeightChange: 3,
   544  		},
   545  		{
   546  			name: "Passed proposal in enactment is applied and removed from enactment list: Unjail Validator",
   547  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   548  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(100))
   549  				valAddr := sdk.ValAddress(addrs[0])
   550  				pubkeys := simapp.CreateTestPubKeys(1)
   551  				pubKey := pubkeys[0]
   552  
   553  				actor := types.NewDefaultActor(addrs[0])
   554  				app.CustomGovKeeper.SaveNetworkActor(ctx, actor)
   555  
   556  				val, err := stakingtypes.NewValidator(valAddr, pubKey)
   557  				require.NoError(t, err)
   558  				app.CustomStakingKeeper.AddValidator(ctx, val)
   559  				err = app.CustomStakingKeeper.Jail(ctx, val.ValKey)
   560  				require.NoError(t, err)
   561  
   562  				proposalID := uint64(1234)
   563  				proposal, err := types.NewProposal(
   564  					proposalID,
   565  					"title",
   566  					"some desc",
   567  					stakingtypes.NewUnjailValidatorProposal(
   568  						addrs[0],
   569  						valAddr,
   570  						"theProposal",
   571  					),
   572  					time.Now(),
   573  					time.Now().Add(10*time.Second),
   574  					time.Now().Add(20*time.Second),
   575  					ctx.BlockHeight()+2,
   576  					ctx.BlockHeight()+3,
   577  				)
   578  				require.NoError(t, err)
   579  
   580  				proposal.Result = types.Enactment
   581  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   582  
   583  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   584  
   585  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   586  				requireIteratorCount(t, iterator, 1)
   587  
   588  				return addrs
   589  			},
   590  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   591  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   592  				requireIteratorCount(t, iterator, 0)
   593  
   594  				validator, err := app.CustomStakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0]))
   595  				require.NoError(t, err)
   596  
   597  				require.False(t, validator.IsJailed())
   598  			},
   599  			blockHeightChange: 3,
   600  		},
   601  		{
   602  			name: "Passed proposal in enactment is applied and removed from enactment list: Create Role",
   603  			prepareScenario: func(app *simapp.SekaiApp, ctx sdk.Context) []sdk.AccAddress {
   604  				addrs := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(100))
   605  
   606  				actor := types.NewDefaultActor(addrs[0])
   607  				app.CustomGovKeeper.SaveNetworkActor(ctx, actor)
   608  
   609  				proposalID := uint64(1234)
   610  				proposal, err := types.NewProposal(
   611  					proposalID,
   612  					"title",
   613  					"some desc",
   614  					types.NewCreateRoleProposal(
   615  						"role1000",
   616  						"role1000 description",
   617  						[]types.PermValue{
   618  							types.PermClaimValidator,
   619  						},
   620  						[]types.PermValue{
   621  							types.PermChangeTxFee,
   622  						},
   623  					),
   624  					time.Now(),
   625  					time.Now().Add(10*time.Second),
   626  					time.Now().Add(20*time.Second),
   627  					ctx.BlockHeight()+2,
   628  					ctx.BlockHeight()+3,
   629  				)
   630  				require.NoError(t, err)
   631  
   632  				proposal.Result = types.Enactment
   633  				app.CustomGovKeeper.SaveProposal(ctx, proposal)
   634  
   635  				app.CustomGovKeeper.AddToEnactmentProposals(ctx, proposal)
   636  
   637  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   638  				requireIteratorCount(t, iterator, 1)
   639  
   640  				_, err = app.CustomGovKeeper.GetRoleBySid(ctx, "role1000")
   641  				require.Error(t, err)
   642  
   643  				return addrs
   644  			},
   645  			validateScenario: func(t *testing.T, app *simapp.SekaiApp, ctx sdk.Context, addrs []sdk.AccAddress) {
   646  				iterator := app.CustomGovKeeper.GetEnactmentProposalsWithFinishedEnactmentEndTimeIterator(ctx, time.Now().Add(25*time.Second))
   647  				requireIteratorCount(t, iterator, 0)
   648  
   649  				role, err := app.CustomGovKeeper.GetRoleBySid(ctx, "role1000")
   650  				require.NoError(t, err)
   651  				perms, found := app.CustomGovKeeper.GetPermissionsForRole(ctx, uint64(role.Id))
   652  				require.True(t, found)
   653  				require.True(t, perms.IsWhitelisted(types.PermClaimValidator))
   654  				require.True(t, perms.IsBlacklisted(types.PermChangeTxFee))
   655  			},
   656  			blockHeightChange: 3,
   657  		},
   658  	}
   659  
   660  	for _, tt := range tests {
   661  		tt := tt
   662  		t.Run(tt.name, func(t *testing.T) {
   663  			app := simapp.Setup(false)
   664  			ctx := app.NewContext(false, tmproto.Header{})
   665  			ctx = ctx.WithBlockTime(time.Now())
   666  
   667  			addrs := tt.prepareScenario(app, ctx)
   668  
   669  			ctx = ctx.WithBlockTime(time.Now().Add(time.Second * 25))
   670  			ctx = ctx.WithBlockHeight(ctx.BlockHeight() + tt.blockHeightChange)
   671  
   672  			gov.EndBlocker(ctx, app.CustomGovKeeper)
   673  
   674  			tt.validateScenario(t, app, ctx, addrs)
   675  		})
   676  	}
   677  }
   678  
   679  func requireIteratorCount(t *testing.T, iterator sdk.Iterator, expectedCount int) {
   680  	c := 0
   681  	for ; iterator.Valid(); iterator.Next() {
   682  		c++
   683  	}
   684  
   685  	require.Equal(t, expectedCount, c)
   686  }