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  }