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 }