github.com/lino-network/lino@v0.6.11/app/app.go (about) 1 package app 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "os" 8 "sync" 9 10 bam "github.com/cosmos/cosmos-sdk/baseapp" 11 wire "github.com/cosmos/cosmos-sdk/codec" 12 sdk "github.com/cosmos/cosmos-sdk/types" 13 cauth "github.com/cosmos/cosmos-sdk/x/auth" 14 "github.com/spf13/viper" 15 abci "github.com/tendermint/tendermint/abci/types" 16 tmcli "github.com/tendermint/tendermint/libs/cli" 17 "github.com/tendermint/tendermint/libs/log" 18 tmtypes "github.com/tendermint/tendermint/types" 19 dbm "github.com/tendermint/tm-db" 20 21 "github.com/lino-network/lino/param" 22 "github.com/lino-network/lino/types" 23 acc "github.com/lino-network/lino/x/account" 24 accmn "github.com/lino-network/lino/x/account/manager" 25 accmodel "github.com/lino-network/lino/x/account/model" 26 acctypes "github.com/lino-network/lino/x/account/types" 27 "github.com/lino-network/lino/x/auth" 28 bandwidth "github.com/lino-network/lino/x/bandwidth" 29 bandwidthmn "github.com/lino-network/lino/x/bandwidth/manager" 30 bandwidthtypes "github.com/lino-network/lino/x/bandwidth/types" 31 dev "github.com/lino-network/lino/x/developer" 32 devmn "github.com/lino-network/lino/x/developer/manager" 33 devtypes "github.com/lino-network/lino/x/developer/types" 34 global "github.com/lino-network/lino/x/global" 35 globalmn "github.com/lino-network/lino/x/global/manager" 36 globaltypes "github.com/lino-network/lino/x/global/types" 37 post "github.com/lino-network/lino/x/post" 38 postmn "github.com/lino-network/lino/x/post/manager" 39 posttypes "github.com/lino-network/lino/x/post/types" 40 price "github.com/lino-network/lino/x/price" 41 pricemn "github.com/lino-network/lino/x/price/manager" 42 pricetypes "github.com/lino-network/lino/x/price/types" 43 rep "github.com/lino-network/lino/x/reputation" 44 val "github.com/lino-network/lino/x/validator" 45 valmn "github.com/lino-network/lino/x/validator/manager" 46 valtypes "github.com/lino-network/lino/x/validator/types" 47 vote "github.com/lino-network/lino/x/vote" 48 votemn "github.com/lino-network/lino/x/vote/manager" 49 votetypes "github.com/lino-network/lino/x/vote/types" 50 ) 51 52 const ( 53 appName = "LinoBlockchain" 54 55 // state files 56 prevStateFolder = "prevstates/" 57 currStateFolder = "currstates/" 58 accountStateFile = "account" 59 developerStateFile = "developer" 60 postStateFile = "post" 61 globalStateFile = "global" 62 validatorStateFile = "validator" 63 reputationStateFile = "reputation" 64 voterStateFile = "voter" 65 ) 66 67 // default home directories for expected binaries 68 var ( 69 DefaultNodeHome = os.ExpandEnv("$HOME/.lino") 70 ) 71 72 // LinoBlockchain - Extended ABCI application 73 type LinoBlockchain struct { 74 *bam.BaseApp 75 cdc *wire.Codec 76 77 // keys to access the KVStore 78 CapKeyMainStore *sdk.KVStoreKey 79 CapKeyAccountStore *sdk.KVStoreKey 80 CapKeyPostStore *sdk.KVStoreKey 81 CapKeyValStore *sdk.KVStoreKey 82 CapKeyVoteStore *sdk.KVStoreKey 83 CapKeyDeveloperStore *sdk.KVStoreKey 84 CapKeyIBCStore *sdk.KVStoreKey 85 CapKeyGlobalStore *sdk.KVStoreKey 86 CapKeyParamStore *sdk.KVStoreKey 87 CapKeyProposalStore *sdk.KVStoreKey 88 CapKeyReputationV2Store *sdk.KVStoreKey 89 CapKeyBandwidthStore *sdk.KVStoreKey 90 CapKeyPriceStore *sdk.KVStoreKey 91 92 // manager for different KVStore 93 accountManager acc.AccountKeeper 94 postManager post.PostKeeper 95 valManager val.ValidatorKeeper 96 globalManager global.GlobalKeeper 97 voteManager vote.VoteKeeper 98 developerManager dev.DeveloperKeeper 99 // proposalManager proposal.ProposalManager 100 reputationManager rep.ReputationKeeper 101 bandwidthManager bandwidth.BandwidthKeeper 102 priceManager price.PriceKeeper 103 104 // global param 105 paramHolder param.ParamHolder 106 107 // auth 108 auth sdk.AnteHandler 109 } 110 111 // NewLinoBlockchain - create a Lino Blockchain instance 112 func NewLinoBlockchain( 113 logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptions ...func(*bam.BaseApp)) *LinoBlockchain { 114 // create your application object 115 cdc := MakeCodec() 116 bApp := bam.NewBaseApp(appName, logger, db, types.TxDecoder(cdc), baseAppOptions...) 117 bApp.SetCommitMultiStoreTracer(traceStore) 118 var lb = &LinoBlockchain{ 119 BaseApp: bApp, 120 cdc: cdc, 121 CapKeyMainStore: sdk.NewKVStoreKey(types.MainKVStoreKey), 122 CapKeyAccountStore: sdk.NewKVStoreKey(types.AccountKVStoreKey), 123 CapKeyPostStore: sdk.NewKVStoreKey(types.PostKVStoreKey), 124 CapKeyValStore: sdk.NewKVStoreKey(types.ValidatorKVStoreKey), 125 CapKeyVoteStore: sdk.NewKVStoreKey(types.VoteKVStoreKey), 126 CapKeyDeveloperStore: sdk.NewKVStoreKey(types.DeveloperKVStoreKey), 127 CapKeyGlobalStore: sdk.NewKVStoreKey(types.GlobalKVStoreKey), 128 CapKeyParamStore: sdk.NewKVStoreKey(types.ParamKVStoreKey), 129 CapKeyProposalStore: sdk.NewKVStoreKey(types.ProposalKVStoreKey), 130 CapKeyReputationV2Store: sdk.NewKVStoreKey(types.ReputationV2KVStoreKey), 131 CapKeyBandwidthStore: sdk.NewKVStoreKey(types.BandwidthKVStoreKey), 132 CapKeyPriceStore: sdk.NewKVStoreKey(types.PriceKVStoreKey), 133 } 134 // layer-1: basics 135 lb.paramHolder = param.NewParamHolder(lb.CapKeyParamStore) 136 lb.globalManager = globalmn.NewGlobalManager( 137 lb.CapKeyGlobalStore, lb.paramHolder, MakeEventManagerCodec(), 138 lb.hourlyBCEvent, lb.dailyBCEvent, lb.monthlyBCEvent, lb.yearlyBCEvent) 139 lb.accountManager = accmn.NewAccountManager(lb.CapKeyAccountStore, lb.paramHolder) 140 lb.reputationManager = rep.NewReputationManager(lb.CapKeyReputationV2Store, lb.paramHolder) 141 // lb.proposalManager = proposal.NewProposalManager(lb.CapKeyProposalStore, lb.paramHolder) 142 143 // layer-2: middlewares 144 //// vote <--> validator 145 voteManager := votemn.NewVoteManager(lb.CapKeyVoteStore, lb.paramHolder, lb.accountManager, lb.globalManager) 146 lb.valManager = valmn.NewValidatorManager(lb.CapKeyValStore, lb.paramHolder, &voteManager, lb.globalManager, lb.accountManager) 147 lb.voteManager = *voteManager.SetHooks(votemn.NewMultiStakingHooks(lb.valManager.Hooks())) 148 //// price -> vote, validator 149 lb.priceManager = pricemn.NewWeightedMedianPriceManager(lb.CapKeyPriceStore, lb.valManager, lb.paramHolder) 150 151 // layer-3: applications 152 lb.developerManager = devmn.NewDeveloperManager( 153 lb.CapKeyDeveloperStore, lb.paramHolder, 154 &voteManager, lb.accountManager, lb.priceManager) 155 //// post -> developer 156 lb.postManager = postmn.NewPostManager( 157 lb.CapKeyPostStore, lb.accountManager, 158 lb.globalManager, lb.developerManager, lb.reputationManager, lb.priceManager, 159 lb.voteManager) 160 // bandwidth -> developer 161 lb.bandwidthManager = bandwidthmn.NewBandwidthManager( 162 lb.CapKeyBandwidthStore, lb.paramHolder, 163 lb.globalManager, &voteManager, lb.developerManager, lb.accountManager) 164 // bandwidth 165 lb.auth = auth.NewAnteHandler(lb.accountManager, lb.bandwidthManager) 166 167 lb.Router(). 168 AddRoute(acctypes.RouterKey, acc.NewHandler(lb.accountManager)). 169 AddRoute(posttypes.RouterKey, post.NewHandler(lb.postManager)). 170 AddRoute(votetypes.RouterKey, vote.NewHandler(lb.voteManager)). 171 AddRoute(devtypes.RouterKey, dev.NewHandler(lb.developerManager)). 172 AddRoute(pricetypes.RouterKey, price.NewHandler(lb.priceManager)). 173 // AddRoute(proposal.RouterKey, proposal.NewHandler( 174 // lb.accountManager, lb.proposalManager, lb.postManager, &lb.globalManager, lb.voteManager)). 175 AddRoute(val.RouterKey, val.NewHandler(lb.valManager)) 176 177 lb.QueryRouter(). 178 AddRoute(acctypes.QuerierRoute, acc.NewQuerier(lb.accountManager)). 179 AddRoute(posttypes.QuerierRoute, post.NewQuerier(lb.postManager)). 180 AddRoute(votetypes.QuerierRoute, vote.NewQuerier(lb.voteManager)). 181 AddRoute(devtypes.QuerierRoute, dev.NewQuerier(lb.developerManager)). 182 // AddRoute(proposal.QuerierRoute, proposal.NewQuerier(lb.proposalManager)). 183 AddRoute(val.QuerierRoute, val.NewQuerier(lb.valManager)). 184 AddRoute(globaltypes.QuerierRoute, global.NewQuerier(lb.globalManager)). 185 AddRoute(param.QuerierRoute, param.NewQuerier(lb.paramHolder)). 186 AddRoute(bandwidthtypes.QuerierRoute, bandwidth.NewQuerier(lb.bandwidthManager)). 187 AddRoute(rep.QuerierRoute, rep.NewQuerier(lb.reputationManager)). 188 AddRoute(pricetypes.QuerierRoute, price.NewQuerier(lb.priceManager)) 189 190 lb.SetInitChainer(lb.initChainer) 191 lb.SetBeginBlocker(lb.beginBlocker) 192 lb.SetEndBlocker(lb.endBlocker) 193 lb.SetAnteHandler(lb.auth) 194 // TODO(Cosmos): mounting multiple stores is broken 195 // https://github.com/cosmos/cosmos-sdk/issues/532 196 197 lb.MountStores( 198 lb.CapKeyMainStore, lb.CapKeyAccountStore, lb.CapKeyPostStore, lb.CapKeyValStore, 199 lb.CapKeyVoteStore, lb.CapKeyDeveloperStore, lb.CapKeyGlobalStore, 200 lb.CapKeyParamStore, lb.CapKeyProposalStore, lb.CapKeyReputationV2Store, lb.CapKeyBandwidthStore, lb.CapKeyPriceStore) 201 if err := lb.LoadLatestVersion(lb.CapKeyMainStore); err != nil { 202 panic(err) 203 } 204 205 lb.Seal() 206 207 return lb 208 } 209 210 // MackCodec - codec for application, used by command line tool and authenticate handler 211 func MakeCodec() *wire.Codec { 212 cdc := wire.New() 213 cdc.RegisterConcrete(cauth.StdTx{}, "auth/StdTx", nil) 214 wire.RegisterCrypto(cdc) 215 sdk.RegisterCodec(cdc) 216 types.RegisterWire(cdc) // types.Msg and types.AddrMsg 217 218 acctypes.RegisterWire(cdc) 219 posttypes.RegisterCodec(cdc) 220 devtypes.RegisterWire(cdc) 221 votetypes.RegisterWire(cdc) 222 valtypes.RegisterCodec(cdc) 223 pricetypes.RegisterCodec(cdc) 224 // proposal.RegisterWire(cdc) 225 registerEvent(cdc) 226 227 cdc.Seal() 228 229 return cdc 230 } 231 232 // MakeEventManagerCodec - return a codec that can marshal events. 233 func MakeEventManagerCodec() *wire.Codec { 234 cdc := wire.New() 235 // events 236 registerEvent(cdc) 237 238 // TODO(yumin): we can remove this part by changing how 239 // change param proposal and its event are done. 240 // param change events 241 cdc.RegisterInterface((*param.Parameter)(nil), nil) 242 cdc.RegisterConcrete(param.GlobalAllocationParam{}, "param/allocation", nil) 243 cdc.RegisterConcrete(param.VoteParam{}, "param/vote", nil) 244 cdc.RegisterConcrete(param.ProposalParam{}, "param/proposal", nil) 245 cdc.RegisterConcrete(param.DeveloperParam{}, "param/developer", nil) 246 cdc.RegisterConcrete(param.ValidatorParam{}, "param/validator", nil) 247 cdc.RegisterConcrete(param.CoinDayParam{}, "param/coinDay", nil) 248 cdc.RegisterConcrete(param.BandwidthParam{}, "param/bandwidth", nil) 249 cdc.RegisterConcrete(param.AccountParam{}, "param/account", nil) 250 cdc.RegisterConcrete(param.PostParam{}, "param/post", nil) 251 wire.RegisterCrypto(cdc) 252 cdc.Seal() 253 254 return cdc 255 } 256 257 func registerEvent(cdc *wire.Codec) { 258 cdc.RegisterInterface((*types.Event)(nil), nil) 259 cdc.RegisterConcrete(posttypes.RewardEvent{}, "lino/eventRewardV2", nil) 260 cdc.RegisterConcrete(accmn.ReturnCoinEvent{}, "lino/eventReturn", nil) 261 cdc.RegisterConcrete(param.ChangeParamEvent{}, "lino/eventCpe", nil) 262 // cdc.RegisterConcrete(proposal.DecideProposalEvent{}, "lino/eventDpe", nil) 263 cdc.RegisterConcrete(votetypes.UnassignDutyEvent{}, "lino/eventUde", nil) 264 } 265 266 // custom logic for lino blockchain initialization 267 func (lb *LinoBlockchain) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { 268 stateJSON := req.AppStateBytes 269 genesisState := new(GenesisState) 270 lb.cdc.MustUnmarshalJSON(stateJSON, genesisState) 271 272 // init parameter holder 273 if genesisState.GenesisParam.InitFromConfig { 274 if err := lb.paramHolder.InitParamFromConfig( 275 ctx, 276 genesisState.GenesisParam.GlobalAllocationParam, 277 genesisState.GenesisParam.PostParam, 278 genesisState.GenesisParam.DeveloperParam, 279 genesisState.GenesisParam.ValidatorParam, 280 genesisState.GenesisParam.VoteParam, 281 genesisState.GenesisParam.ProposalParam, 282 genesisState.GenesisParam.CoinDayParam, 283 genesisState.GenesisParam.BandwidthParam, 284 genesisState.GenesisParam.AccountParam, 285 genesisState.GenesisParam.ReputationParam, 286 genesisState.GenesisParam.PriceParam, 287 ); err != nil { 288 panic(err) 289 } 290 } else { 291 if err := lb.paramHolder.InitParam(ctx); err != nil { 292 panic(err) 293 } 294 } 295 296 // initialize account module 297 if err := genesisState.GenesisPools.IsValid(); err != nil { 298 panic(err) 299 } 300 accPools := make([]accmodel.Pool, 0) 301 for _, pool := range genesisState.GenesisPools.Pools { 302 accPools = append(accPools, accmodel.Pool{ 303 Name: pool.Name, 304 Balance: pool.Amount, 305 }) 306 } 307 lb.accountManager.InitGenesis(ctx, genesisState.GenesisPools.Total, accPools) 308 309 // initialize global module 310 lb.globalManager.InitGenesis(ctx) 311 312 // initialize vote module 313 lb.voteManager.InitGenesis(ctx) 314 315 // initialize developer, write down reserve pool amount. 316 if err := lb.developerManager.InitGenesis( 317 ctx, genesisState.GenesisPools.ReservePool()); err != nil { 318 panic(err) 319 } 320 321 // initialize price manger. 322 if err := lb.priceManager.InitGenesis(ctx, genesisState.InitCoinPrice); err != nil { 323 panic(err) 324 } 325 326 // init proposal skipped for now. 327 // if err := lb.proposalManager.InitGenesis(ctx); err != nil { 328 // panic(err) 329 // } 330 331 // init bandwidth module 332 if err := lb.bandwidthManager.InitGenesis(ctx); err != nil { 333 panic(err) 334 } 335 336 // init validator genesis. 337 lb.valManager.InitGenesis(ctx) 338 339 // import from prev state, do not read from genesis. 340 if genesisState.LoadPrevStates { 341 lb.ImportFromFiles(ctx) 342 } else { 343 // init genesis accounts 344 for _, gacc := range genesisState.Accounts { 345 if err := lb.toAppAccount(ctx, gacc); err != nil { 346 panic(err) 347 } 348 } 349 350 // init genesis developers 351 for _, developer := range genesisState.Developers { 352 if err := lb.toAppDeveloper(ctx, developer); err != nil { 353 panic(err) 354 } 355 } 356 357 } 358 359 // generate respoinse init message. 360 validators, err := lb.valManager.GetInitValidators(ctx) 361 if err != nil { 362 panic(err) 363 } 364 365 return abci.ResponseInitChain{ 366 ConsensusParams: req.ConsensusParams, 367 Validators: validators, 368 } 369 } 370 371 // convert GenesisAccount to AppAccount 372 func (lb *LinoBlockchain) toAppAccount(ctx sdk.Context, ga GenesisAccount) sdk.Error { 373 if lb.accountManager.DoesAccountExist(ctx, types.AccountKey(ga.Name)) { 374 panic(fmt.Errorf("genesis account already exist")) 375 } 376 if err := lb.accountManager.GenesisAccount( 377 ctx, types.AccountKey(ga.Name), ga.SignKey, ga.TxKey); err != nil { 378 panic(err) 379 } 380 if err := lb.accountManager.MoveFromPool(ctx, 381 types.AccountVestingPool, 382 types.NewAccOrAddrFromAcc(types.AccountKey(ga.Name)), ga.Coin); err != nil { 383 panic(err) 384 } 385 386 valParam := lb.paramHolder.GetValidatorParam(ctx) 387 if ga.IsValidator { 388 if err := lb.voteManager.StakeIn( 389 ctx, types.AccountKey(ga.Name), valParam.ValidatorMinDeposit); err != nil { 390 panic(err) 391 } 392 if err := lb.valManager.RegisterValidator( 393 ctx, types.AccountKey(ga.Name), ga.ValPubKey, ""); err != nil { 394 panic(err) 395 } 396 } 397 return nil 398 } 399 400 // convert GenesisDeveloper to AppDeveloper 401 func (lb *LinoBlockchain) toAppDeveloper( 402 ctx sdk.Context, developer GenesisAppDeveloper) sdk.Error { 403 // skipped. 404 // if !lb.accountManager.DoesAccountExist(ctx, types.AccountKey(developer.Name)) { 405 // return ErrGenesisFailed("genesis developer account doesn't exist") 406 // } 407 408 // if err := lb.accountManager.MinusCoinFromUsername( 409 // ctx, types.AccountKey(developer.Name), developer.Deposit); err != nil { 410 // return err 411 // } 412 413 // if err := lb.developerManager.RegisterDeveloper( 414 // ctx, types.AccountKey(developer.Name), developer.Website, 415 // developer.Description, developer.AppMetaData); err != nil { 416 // return err 417 // } 418 return nil 419 } 420 421 // init process for a block, execute time events and fire incompetent validators 422 func (lb *LinoBlockchain) beginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { 423 // blockchain scheduled events 424 lb.globalManager.OnBeginBlock(ctx) // MUST BE THE FIRST ONE 425 bandwidth.BeginBlocker(ctx, req, lb.bandwidthManager) 426 val.BeginBlocker(ctx, req, lb.valManager) 427 // module events 428 lb.globalManager.ExecuteEvents(ctx, lb.executeEvent) 429 return abci.ResponseBeginBlock{} 430 } 431 432 // execute event based on their type 433 func (lb *LinoBlockchain) executeEvent(ctx sdk.Context, event types.Event) sdk.Error { 434 switch e := event.(type) { 435 case posttypes.RewardEvent: 436 if err := lb.postManager.ExecRewardEvent(ctx, e); err != nil { 437 return err 438 } 439 case accmn.ReturnCoinEvent: 440 if err := e.Execute(ctx, lb.accountManager.(accmn.AccountManager)); err != nil { 441 return err 442 } 443 // case proposal.DecideProposalEvent: 444 // if err := e.Execute( 445 // ctx, lb.voteManager, lb.valManager, lb.accountManager, lb.proposalManager, 446 // lb.postManager, &lb.globalManager); err != nil { 447 // return err 448 // } 449 case param.ChangeParamEvent: 450 if err := e.Execute(ctx, lb.paramHolder); err != nil { 451 return err 452 } 453 case votetypes.UnassignDutyEvent: 454 if err := lb.voteManager.ExecUnassignDutyEvent(ctx, e); err != nil { 455 return err 456 } 457 default: 458 return types.ErrUnknownEvent() 459 } 460 return nil 461 } 462 463 // udpate validator set and renew reputation round 464 func (lb *LinoBlockchain) endBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { 465 acc.EndBlocker(ctx, req, lb.accountManager) 466 rep.EndBlocker(ctx, req, lb.reputationManager) 467 bandwidth.EndBlocker(ctx, req, lb.bandwidthManager) 468 // last, update last block time. 469 lb.globalManager.OnEndBlock(ctx) 470 471 // update validator set. 472 validatorUpdates, err := lb.valManager.GetValidatorUpdates(ctx) 473 if err != nil { 474 panic(err) 475 } 476 477 return abci.ResponseEndBlock{ 478 ValidatorUpdates: validatorUpdates, 479 } 480 } 481 482 // execute hourly event, distribute inflation to validators and 483 // add hourly inflation to content creator reward pool 484 func (lb *LinoBlockchain) hourlyBCEvent(ctx sdk.Context) (errs []types.BCEventErr) { 485 if err := lb.accountManager.Mint(ctx); err != nil { 486 errs = append(errs, types.NewBCEventErr(ctx, err, "account/mint")) 487 } 488 if err := lb.valManager.DistributeInflationToValidator(ctx); err != nil { 489 errs = append(errs, types.NewBCEventErr(ctx, err, "validator/inflation")) 490 } 491 if err := lb.bandwidthManager.ReCalculateAppBandwidthInfo(ctx); err != nil { 492 errs = append(errs, types.NewBCEventErr(ctx, err, "bandwidth/recalculate")) 493 } 494 if err := lb.priceManager.UpdatePrice(ctx); err != nil { 495 errs = append(errs, types.NewBCEventErr(ctx, err, "price/update")) 496 } 497 return 498 } 499 500 // execute daily event, record consumption friction and lino power 501 func (lb *LinoBlockchain) dailyBCEvent(ctx sdk.Context) (errs []types.BCEventErr) { 502 if err := lb.voteManager.DailyAdvanceLinoStakeStats(ctx); err != nil { 503 errs = append(errs, types.NewBCEventErr(ctx, err, "vote/advance-stake-stats")) 504 } 505 if err := lb.bandwidthManager.DecayMaxMPS(ctx); err != nil { 506 errs = append(errs, types.NewBCEventErr(ctx, err, "bandwidth/decay-max-mps")) 507 } 508 return 509 } 510 511 // execute monthly event, distribute inflation to applications. 512 func (lb *LinoBlockchain) monthlyBCEvent(ctx sdk.Context) (errs []types.BCEventErr) { 513 // distributeInflationToDeveloper 514 if err := lb.developerManager.MonthlyDistributeDevInflation(ctx); err != nil { 515 errs = append(errs, types.NewBCEventErr(ctx, err, "dev/inflation")) 516 } 517 return 518 } 519 520 func (lb *LinoBlockchain) yearlyBCEvent(ctx sdk.Context) (errs []types.BCEventErr) { 521 return nil 522 } 523 524 type importExportModule struct { 525 module interface { 526 ExportToFile(ctx sdk.Context, cdc *wire.Codec, filepath string) error 527 ImportFromFile(ctx sdk.Context, cdc *wire.Codec, filepath string) error 528 } 529 filename string 530 } 531 532 func (lb *LinoBlockchain) getImportExportModules() []importExportModule { 533 return []importExportModule{ 534 { 535 module: lb.accountManager, 536 filename: accountStateFile, 537 }, 538 { 539 module: lb.postManager, 540 filename: postStateFile, 541 }, 542 { 543 module: lb.developerManager, 544 filename: developerStateFile, 545 }, 546 { 547 module: lb.globalManager, 548 filename: globalStateFile, 549 }, 550 { 551 module: lb.voteManager, 552 filename: voterStateFile, 553 }, 554 { 555 module: lb.valManager, 556 filename: validatorStateFile, 557 }, 558 { 559 module: lb.reputationManager, 560 filename: reputationStateFile, 561 }, 562 } 563 } 564 565 // Custom logic for state export 566 func (lb *LinoBlockchain) ExportAppStateAndValidators() (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) { 567 ctx := lb.NewContext(true, abci.Header{}) 568 569 exportPath := lb.GetHomeDir() + "/" + currStateFolder 570 err = os.MkdirAll(exportPath, os.ModePerm) 571 if err != nil { 572 panic("failed to create export dir due to: " + err.Error()) 573 } 574 575 var wg sync.WaitGroup 576 modules := lb.getImportExportModules() 577 for i := range modules { 578 wg.Add(1) 579 go func(i int) { 580 defer wg.Done() 581 err := modules[i].module.ExportToFile(ctx, lb.cdc, exportPath+modules[i].filename) 582 if err != nil { 583 panic(err) 584 } 585 fmt.Printf("Export %s Done\n", modules[i].filename) 586 }(i) 587 } 588 589 wg.Wait() 590 591 genesisState := GenesisState{} 592 593 appState, err = wire.MarshalJSONIndent(lb.cdc, genesisState) 594 if err != nil { 595 return nil, nil, err 596 } 597 return appState, validators, nil 598 } 599 600 // ImportFromFiles Custom logic for state export 601 func (lb *LinoBlockchain) ImportFromFiles(ctx sdk.Context) { 602 prevStateDir := lb.GetHomeDir() + "/" + prevStateFolder 603 604 modules := lb.getImportExportModules() 605 for _, toImport := range modules { 606 ctx.Logger().Info(fmt.Sprintf("loading: %s state", toImport.filename)) 607 err := toImport.module.ImportFromFile(ctx, lb.cdc, prevStateDir+toImport.filename) 608 if err != nil { 609 panic(err) 610 } 611 ctx.Logger().Info(fmt.Sprintf("imported: %s state", toImport.filename)) 612 } 613 } 614 615 func (lb *LinoBlockchain) GetHomeDir() string { 616 return viper.GetString(tmcli.HomeFlag) 617 }