github.com/Finschia/finschia-sdk@v0.49.1/x/foundation/keeper/internal/genesis_test.go (about)

     1  package internal_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    10  
    11  	"github.com/Finschia/finschia-sdk/crypto/keys/secp256k1"
    12  	"github.com/Finschia/finschia-sdk/simapp"
    13  	"github.com/Finschia/finschia-sdk/testutil/testdata"
    14  	sdk "github.com/Finschia/finschia-sdk/types"
    15  	authtypes "github.com/Finschia/finschia-sdk/x/auth/types"
    16  	"github.com/Finschia/finschia-sdk/x/foundation"
    17  	"github.com/Finschia/finschia-sdk/x/foundation/keeper/internal"
    18  )
    19  
    20  func workingPolicy() foundation.DecisionPolicy {
    21  	return &foundation.ThresholdDecisionPolicy{
    22  		Threshold: sdk.OneDec(),
    23  		Windows: &foundation.DecisionPolicyWindows{
    24  			VotingPeriod: 7 * 24 * time.Hour, // one week
    25  		},
    26  	}
    27  }
    28  
    29  func TestImportExportGenesis(t *testing.T) {
    30  	checkTx := false
    31  	app := simapp.Setup(checkTx)
    32  	testdata.RegisterInterfaces(app.InterfaceRegistry())
    33  
    34  	ctx := app.BaseApp.NewContext(checkTx, tmproto.Header{})
    35  	keeper := app.FoundationKeeper
    36  
    37  	createAddress := func() sdk.AccAddress {
    38  		return sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
    39  	}
    40  
    41  	authority := foundation.DefaultAuthority()
    42  	existingAccount := createAddress()
    43  	app.AccountKeeper.SetAccount(ctx, app.AccountKeeper.NewAccountWithAddress(ctx, existingAccount))
    44  
    45  	member := createAddress()
    46  	stranger := createAddress()
    47  
    48  	testCases := map[string]struct {
    49  		init   *foundation.GenesisState
    50  		valid  bool
    51  		export *foundation.GenesisState
    52  	}{
    53  		"minimal": {
    54  			init: &foundation.GenesisState{
    55  				Params:     foundation.DefaultParams(),
    56  				Foundation: foundation.DefaultFoundation(),
    57  			},
    58  			valid: true,
    59  			export: &foundation.GenesisState{
    60  				Params:     foundation.DefaultParams(),
    61  				Foundation: foundation.DefaultFoundation(),
    62  			},
    63  		},
    64  		"members": {
    65  			init: &foundation.GenesisState{
    66  				Params: foundation.DefaultParams(),
    67  				Foundation: *foundation.FoundationInfo{
    68  					Version:     1,
    69  					TotalWeight: sdk.OneDec(),
    70  				}.WithDecisionPolicy(workingPolicy()),
    71  				Members: []foundation.Member{
    72  					{
    73  						Address: member.String(),
    74  					},
    75  				},
    76  			},
    77  			valid: true,
    78  			export: &foundation.GenesisState{
    79  				Params: foundation.DefaultParams(),
    80  				Foundation: *foundation.FoundationInfo{
    81  					Version:     1,
    82  					TotalWeight: sdk.OneDec(),
    83  				}.WithDecisionPolicy(workingPolicy()),
    84  				Members: []foundation.Member{
    85  					{
    86  						Address: member.String(),
    87  					},
    88  				},
    89  			},
    90  		},
    91  		"proposals": {
    92  			init: &foundation.GenesisState{
    93  				Params: foundation.DefaultParams(),
    94  				Foundation: *foundation.FoundationInfo{
    95  					Version:     1,
    96  					TotalWeight: sdk.OneDec(),
    97  				}.WithDecisionPolicy(workingPolicy()),
    98  				Members: []foundation.Member{
    99  					{
   100  						Address: member.String(),
   101  					},
   102  				},
   103  				PreviousProposalId: 1,
   104  				Proposals: []foundation.Proposal{
   105  					*foundation.Proposal{
   106  						Id:                1,
   107  						Proposers:         []string{member.String()},
   108  						FoundationVersion: 1,
   109  					}.WithMsgs([]sdk.Msg{testdata.NewTestMsg(authority)}),
   110  				},
   111  				Votes: []foundation.Vote{
   112  					{
   113  						ProposalId: 1,
   114  						Voter:      member.String(),
   115  						Option:     foundation.VOTE_OPTION_YES,
   116  					},
   117  				},
   118  			},
   119  			valid: true,
   120  			export: &foundation.GenesisState{
   121  				Params: foundation.DefaultParams(),
   122  				Foundation: *foundation.FoundationInfo{
   123  					Version:     1,
   124  					TotalWeight: sdk.OneDec(),
   125  				}.WithDecisionPolicy(workingPolicy()),
   126  				Members: []foundation.Member{
   127  					{
   128  						Address: member.String(),
   129  					},
   130  				},
   131  				PreviousProposalId: 1,
   132  				Proposals: []foundation.Proposal{
   133  					*foundation.Proposal{
   134  						Id:                1,
   135  						Proposers:         []string{member.String()},
   136  						FoundationVersion: 1,
   137  						FinalTallyResult: foundation.TallyResult{
   138  							YesCount:        sdk.ZeroDec(),
   139  							NoCount:         sdk.ZeroDec(),
   140  							AbstainCount:    sdk.ZeroDec(),
   141  							NoWithVetoCount: sdk.ZeroDec(),
   142  						},
   143  					}.WithMsgs([]sdk.Msg{testdata.NewTestMsg(authority)}),
   144  				},
   145  				Votes: []foundation.Vote{
   146  					{
   147  						ProposalId: 1,
   148  						Voter:      member.String(),
   149  						Option:     foundation.VOTE_OPTION_YES,
   150  					},
   151  				},
   152  			},
   153  		},
   154  		"authorizations": {
   155  			init: &foundation.GenesisState{
   156  				Params:     foundation.DefaultParams(),
   157  				Foundation: foundation.DefaultFoundation(),
   158  				Censorships: []foundation.Censorship{
   159  					{
   160  						MsgTypeUrl: sdk.MsgTypeURL((*foundation.MsgWithdrawFromTreasury)(nil)),
   161  						Authority:  foundation.CensorshipAuthorityFoundation,
   162  					},
   163  				},
   164  				Authorizations: []foundation.GrantAuthorization{
   165  					*foundation.GrantAuthorization{
   166  						Grantee: stranger.String(),
   167  					}.WithAuthorization(&foundation.ReceiveFromTreasuryAuthorization{}),
   168  				},
   169  			},
   170  			valid: true,
   171  			export: &foundation.GenesisState{
   172  				Params:     foundation.DefaultParams(),
   173  				Foundation: foundation.DefaultFoundation(),
   174  				Censorships: []foundation.Censorship{
   175  					{
   176  						MsgTypeUrl: sdk.MsgTypeURL((*foundation.MsgWithdrawFromTreasury)(nil)),
   177  						Authority:  foundation.CensorshipAuthorityFoundation,
   178  					},
   179  				},
   180  				Authorizations: []foundation.GrantAuthorization{
   181  					*foundation.GrantAuthorization{
   182  						Grantee: stranger.String(),
   183  					}.WithAuthorization(&foundation.ReceiveFromTreasuryAuthorization{}),
   184  				},
   185  			},
   186  		},
   187  		"pool": {
   188  			init: &foundation.GenesisState{
   189  				Params:     foundation.DefaultParams(),
   190  				Foundation: foundation.DefaultFoundation(),
   191  				Pool: foundation.Pool{
   192  					Treasury: sdk.NewDecCoins(sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.OneInt())),
   193  				},
   194  			},
   195  			valid: true,
   196  			export: &foundation.GenesisState{
   197  				Params:     foundation.DefaultParams(),
   198  				Foundation: foundation.DefaultFoundation(),
   199  				Pool: foundation.Pool{
   200  					Treasury: sdk.NewDecCoins(sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.OneInt())),
   201  				},
   202  			},
   203  		},
   204  		"member of long metadata": {
   205  			init: &foundation.GenesisState{
   206  				Params: foundation.DefaultParams(),
   207  				Foundation: *foundation.FoundationInfo{
   208  					Version:     1,
   209  					TotalWeight: sdk.OneDec(),
   210  				}.WithDecisionPolicy(workingPolicy()),
   211  				Members: []foundation.Member{
   212  					{
   213  						Address:  member.String(),
   214  						Metadata: string(make([]rune, 256)),
   215  					},
   216  				},
   217  			},
   218  		},
   219  		"proposal of long metadata": {
   220  			init: &foundation.GenesisState{
   221  				Params: foundation.DefaultParams(),
   222  				Foundation: *foundation.FoundationInfo{
   223  					Version:     1,
   224  					TotalWeight: sdk.OneDec(),
   225  				}.WithDecisionPolicy(workingPolicy()),
   226  				Members: []foundation.Member{
   227  					{
   228  						Address: member.String(),
   229  					},
   230  				},
   231  				PreviousProposalId: 1,
   232  				Proposals: []foundation.Proposal{
   233  					*foundation.Proposal{
   234  						Id:                1,
   235  						Metadata:          string(make([]rune, 256)),
   236  						Proposers:         []string{member.String()},
   237  						FoundationVersion: 1,
   238  					}.WithMsgs([]sdk.Msg{testdata.NewTestMsg()}),
   239  				},
   240  			},
   241  		},
   242  		"vote of long metadata": {
   243  			init: &foundation.GenesisState{
   244  				Params: foundation.DefaultParams(),
   245  				Foundation: *foundation.FoundationInfo{
   246  					Version:     1,
   247  					TotalWeight: sdk.OneDec(),
   248  				}.WithDecisionPolicy(workingPolicy()),
   249  				Members: []foundation.Member{
   250  					{
   251  						Address: member.String(),
   252  					},
   253  				},
   254  				PreviousProposalId: 1,
   255  				Proposals: []foundation.Proposal{
   256  					*foundation.Proposal{
   257  						Id:                1,
   258  						Proposers:         []string{member.String()},
   259  						FoundationVersion: 1,
   260  					}.WithMsgs([]sdk.Msg{testdata.NewTestMsg()}),
   261  				},
   262  				Votes: []foundation.Vote{
   263  					{
   264  						ProposalId: 1,
   265  						Voter:      member.String(),
   266  						Option:     foundation.VOTE_OPTION_YES,
   267  						Metadata:   string(make([]rune, 256)),
   268  					},
   269  				},
   270  			},
   271  		},
   272  	}
   273  
   274  	for name, tc := range testCases {
   275  		ctx, _ := ctx.CacheContext()
   276  
   277  		err := foundation.ValidateGenesis(*tc.init)
   278  		require.NoError(t, err, name)
   279  
   280  		err = keeper.InitGenesis(ctx, tc.init)
   281  		if !tc.valid {
   282  			require.Error(t, err, name)
   283  			continue
   284  		}
   285  		require.NoError(t, err, name)
   286  
   287  		actual := keeper.ExportGenesis(ctx)
   288  		require.Equal(t, tc.export, actual, name)
   289  	}
   290  }
   291  
   292  func TestShouldPanicWhenFailToGenerateFoundationModuleAccountInInitGenesis(t *testing.T) {
   293  	checkTx := false
   294  	app := simapp.Setup(checkTx)
   295  	testdata.RegisterInterfaces(app.InterfaceRegistry())
   296  	testdata.RegisterMsgServer(app.MsgServiceRouter(), testdata.MsgServerImpl{})
   297  	gs := &foundation.GenesisState{
   298  		Params:     foundation.DefaultParams(),
   299  		Foundation: foundation.DefaultFoundation(),
   300  	}
   301  	ctx := app.BaseApp.NewContext(checkTx, tmproto.Header{})
   302  
   303  	testCases := map[string]struct {
   304  		mockAccKeeper *stubAccKeeper
   305  	}{
   306  		"failed to generate module account=" + foundation.ModuleName: {
   307  			mockAccKeeper: &stubAccKeeper{nameToFail: foundation.ModuleName},
   308  		},
   309  		"failed to generate module account=" + foundation.TreasuryName: {
   310  			mockAccKeeper: &stubAccKeeper{nameToFail: foundation.TreasuryName},
   311  		},
   312  	}
   313  
   314  	for name, tc := range testCases {
   315  		t.Run(name, func(t *testing.T) {
   316  			assert.Panics(t, func() {
   317  				k := internal.NewKeeper(
   318  					app.AppCodec(),
   319  					app.GetKey(foundation.ModuleName),
   320  					app.MsgServiceRouter(),
   321  					tc.mockAccKeeper,
   322  					app.BankKeeper,
   323  					authtypes.FeeCollectorName,
   324  					foundation.DefaultConfig(),
   325  					foundation.DefaultAuthority().String(),
   326  					app.GetSubspace(foundation.ModuleName),
   327  				)
   328  
   329  				_ = k.InitGenesis(ctx, gs)
   330  				assert.FailNow(t, "not supposed to reach here, should panic before")
   331  			})
   332  		})
   333  	}
   334  }
   335  
   336  type stubAccKeeper struct {
   337  	nameToFail string
   338  }
   339  
   340  func (s *stubAccKeeper) GetModuleAccount(_ sdk.Context, name string) authtypes.ModuleAccountI {
   341  	if s.nameToFail == name {
   342  		return nil
   343  	}
   344  	return authtypes.NewEmptyModuleAccount("dontcare")
   345  }