package app
import (
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
"cosmossdk.io/math"
"fmt"
"github.com/cometbft/cometbft/crypto"
"github.com/cometbft/cometbft/libs/bytes"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/server"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/types/bech32"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
v7 "github.com/cybercongress/go-cyber/v7/app/upgrades/v7"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
v5 "github.com/cybercongress/go-cyber/v7/app/upgrades/v5"
v6 "github.com/cybercongress/go-cyber/v7/app/upgrades/v6"
"github.com/cybercongress/go-cyber/v7/client/docs"
bandwidthkeeper "github.com/cybercongress/go-cyber/v7/x/bandwidth/keeper"
cyberbankkeeper "github.com/cybercongress/go-cyber/v7/x/cyberbank/keeper"
graphkeeper "github.com/cybercongress/go-cyber/v7/x/graph/keeper"
rankkeeper "github.com/cybercongress/go-cyber/v7/x/rank/keeper"
"io"
"os"
"time"
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/x/auth/posthandler"
v2 "github.com/cybercongress/go-cyber/v7/app/upgrades/v2"
v3 "github.com/cybercongress/go-cyber/v7/app/upgrades/v3"
v4 "github.com/cybercongress/go-cyber/v7/app/upgrades/v4"
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client"
"github.com/cybercongress/go-cyber/v7/app/keepers"
"github.com/cybercongress/go-cyber/v7/app/upgrades"
dbm "github.com/cometbft/cometbft-db"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec/types"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/spf13/cast"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
tmos "github.com/cometbft/cometbft/libs/os"
"github.com/cosmos/cosmos-sdk/baseapp"
nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/crisis"
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/CosmWasm/wasmd/x/wasm"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
tmjson "github.com/cometbft/cometbft/libs/json"
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
"github.com/cybercongress/go-cyber/v7/utils"
runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services"
)
const (
appName = "BostromHub"
Name = "bostrom"
)
var (
NodeDir = ".cyber"
Bech32Prefix = "bostrom"
Upgrades = []upgrades.Upgrade{v2.Upgrade, v3.Upgrade, v4.Upgrade, v6.Upgrade, v7.Upgrade}
Forks = []upgrades.Fork{v5.Fork}
)
var (
DefaultNodeHome = os.ExpandEnv("$HOME/") + NodeDir
)
func getGovProposalHandlers() []govclient.ProposalHandler {
return []govclient.ProposalHandler{
paramsclient.ProposalHandler,
upgradeclient.LegacyProposalHandler,
upgradeclient.LegacyCancelProposalHandler,
ibcclientclient.UpdateClientProposalHandler,
ibcclientclient.UpgradeProposalHandler,
}
}
var (
_ runtime.AppI = (*App)(nil)
_ servertypes.Application = (*App)(nil)
)
type App struct {
*baseapp.BaseApp
keepers.AppKeepers
aminoCodec *codec.LegacyAmino
appCodec codec.Codec
txConfig client.TxConfig
interfaceRegistry types.InterfaceRegistry
invCheckPeriod uint
ModuleManager *module.Manager
sm *module.SimulationManager
configurator module.Configurator
}
func NewBostromApp(
logger log.Logger,
db dbm.DB,
traceStore io.Writer,
loadLatest bool,
appOpts servertypes.AppOptions,
wasmOpts []wasmkeeper.Option,
baseAppOptions ...func(*baseapp.BaseApp),
) *App {
wasmtypes.MaxWasmSize = 2 * 1024 * 1024 encodingConfig := MakeEncodingConfig()
appCodec, legacyAmino := encodingConfig.Codec, encodingConfig.Amino
interfaceRegistry := encodingConfig.InterfaceRegistry
txConfig := encodingConfig.TxConfig
skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants))
invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod))
bApp := baseapp.NewBaseApp(
appName,
logger,
db,
txConfig.TxDecoder(),
baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetVersion(version.Version)
bApp.SetInterfaceRegistry(interfaceRegistry)
bApp.SetTxEncoder(txConfig.TxEncoder())
app := &App{
BaseApp: bApp,
aminoCodec: legacyAmino,
appCodec: appCodec,
txConfig: txConfig,
interfaceRegistry: interfaceRegistry,
invCheckPeriod: invCheckPeriod,
}
app.AppKeepers = keepers.NewAppKeepers(
appCodec,
bApp,
legacyAmino,
keepers.GetMaccPerms(),
invCheckPeriod,
logger,
appOpts,
wasmOpts,
)
app.ModuleManager = module.NewManager(appModules(app, encodingConfig, skipGenesisInvariants)...)
app.ModuleManager.SetOrderBeginBlockers(orderBeginBlockers()...)
app.ModuleManager.SetOrderEndBlockers(orderEndBlockers()...)
app.ModuleManager.SetOrderInitGenesis(orderInitBlockers()...)
app.ModuleManager.RegisterInvariants(app.CrisisKeeper)
app.configurator = module.NewConfigurator(appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
delete(app.ModuleManager.Modules, banktypes.ModuleName)
app.ModuleManager.RegisterServices(app.configurator)
autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.ModuleManager.Modules))
app.ModuleManager.Modules[banktypes.ModuleName] = bank.NewAppModule(appCodec, app.CyberbankKeeper.Proxy, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName))
banktypes.RegisterMsgServer(app.configurator.MsgServer(), bankkeeper.NewMsgServerImpl(app.CyberbankKeeper.Proxy))
banktypes.RegisterQueryServer(app.configurator.QueryServer(), app.CyberbankKeeper.Proxy)
reflectionSvc, err := runtimeservices.NewReflectionService()
if err != nil {
panic(err)
}
reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc)
app.MountKVStores(app.GetKVStoreKey())
app.MountTransientStores(app.GetTransientStoreKey())
app.MountMemoryStores(app.GetMemoryStoreKey())
wasmConfig, err := wasm.ReadWasmConfig(appOpts)
if err != nil {
panic("error while reading wasm config: " + err.Error())
}
proofExemptContracts := cast.ToStringSlice(appOpts.Get("proof-exempt.contracts"))
anteHandler, err := NewAnteHandler(
HandlerOptions{
HandlerOptions: ante.HandlerOptions{
AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper,
FeegrantKeeper: app.FeeGrantKeeper,
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
},
IBCKeeper: app.IBCKeeper,
TXCounterStoreKey: app.GetKey(wasmtypes.StoreKey),
WasmConfig: &wasmConfig,
WasmKeeper: app.WasmKeeper,
ProofExemptContracts: proofExemptContracts,
},
)
if err != nil {
panic(fmt.Errorf("failed to create AnteHandler: %s", err))
}
app.SetAnteHandler(anteHandler)
app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
if manager := app.SnapshotManager(); manager != nil {
err = manager.RegisterExtensions(
wasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), app.WasmKeeper),
cyberbankkeeper.NewCyberbankSnapshotter(app.CommitMultiStore(), app.CyberbankKeeper),
graphkeeper.NewGraphSnapshotter(app.CommitMultiStore(), app.AppKeepers.GraphKeeper, app.IndexKeeper),
bandwidthkeeper.NewBandwidthSnapshotter(app.CommitMultiStore(), app.BandwidthMeter),
rankkeeper.NewRankSnapshotter(app.CommitMultiStore(), app.RankKeeper),
)
if err != nil {
panic("failed to register snapshot extension: " + err.Error())
}
}
app.setupUpgradeHandlers(app.configurator)
app.setupUpgradeStoreLoaders()
app.setPostHandler()
if loadLatest {
if err := app.LoadLatestVersion(); err != nil {
tmos.Exit(fmt.Sprintf("failed to load latest version: %s", err))
}
ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{})
app.loadContexts(db, ctx)
if err := app.WasmKeeper.InitializePinnedCodes(ctx); err != nil {
tmos.Exit(fmt.Sprintf("failed initialize pinned codes %s", err))
}
}
app.sm = module.NewSimulationManager(simulationModules(app, encodingConfig, skipGenesisInvariants)...)
app.sm.RegisterStoreDecoders()
return app
}
func (app *App) setPostHandler() {
postHandler, err := posthandler.NewPostHandler(
posthandler.HandlerOptions{},
)
if err != nil {
panic(err)
}
app.SetPostHandler(postHandler)
}
func (app *App) Name() string {
return app.BaseApp.Name()
}
func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
return app.ModuleManager.BeginBlock(ctx, req)
}
func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
return app.ModuleManager.EndBlock(ctx, req)
}
func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
var genesisState GenesisState
if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
}
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
resp := app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
for _, account := range app.AccountKeeper.GetAllAccounts(ctx) {
app.CyberbankKeeper.InitializeStakeAmpere(
account.GetAccountNumber(),
uint64(app.CyberbankKeeper.Proxy.GetAccountStakeAmperPlusRouted(ctx, account.GetAddress())),
)
}
return resp
}
func (app *App) LoadHeight(height int64) error {
return app.LoadVersion(height)
}
func (app *App) ModuleAccountAddrs() map[string]bool {
modAccAddrs := make(map[string]bool)
for acc := range keepers.GetMaccPerms() {
modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true
}
return modAccAddrs
}
func (app *App) LegacyAmino() *codec.LegacyAmino {
return app.aminoCodec
}
func (app *App) AppCodec() codec.Codec {
return app.appCodec
}
func (app *App) InterfaceRegistry() types.InterfaceRegistry {
return app.interfaceRegistry
}
func (app *App) GetSubspace(moduleName string) paramstypes.Subspace {
subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)
return subspace
}
func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
clientCtx := apiSvr.ClientCtx
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
docs.RegisterOpenAPIService(Name, apiSvr.Router)
}
func (app *App) RegisterTxService(clientCtx client.Context) {
authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry)
}
func (app *App) RegisterTendermintService(clientCtx client.Context) {
tmservice.RegisterTendermintService(
clientCtx,
app.BaseApp.GRPCQueryRouter(),
app.interfaceRegistry,
app.Query,
)
}
func (app *App) RegisterNodeService(clientCtx client.Context) {
nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter())
}
func (app *App) setupUpgradeStoreLoaders() {
upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic("failed to read upgrade info from disk" + err.Error())
}
if app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
return
}
for _, upgrade := range Upgrades {
storeUpgrades := upgrade.StoreUpgrades
if upgradeInfo.Name == upgrade.UpgradeName {
app.SetStoreLoader(
upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades),
)
}
}
}
func (app *App) setupUpgradeHandlers(cfg module.Configurator) {
for _, upgrade := range Upgrades {
app.UpgradeKeeper.SetUpgradeHandler(
upgrade.UpgradeName,
upgrade.CreateUpgradeHandler(
app.ModuleManager,
cfg,
&app.AppKeepers,
),
)
}
}
func (app *App) SimulationManager() *module.SimulationManager {
return app.sm
}
func MakeCodecs() (codec.Codec, *codec.LegacyAmino) {
config := MakeEncodingConfig()
return config.Codec, config.Amino
}
func (app *App) loadContexts(db dbm.DB, ctx sdk.Context) {
freshCtx := ctx.WithBlockHeight(int64(app.RankKeeper.GetLatestBlockNumber(ctx)))
start := time.Now()
app.BaseApp.Logger().Info("Loading the brain state")
if app.LastBlockHeight() >= 1 {
calculationPeriod := app.RankKeeper.GetParams(freshCtx).CalculationPeriod
if calculationPeriod == 0 {
calculationPeriod = int64(5)
}
rankRoundBlockNumber := (freshCtx.BlockHeight() / calculationPeriod) * calculationPeriod
if rankRoundBlockNumber == 0 && freshCtx.BlockHeight() >= 1 {
rankRoundBlockNumber = 1
}
rankCtx, err := utils.NewContextWithMSVersion(db, rankRoundBlockNumber, app.GetKVStoreKey())
if err != nil {
tmos.Exit(err.Error())
}
app.CyberbankKeeper.LoadState(rankCtx, freshCtx)
app.IndexKeeper.LoadState(rankCtx, freshCtx)
app.BandwidthMeter.LoadState(freshCtx)
app.GraphKeeper.LoadNeudeg(rankCtx, freshCtx)
app.RankKeeper.LoadState(freshCtx)
app.RankKeeper.StartRankCalculation(freshCtx)
} else {
app.CyberbankKeeper.LoadState(freshCtx, freshCtx)
app.IndexKeeper.LoadState(freshCtx, freshCtx)
app.BandwidthMeter.InitState()
app.GraphKeeper.LoadNeudeg(freshCtx, freshCtx)
app.RankKeeper.LoadState(freshCtx)
}
app.BaseApp.Logger().Info(
"Cyber Consensus Supercomputer is started!",
"duration", time.Since(start).String(),
)
}
func InitAppForTestnet(app *App, newValAddr bytes.HexBytes, newValPubKey crypto.PubKey, newOperatorAddress, upgradeToTrigger string) *App {
ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{})
pubkey := &ed25519.PubKey{Key: newValPubKey.Bytes()}
pubkeyAny, err := types.NewAnyWithValue(pubkey)
if err != nil {
tmos.Exit(err.Error())
}
_, bz, err := bech32.DecodeAndConvert(newOperatorAddress)
if err != nil {
tmos.Exit(err.Error())
}
bech32Addr, err := bech32.ConvertAndEncode("bostromvaloper", bz)
if err != nil {
tmos.Exit(err.Error())
}
newVal := stakingtypes.Validator{
OperatorAddress: bech32Addr,
ConsensusPubkey: pubkeyAny,
Jailed: false,
Status: stakingtypes.Bonded,
Tokens: math.NewInt(900000000000000),
DelegatorShares: sdk.MustNewDecFromStr("10000000"),
Description: stakingtypes.Description{
Moniker: "Testnet Validator",
},
Commission: stakingtypes.Commission{
CommissionRates: stakingtypes.CommissionRates{
Rate: sdk.MustNewDecFromStr("0.05"),
MaxRate: sdk.MustNewDecFromStr("0.1"),
MaxChangeRate: sdk.MustNewDecFromStr("0.05"),
},
},
MinSelfDelegation: math.OneInt(),
}
stakingKey := app.GetKey(stakingtypes.ModuleName)
stakingStore := ctx.KVStore(stakingKey)
iterator := app.StakingKeeper.ValidatorsPowerStoreIterator(ctx)
for ; iterator.Valid(); iterator.Next() {
stakingStore.Delete(iterator.Key())
}
iterator.Close()
iterator = app.StakingKeeper.LastValidatorsIterator(ctx)
for ; iterator.Valid(); iterator.Next() {
stakingStore.Delete(iterator.Key())
}
iterator.Close()
iterator = storetypes.KVStorePrefixIterator(stakingStore, stakingtypes.ValidatorsKey)
for ; iterator.Valid(); iterator.Next() {
stakingStore.Delete(iterator.Key())
}
iterator.Close()
iterator = storetypes.KVStorePrefixIterator(stakingStore, stakingtypes.ValidatorQueueKey)
for ; iterator.Valid(); iterator.Next() {
stakingStore.Delete(iterator.Key())
}
iterator.Close()
app.StakingKeeper.SetValidator(ctx, newVal)
err = app.StakingKeeper.SetValidatorByConsAddr(ctx, newVal)
if err != nil {
tmos.Exit(err.Error())
}
app.StakingKeeper.SetValidatorByPowerIndex(ctx, newVal)
valAddr, err := sdk.ValAddressFromBech32(newVal.GetOperator().String())
if err != nil {
tmos.Exit(err.Error())
}
app.StakingKeeper.SetLastValidatorPower(ctx, valAddr, 0)
if err := app.StakingKeeper.Hooks().AfterValidatorCreated(ctx, valAddr); err != nil {
panic(err)
}
valAddr, err = sdk.ValAddressFromBech32(newVal.GetOperator().String())
if err != nil {
tmos.Exit(err.Error())
}
app.DistrKeeper.SetValidatorHistoricalRewards(ctx, valAddr, 0, distrtypes.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1))
app.DistrKeeper.SetValidatorCurrentRewards(ctx, valAddr, distrtypes.NewValidatorCurrentRewards(sdk.DecCoins{}, 1))
app.DistrKeeper.SetValidatorAccumulatedCommission(ctx, valAddr, distrtypes.InitialValidatorAccumulatedCommission())
app.DistrKeeper.SetValidatorOutstandingRewards(ctx, valAddr, distrtypes.ValidatorOutstandingRewards{Rewards: sdk.DecCoins{}})
newConsAddr := sdk.ConsAddress(newValAddr.Bytes())
newValidatorSigningInfo := slashingtypes.ValidatorSigningInfo{
Address: newConsAddr.String(),
StartHeight: app.LastBlockHeight() - 1,
Tombstoned: false,
}
app.SlashingKeeper.SetValidatorSigningInfo(ctx, newConsAddr, newValidatorSigningInfo)
if upgradeToTrigger != "" {
upgradePlan := upgradetypes.Plan{
Name: upgradeToTrigger,
Height: app.LastBlockHeight(),
}
err = app.UpgradeKeeper.ScheduleUpgrade(ctx, upgradePlan)
if err != nil {
panic(err)
}
}
return app
}