From b8294fdd1cb58705e61e7bd9225120aa4694dc82 Mon Sep 17 00:00:00 2001 From: billy rennekamp Date: Thu, 7 Jul 2022 12:43:44 +0200 Subject: [PATCH 1/4] copy of consumer app --- .../ante/msg_filter_ante.go | 58 ++ .../ante/msg_filter_ante_test.go | 85 ++ app/consumer-democracy/ante_handler.go | 58 ++ app/consumer-democracy/app.go | 746 ++++++++++++++++++ app/consumer-democracy/export.go | 198 +++++ app/consumer-democracy/genesis.go | 21 + 6 files changed, 1166 insertions(+) create mode 100644 app/consumer-democracy/ante/msg_filter_ante.go create mode 100644 app/consumer-democracy/ante/msg_filter_ante_test.go create mode 100644 app/consumer-democracy/ante_handler.go create mode 100644 app/consumer-democracy/app.go create mode 100644 app/consumer-democracy/export.go create mode 100644 app/consumer-democracy/genesis.go diff --git a/app/consumer-democracy/ante/msg_filter_ante.go b/app/consumer-democracy/ante/msg_filter_ante.go new file mode 100644 index 0000000000..5788f12a5e --- /dev/null +++ b/app/consumer-democracy/ante/msg_filter_ante.go @@ -0,0 +1,58 @@ +package ante + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var validMsgsCCVDisabled = map[string]struct{}{} + +type ( + // ConsumerKeeper defines the interface required by a consumer module keeper. + ConsumerKeeper interface { + GetProviderChannel(ctx sdk.Context) (string, bool) + } + + // MsgFilterDecorator defines an AnteHandler decorator that enables message + // filtering based on certain criteria. + MsgFilterDecorator struct { + ConsumerKeeper ConsumerKeeper + } +) + +func NewMsgFilterDecorator(k ConsumerKeeper) MsgFilterDecorator { + return MsgFilterDecorator{ + ConsumerKeeper: k, + } +} + +func (mfd MsgFilterDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + currHeight := ctx.BlockHeight() + + // If the CCV channel has not yet been established, then we must only allow certain + // message types. + if _, ok := mfd.ConsumerKeeper.GetProviderChannel(ctx); !ok { + if !hasValidMsgsPreCCV(tx.GetMsgs()) { + return ctx, fmt.Errorf("tx contains unsupported message types at height %d", currHeight) + } + } + + return next(ctx, tx, simulate) +} + +func hasValidMsgsPreCCV(msgs []sdk.Msg) bool { + for _, msg := range msgs { + msgType := sdk.MsgTypeURL(msg) + + // Only accept IBC messages prior to the CCV channel being established. + // Note, rather than listing out all possible IBC message types, we assume + // all IBC message types have a correct and canonical prefix -- /ibc.* + if !strings.HasPrefix(msgType, "/ibc.") { + return false + } + } + + return true +} diff --git a/app/consumer-democracy/ante/msg_filter_ante_test.go b/app/consumer-democracy/ante/msg_filter_ante_test.go new file mode 100644 index 0000000000..6fb1f08955 --- /dev/null +++ b/app/consumer-democracy/ante/msg_filter_ante_test.go @@ -0,0 +1,85 @@ +package ante_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" + appconsumer "github.com/cosmos/interchain-security/app/consumer" + "github.com/cosmos/interchain-security/app/consumer/ante" + "github.com/stretchr/testify/require" + "github.com/tendermint/spm/cosmoscmd" +) + +type consumerKeeper struct { + channelExists bool +} + +func (k consumerKeeper) GetProviderChannel(_ sdk.Context) (string, bool) { + return "", k.channelExists +} + +func noOpAnteDecorator() sdk.AnteHandler { + return func(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) { + return ctx, nil + } +} + +func TestMsgFilterDecorator(t *testing.T) { + txCfg := cosmoscmd.MakeEncodingConfig(appconsumer.ModuleBasics).TxConfig + + testCases := []struct { + name string + ctx sdk.Context + consumerKeeper ante.ConsumerKeeper + msgs []sdk.Msg + expectErr bool + }{ + { + name: "valid tx pre-CCV", + ctx: sdk.Context{}, + consumerKeeper: consumerKeeper{channelExists: false}, + msgs: []sdk.Msg{ + &ibcclienttypes.MsgUpdateClient{}, + }, + expectErr: false, + }, + { + name: "invalid tx pre-CCV", + ctx: sdk.Context{}, + consumerKeeper: consumerKeeper{channelExists: false}, + msgs: []sdk.Msg{ + &banktypes.MsgSend{}, + }, + expectErr: true, + }, + { + name: "valid tx post-CCV", + ctx: sdk.Context{}, + consumerKeeper: consumerKeeper{channelExists: true}, + msgs: []sdk.Msg{ + &banktypes.MsgSend{}, + }, + expectErr: false, + }, + } + + for _, tc := range testCases { + tc := tc + + t.Run(tc.name, func(t *testing.T) { + handler := ante.NewMsgFilterDecorator(tc.consumerKeeper) + + txBuilder := txCfg.NewTxBuilder() + require.NoError(t, txBuilder.SetMsgs(tc.msgs...)) + + _, err := handler.AnteHandle(tc.ctx, txBuilder.GetTx(), false, noOpAnteDecorator()) + if tc.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/app/consumer-democracy/ante_handler.go b/app/consumer-democracy/ante_handler.go new file mode 100644 index 0000000000..ea0984b41b --- /dev/null +++ b/app/consumer-democracy/ante_handler.go @@ -0,0 +1,58 @@ +package app + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/ante" + ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" + consumerante "github.com/cosmos/interchain-security/app/consumer/ante" + ibcconsumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" +) + +// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC +// channel keeper. +type HandlerOptions struct { + ante.HandlerOptions + + IBCKeeper *ibckeeper.Keeper + ConsumerKeeper ibcconsumerkeeper.Keeper +} + +func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { + if options.AccountKeeper == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler") + } + if options.BankKeeper == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") + } + if options.SignModeHandler == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") + } + + var sigGasConsumer = options.SigGasConsumer + if sigGasConsumer == nil { + sigGasConsumer = ante.DefaultSigVerificationGasConsumer + } + + anteDecorators := []sdk.AnteDecorator{ + ante.NewSetUpContextDecorator(), + ante.NewRejectExtensionOptionsDecorator(), + consumerante.NewMsgFilterDecorator(options.ConsumerKeeper), + ante.NewMempoolFeeDecorator(), + ante.NewValidateBasicDecorator(), + ante.NewTxTimeoutHeightDecorator(), + ante.NewValidateMemoDecorator(options.AccountKeeper), + ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), + ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), + // SetPubKeyDecorator must be called before all signature verification decorators + ante.NewSetPubKeyDecorator(options.AccountKeeper), + ante.NewValidateSigCountDecorator(options.AccountKeeper), + ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), + ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), + ante.NewIncrementSequenceDecorator(options.AccountKeeper), + ibcante.NewAnteDecorator(options.IBCKeeper), + } + + return sdk.ChainAnteDecorators(anteDecorators...), nil +} diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go new file mode 100644 index 0000000000..7f60c0dc47 --- /dev/null +++ b/app/consumer-democracy/app.go @@ -0,0 +1,746 @@ +package app + +import ( + "fmt" + "io" + stdlog "log" + "net/http" + "os" + "path/filepath" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" + "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/server/api" + "github.com/cosmos/cosmos-sdk/server/config" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/simapp" + store "github.com/cosmos/cosmos-sdk/store/types" + 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" + "github.com/cosmos/cosmos-sdk/x/auth/ante" + authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/auth/vesting" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + "github.com/cosmos/cosmos-sdk/x/authz" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module" + "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" + "github.com/cosmos/cosmos-sdk/x/capability" + capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + "github.com/cosmos/cosmos-sdk/x/crisis" + crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" + "github.com/cosmos/cosmos-sdk/x/evidence" + evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + "github.com/cosmos/cosmos-sdk/x/feegrant" + feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" + feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" + "github.com/cosmos/cosmos-sdk/x/params" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/cosmos-sdk/x/slashing" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + "github.com/cosmos/cosmos-sdk/x/upgrade" + upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/cosmos/ibc-go/v3/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v3/modules/core" + ibcconnectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" + porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" + ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" + ibctesting "github.com/cosmos/ibc-go/v3/testing" + "github.com/gorilla/mux" + "github.com/rakyll/statik/fs" + "github.com/spf13/cast" + "github.com/tendermint/spm/cosmoscmd" + abci "github.com/tendermint/tendermint/abci/types" + tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/libs/log" + tmos "github.com/tendermint/tendermint/libs/os" + dbm "github.com/tendermint/tm-db" + + ibcconsumer "github.com/cosmos/interchain-security/x/ccv/consumer" + ibcconsumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" + ibcconsumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" + + // unnamed import of statik for swagger UI support + _ "github.com/cosmos/cosmos-sdk/client/docs/statik" + ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" +) + +const ( + AppName = "interchain-security-c" + upgradeName = "v07-Theta" + AccountAddressPrefix = "cosmos" +) + +var ( + // DefaultNodeHome default home directories for the application daemon + DefaultNodeHome string + + // ModuleBasics defines the module BasicManager is in charge of setting up basic, + // non-dependant module elements, such as codec registration + // and genesis verification. + ModuleBasics = module.NewBasicManager( + auth.AppModuleBasic{}, + bank.AppModuleBasic{}, + capability.AppModuleBasic{}, + params.AppModuleBasic{}, + crisis.AppModuleBasic{}, + slashing.AppModuleBasic{}, + feegrantmodule.AppModuleBasic{}, + authzmodule.AppModuleBasic{}, + ibc.AppModuleBasic{}, + upgrade.AppModuleBasic{}, + evidence.AppModuleBasic{}, + transfer.AppModuleBasic{}, + vesting.AppModuleBasic{}, + //router.AppModuleBasic{}, + ibcconsumer.AppModuleBasic{}, + ) + + // module account permissions + maccPerms = map[string][]string{ + authtypes.FeeCollectorName: nil, + ibcconsumertypes.ConsumerRedistributeName: nil, + ibcconsumertypes.ConsumerToSendToProviderName: nil, + ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + } +) + +var ( + _ simapp.App = (*App)(nil) + _ servertypes.Application = (*App)(nil) + _ cosmoscmd.CosmosApp = (*App)(nil) + _ ibctesting.TestingApp = (*App)(nil) +) + +// App extends an ABCI application, but with most of its parameters exported. +// They are exported for convenience in creating helper functions, as object +// capabilities aren't needed for testing. +type App struct { // nolint: golint + *baseapp.BaseApp + legacyAmino *codec.LegacyAmino + appCodec codec.Codec + interfaceRegistry types.InterfaceRegistry + + invCheckPeriod uint + + // keys to access the substores + keys map[string]*sdk.KVStoreKey + tkeys map[string]*sdk.TransientStoreKey + memKeys map[string]*sdk.MemoryStoreKey + + // keepers + AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.Keeper + CapabilityKeeper *capabilitykeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + + // NOTE the distribution keeper should either be removed + // from consumer chain or set to use an independant + // different fee-pool from the consumer chain ConsumerKeeper + + CrisisKeeper crisiskeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + EvidenceKeeper evidencekeeper.Keeper + TransferKeeper ibctransferkeeper.Keeper + FeeGrantKeeper feegrantkeeper.Keeper + AuthzKeeper authzkeeper.Keeper + ConsumerKeeper ibcconsumerkeeper.Keeper + + // make scoped keepers public for test purposes + ScopedIBCKeeper capabilitykeeper.ScopedKeeper + ScopedTransferKeeper capabilitykeeper.ScopedKeeper + ScopedIBCConsumerKeeper capabilitykeeper.ScopedKeeper + + // the module manager + MM *module.Manager + + // simulation manager + sm *module.SimulationManager + configurator module.Configurator +} + +func init() { + userHomeDir, err := os.UserHomeDir() + if err != nil { + stdlog.Println("Failed to get home dir %2", err) + } + + DefaultNodeHome = filepath.Join(userHomeDir, "."+AppName) +} + +// New returns a reference to an initialized App. +func New( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + loadLatest bool, + skipUpgradeHeights map[int64]bool, + homePath string, + invCheckPeriod uint, + encodingConfig cosmoscmd.EncodingConfig, + appOpts servertypes.AppOptions, + baseAppOptions ...func(*baseapp.BaseApp), +) cosmoscmd.App { + + appCodec := encodingConfig.Marshaler + legacyAmino := encodingConfig.Amino + interfaceRegistry := encodingConfig.InterfaceRegistry + + bApp := baseapp.NewBaseApp(AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) + bApp.SetCommitMultiStoreTracer(traceStore) + bApp.SetVersion(version.Version) + bApp.SetInterfaceRegistry(interfaceRegistry) + + keys := sdk.NewKVStoreKeys( + authtypes.StoreKey, banktypes.StoreKey, slashingtypes.StoreKey, + paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, + evidencetypes.StoreKey, ibctransfertypes.StoreKey, + capabilitytypes.StoreKey, feegrant.StoreKey, authzkeeper.StoreKey, + ibcconsumertypes.StoreKey, + ) + tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) + memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + + app := &App{ + BaseApp: bApp, + legacyAmino: legacyAmino, + appCodec: appCodec, + interfaceRegistry: interfaceRegistry, + invCheckPeriod: invCheckPeriod, + keys: keys, + tkeys: tkeys, + memKeys: memKeys, + } + + app.ParamsKeeper = initParamsKeeper( + appCodec, + legacyAmino, + keys[paramstypes.StoreKey], + tkeys[paramstypes.TStoreKey], + ) + + // set the BaseApp's parameter store + bApp.SetParamStore( + app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable( + paramskeeper.ConsensusParamsKeyTable()), + ) + + // add capability keeper and ScopeToModule for ibc module + app.CapabilityKeeper = capabilitykeeper.NewKeeper( + appCodec, + keys[capabilitytypes.StoreKey], + memKeys[capabilitytypes.MemStoreKey], + ) + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) + scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) + scopedIBCConsumerKeeper := app.CapabilityKeeper.ScopeToModule(ibcconsumertypes.ModuleName) + app.CapabilityKeeper.Seal() + + // add keepers + app.AccountKeeper = authkeeper.NewAccountKeeper( + appCodec, + keys[authtypes.StoreKey], + app.GetSubspace(authtypes.ModuleName), + authtypes.ProtoBaseAccount, + maccPerms, + ) + + // Remove the fee-pool from the group of blocked recipient addresses in bank + // this is required for the provider chain to be able to receive tokens from + // the consumer chain + bankBlockedAddrs := app.ModuleAccountAddrs() + delete(bankBlockedAddrs, authtypes.NewModuleAddress( + authtypes.FeeCollectorName).String()) + + app.BankKeeper = bankkeeper.NewBaseKeeper( + appCodec, + keys[banktypes.StoreKey], + app.AccountKeeper, + app.GetSubspace(banktypes.ModuleName), + bankBlockedAddrs, + ) + app.AuthzKeeper = authzkeeper.NewKeeper( + keys[authzkeeper.StoreKey], + appCodec, + app.BaseApp.MsgServiceRouter(), + ) + app.FeeGrantKeeper = feegrantkeeper.NewKeeper( + appCodec, + keys[feegrant.StoreKey], + app.AccountKeeper, + ) + app.SlashingKeeper = slashingkeeper.NewKeeper( + appCodec, + keys[slashingtypes.StoreKey], + &app.ConsumerKeeper, + app.GetSubspace(slashingtypes.ModuleName), + ) + app.CrisisKeeper = crisiskeeper.NewKeeper( + app.GetSubspace(crisistypes.ModuleName), + invCheckPeriod, + app.BankKeeper, + authtypes.FeeCollectorName, + ) + app.UpgradeKeeper = upgradekeeper.NewKeeper( + skipUpgradeHeights, + keys[upgradetypes.StoreKey], + appCodec, + homePath, + app.BaseApp, + ) + app.IBCKeeper = ibckeeper.NewKeeper( + appCodec, + keys[ibchost.StoreKey], + app.GetSubspace(ibchost.ModuleName), + &app.ConsumerKeeper, + app.UpgradeKeeper, + scopedIBCKeeper, + ) + + // Create CCV consumer and modules + app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( + appCodec, + keys[ibcconsumertypes.StoreKey], + app.GetSubspace(ibcconsumertypes.ModuleName), + scopedIBCConsumerKeeper, + app.IBCKeeper.ChannelKeeper, + &app.IBCKeeper.PortKeeper, + app.IBCKeeper.ConnectionKeeper, + app.IBCKeeper.ClientKeeper, + app.SlashingKeeper, + app.BankKeeper, + app.AccountKeeper, + &app.TransferKeeper, + app.IBCKeeper, + authtypes.FeeCollectorName, + ) + + // consumer keeper satisfies the staking keeper interface + // of the slashing module + app.SlashingKeeper = slashingkeeper.NewKeeper( + appCodec, + keys[slashingtypes.StoreKey], + &app.ConsumerKeeper, + app.GetSubspace(slashingtypes.ModuleName), + ) + + // register slashing module StakingHooks to the consumer keeper + app.ConsumerKeeper = *app.ConsumerKeeper.SetHooks(app.SlashingKeeper.Hooks()) + consumerModule := ibcconsumer.NewAppModule(app.ConsumerKeeper) + + app.TransferKeeper = ibctransferkeeper.NewKeeper( + appCodec, + keys[ibctransfertypes.StoreKey], + app.GetSubspace(ibctransfertypes.ModuleName), + app.IBCKeeper.ChannelKeeper, + app.IBCKeeper.ChannelKeeper, + &app.IBCKeeper.PortKeeper, + app.AccountKeeper, + app.BankKeeper, + scopedTransferKeeper, + ) + transferModule := transfer.NewAppModule(app.TransferKeeper) + ibcmodule := transfer.NewIBCModule(app.TransferKeeper) + + // create static IBC router, add transfer route, then set and seal it + ibcRouter := porttypes.NewRouter() + ibcRouter.AddRoute(ibctransfertypes.ModuleName, ibcmodule) + ibcRouter.AddRoute(ibcconsumertypes.ModuleName, consumerModule) + app.IBCKeeper.SetRouter(ibcRouter) + + // create evidence keeper with router + evidenceKeeper := evidencekeeper.NewKeeper( + appCodec, + keys[evidencetypes.StoreKey], + &app.ConsumerKeeper, + app.SlashingKeeper, + ) + + app.EvidenceKeeper = *evidenceKeeper + + skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants)) + + // NOTE: Any module instantiated in the module manager that is later modified + // must be passed by reference here. + app.MM = module.NewManager( + auth.NewAppModule(appCodec, app.AccountKeeper, nil), + vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), + bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), + capability.NewAppModule(appCodec, *app.CapabilityKeeper), + crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.ConsumerKeeper), + upgrade.NewAppModule(app.UpgradeKeeper), + evidence.NewAppModule(app.EvidenceKeeper), + feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + ibc.NewAppModule(app.IBCKeeper), + params.NewAppModule(app.ParamsKeeper), + transferModule, + consumerModule, + ) + + // During begin block slashing happens after distr.BeginBlocker so that + // there is nothing left over in the validator fee pool, so as to keep the + // CanWithdrawInvariant invariant. + // NOTE: staking module is required if HistoricalEntries param > 0 + // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) + app.MM.SetOrderBeginBlockers( + // upgrades should be run first + upgradetypes.ModuleName, + capabilitytypes.ModuleName, + crisistypes.ModuleName, + ibctransfertypes.ModuleName, + ibchost.ModuleName, + authtypes.ModuleName, + banktypes.ModuleName, + slashingtypes.ModuleName, + evidencetypes.ModuleName, + authz.ModuleName, + feegrant.ModuleName, + paramstypes.ModuleName, + vestingtypes.ModuleName, + ibcconsumertypes.ModuleName, + ) + app.MM.SetOrderEndBlockers( + crisistypes.ModuleName, + ibctransfertypes.ModuleName, + ibchost.ModuleName, + feegrant.ModuleName, + authz.ModuleName, + capabilitytypes.ModuleName, + authtypes.ModuleName, + banktypes.ModuleName, + slashingtypes.ModuleName, + evidencetypes.ModuleName, + paramstypes.ModuleName, + upgradetypes.ModuleName, + vestingtypes.ModuleName, + ibcconsumertypes.ModuleName, + ) + + // NOTE: The genutils module must occur after staking so that pools are + // properly initialized with tokens from genesis accounts. + // NOTE: The genutils module must also occur after auth so that it can access the params from auth. + // NOTE: Capability module must occur first so that it can initialize any capabilities + // so that other modules that want to create or claim capabilities afterwards in InitChain + // can do so safely. + app.MM.SetOrderInitGenesis( + capabilitytypes.ModuleName, + banktypes.ModuleName, + slashingtypes.ModuleName, + crisistypes.ModuleName, + ibchost.ModuleName, + evidencetypes.ModuleName, + ibctransfertypes.ModuleName, + feegrant.ModuleName, + authz.ModuleName, + authtypes.ModuleName, + + paramstypes.ModuleName, + upgradetypes.ModuleName, + vestingtypes.ModuleName, + ibcconsumertypes.ModuleName, + ) + + app.MM.RegisterInvariants(&app.CrisisKeeper) + app.MM.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) + + app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) + app.MM.RegisterServices(app.configurator) + + // create the simulation manager and define the order of the modules for deterministic simulations + // + // NOTE: this is not required apps that don't use the simulator for fuzz testing + // transactions + app.sm = module.NewSimulationManager( + auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts), + bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), + capability.NewAppModule(appCodec, *app.CapabilityKeeper), + feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + params.NewAppModule(app.ParamsKeeper), + evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), + transferModule, + ) + + app.sm.RegisterStoreDecoders() + + // initialize stores + app.MountKVStores(keys) + app.MountTransientStores(tkeys) + app.MountMemoryStores(memKeys) + + 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, + ConsumerKeeper: app.ConsumerKeeper, + }, + ) + 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) + + app.UpgradeKeeper.SetUpgradeHandler( + upgradeName, + func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { + app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) + + fromVM := make(map[string]uint64) + + for moduleName, eachModule := range app.MM.Modules { + fromVM[moduleName] = eachModule.ConsensusVersion() + } + + ctx.Logger().Info("start to run module migrations...") + + return app.MM.RunMigrations(ctx, app.configurator, fromVM) + }, + ) + + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() + if err != nil { + panic(fmt.Sprintf("failed to read upgrade info from disk %s", err)) + } + + if upgradeInfo.Name == upgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + storeUpgrades := store.StoreUpgrades{} + + // configure store loader that checks if version == upgradeHeight and applies store upgrades + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + } + + if loadLatest { + if err := app.LoadLatestVersion(); err != nil { + tmos.Exit(fmt.Sprintf("failed to load latest version: %s", err)) + } + } + + app.ScopedIBCKeeper = scopedIBCKeeper + app.ScopedTransferKeeper = scopedTransferKeeper + app.ScopedIBCConsumerKeeper = scopedIBCConsumerKeeper + + return app +} + +// Name returns the name of the App +func (app *App) Name() string { return app.BaseApp.Name() } + +// BeginBlocker application updates every begin block +func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + return app.MM.BeginBlock(ctx, req) +} + +// EndBlocker application updates every end block +func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + return app.MM.EndBlock(ctx, req) +} + +// InitChainer application update at chain initialization +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.MM.GetVersionMap()) + return app.MM.InitGenesis(ctx, app.appCodec, genesisState) +} + +// LoadHeight loads a particular height +func (app *App) LoadHeight(height int64) error { + return app.LoadVersion(height) +} + +// ModuleAccountAddrs returns all the app's module account addresses. +func (app *App) ModuleAccountAddrs() map[string]bool { + modAccAddrs := make(map[string]bool) + for acc := range maccPerms { + modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true + } + + return modAccAddrs +} + +// LegacyAmino returns App's amino codec. +// +// NOTE: This is solely to be used for testing purposes as it may be desirable +// for modules to register their own custom testing types. +func (app *App) LegacyAmino() *codec.LegacyAmino { + return app.legacyAmino +} + +// AppCodec returns the app codec. +// +// NOTE: This is solely to be used for testing purposes as it may be desirable +// for modules to register their own custom testing types. +func (app *App) AppCodec() codec.Codec { + return app.appCodec +} + +// InterfaceRegistry returns the InterfaceRegistry +func (app *App) InterfaceRegistry() types.InterfaceRegistry { + return app.interfaceRegistry +} + +// GetKey returns the KVStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (app *App) GetKey(storeKey string) *sdk.KVStoreKey { + return app.keys[storeKey] +} + +// GetTKey returns the TransientStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (app *App) GetTKey(storeKey string) *sdk.TransientStoreKey { + return app.tkeys[storeKey] +} + +// GetMemKey returns the MemStoreKey for the provided mem key. +// +// NOTE: This is solely used for testing purposes. +func (app *App) GetMemKey(storeKey string) *sdk.MemoryStoreKey { + return app.memKeys[storeKey] +} + +// GetSubspace returns a param subspace for a given module name. +// +// NOTE: This is solely to be used for testing purposes. +func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { + subspace, _ := app.ParamsKeeper.GetSubspace(moduleName) + return subspace +} + +// SimulationManager implements the SimulationApp interface +func (app *App) SimulationManager() *module.SimulationManager { + return app.sm +} + +// TestingApp functions + +// GetBaseApp implements the TestingApp interface. +func (app *App) GetBaseApp() *baseapp.BaseApp { + return app.BaseApp +} + +// GetStakingKeeper implements the TestingApp interface. +func (app *App) GetStakingKeeper() ibcclienttypes.StakingKeeper { + return app.ConsumerKeeper +} + +// GetIBCKeeper implements the TestingApp interface. +func (app *App) GetIBCKeeper() *ibckeeper.Keeper { + return app.IBCKeeper +} + +// GetScopedIBCKeeper implements the TestingApp interface. +func (app *App) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper { + return app.ScopedIBCKeeper +} + +// GetTxConfig implements the TestingApp interface. +func (app *App) GetTxConfig() client.TxConfig { + return cosmoscmd.MakeEncodingConfig(ModuleBasics).TxConfig +} + +// RegisterAPIRoutes registers all application module routes with the provided +// API server. +func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { + clientCtx := apiSvr.ClientCtx + rpc.RegisterRoutes(clientCtx, apiSvr.Router) + // Register legacy tx routes. + authrest.RegisterTxRoutes(clientCtx, apiSvr.Router) + // Register new tx routes from grpc-gateway. + authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + // Register new tendermint queries routes from grpc-gateway. + tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + + // Register legacy and grpc-gateway routes for all modules. + ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router) + ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + + // register swagger API from root so that other applications can override easily + if apiConfig.Swagger { + RegisterSwaggerAPI(apiSvr.Router) + } +} + +// RegisterTxService implements the Application.RegisterTxService method. +func (app *App) RegisterTxService(clientCtx client.Context) { + authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) +} + +// RegisterTendermintService implements the Application.RegisterTendermintService method. +func (app *App) RegisterTendermintService(clientCtx client.Context) { + tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry) +} + +// RegisterSwaggerAPI registers swagger route with API Server +func RegisterSwaggerAPI(rtr *mux.Router) { + statikFS, err := fs.New() + if err != nil { + panic(err) + } + + staticServer := http.FileServer(statikFS) + rtr.PathPrefix("/swagger/").Handler(http.StripPrefix("/swagger/", staticServer)) +} + +// GetMaccPerms returns a copy of the module account permissions +func GetMaccPerms() map[string][]string { + dupMaccPerms := make(map[string][]string) + for k, v := range maccPerms { + dupMaccPerms[k] = v + } + return dupMaccPerms +} + +// initParamsKeeper init params keeper and its subspaces +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper { + paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) + + paramsKeeper.Subspace(authtypes.ModuleName) + paramsKeeper.Subspace(banktypes.ModuleName) + paramsKeeper.Subspace(slashingtypes.ModuleName) + paramsKeeper.Subspace(crisistypes.ModuleName) + paramsKeeper.Subspace(ibctransfertypes.ModuleName) + paramsKeeper.Subspace(ibchost.ModuleName) + paramsKeeper.Subspace(ibcconsumertypes.ModuleName) + + return paramsKeeper +} diff --git a/app/consumer-democracy/export.go b/app/consumer-democracy/export.go new file mode 100644 index 0000000000..c146ab7ad2 --- /dev/null +++ b/app/consumer-democracy/export.go @@ -0,0 +1,198 @@ +package app + +import ( + "encoding/json" + "fmt" + + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + servertypes "github.com/cosmos/cosmos-sdk/server/types" + sdk "github.com/cosmos/cosmos-sdk/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + tmtypes "github.com/tendermint/tendermint/types" +) + +// ExportAppStateAndValidators exports the state of the application for a genesis +// file. +func (app *App) ExportAppStateAndValidators( + forZeroHeight bool, jailAllowedAddrs []string, +) (servertypes.ExportedApp, error) { + + // as if they could withdraw from the start of the next block + ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + + // We export at last height + 1, because that's the height at which + // Tendermint will start InitChain. + height := app.LastBlockHeight() + 1 + if forZeroHeight { + height = 0 + app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) + } + + genState := app.MM.ExportGenesis(ctx, app.appCodec) + appState, err := json.MarshalIndent(genState, "", " ") + if err != nil { + return servertypes.ExportedApp{}, err + } + + validators, err := app.GetValidatorSet(ctx) + if err != nil { + return servertypes.ExportedApp{}, err + } + return servertypes.ExportedApp{ + AppState: appState, + Validators: validators, + Height: height, + ConsensusParams: app.BaseApp.GetConsensusParams(ctx), + }, nil +} + +// prepare for fresh start at zero height +// NOTE zero height genesis is a temporary feature which will be deprecated +// in favour of export at a block height +func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) { + // applyAllowedAddrs := false + + // check if there is a allowed address list + // if len(jailAllowedAddrs) > 0 { + // applyAllowedAddrs = true + // } + + // allowedAddrsMap := make(map[string]bool) + + // for _, addr := range jailAllowedAddrs { + // _, err := sdk.ValAddressFromBech32(addr) + // if err != nil { + // log.Fatal(err) + // } + // allowedAddrsMap[addr] = true + // } + + /* Just to be safe, assert the invariants on current state. */ + app.CrisisKeeper.AssertInvariants(ctx) + + /* Handle fee distribution state. */ + + // withdraw all validator commission + // app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + // _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) + // if err != nil { + // panic(err) + // } + // return false + // }) + + // withdraw all delegator rewards + // dels := app.StakingKeeper.GetAllDelegations(ctx) + // for _, delegation := range dels { + // _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr()) + // if err != nil { + // panic(err) + // } + // } + + // clear validator slash events + // app.DistrKeeper.DeleteAllValidatorSlashEvents(ctx) + + // clear validator historical rewards + // app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) + + // set context height to zero + height := ctx.BlockHeight() + ctx = ctx.WithBlockHeight(0) + + // reinitialize all validators + // app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + // // donate any unwithdrawn outstanding reward fraction tokens to the community pool + // scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) + // feePool := app.DistrKeeper.GetFeePool(ctx) + // feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) + // app.DistrKeeper.SetFeePool(ctx, feePool) + + // app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) + // return false + // }) + + // reinitialize all delegations + // for _, del := range dels { + // app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + // app.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + // } + + // reset context height + ctx = ctx.WithBlockHeight(height) + + /* Handle staking state. */ + + // iterate through redelegations, reset creation height + // app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { + // for i := range red.Entries { + // red.Entries[i].CreationHeight = 0 + // } + // app.StakingKeeper.SetRedelegation(ctx, red) + // return false + // }) + + // iterate through unbonding delegations, reset creation height + // app.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { + // for i := range ubd.Entries { + // ubd.Entries[i].CreationHeight = 0 + // } + // app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) + // return false + // }) + + // Iterate through validators by power descending, reset bond heights, and + // update bond intra-tx counters. + // store := ctx.KVStore(app.keys[stakingtypes.StoreKey]) + // iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) + // counter := int16(0) + + // for ; iter.Valid(); iter.Next() { + // addr := sdk.ValAddress(iter.Key()[1:]) + // validator, found := app.StakingKeeper.GetValidator(ctx, addr) + // if !found { + // panic("expected validator, not found") + // } + + // validator.UnbondingHeight = 0 + // if applyAllowedAddrs && !allowedAddrsMap[addr.String()] { + // validator.Jailed = true + // } + + // app.StakingKeeper.SetValidator(ctx, validator) + // counter++ + // } + + // iter.Close() + + // if _, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil { + // panic(err) + // } + + /* Handle slashing state. */ + + // reset start height on signing infos + app.SlashingKeeper.IterateValidatorSigningInfos( + ctx, + func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) { + info.StartHeight = 0 + app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info) + return false + }, + ) +} + +// GetValidatorSet returns a slice of bonded validators. +func (app *App) GetValidatorSet(ctx sdk.Context) ([]tmtypes.GenesisValidator, error) { + cVals := app.ConsumerKeeper.GetAllCCValidator(ctx) + if len(cVals) == 0 { + return nil, fmt.Errorf("empty validator set") + } + + vals := []tmtypes.GenesisValidator{} + for _, v := range cVals { + vals = append(vals, tmtypes.GenesisValidator{Address: v.Address, Power: v.Power}) + } + return vals, nil +} diff --git a/app/consumer-democracy/genesis.go b/app/consumer-democracy/genesis.go new file mode 100644 index 0000000000..5bf0c1da80 --- /dev/null +++ b/app/consumer-democracy/genesis.go @@ -0,0 +1,21 @@ +package app + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/codec" +) + +// The genesis state of the blockchain is represented here as a map of raw json +// messages key'd by a identifier string. +// The identifier is used to determine which module genesis information belongs +// to so it may be appropriately routed during init chain. +// Within this application default genesis information is retrieved from +// the ModuleBasicManager which populates json from each BasicModule +// object provided to it during init. +type GenesisState map[string]json.RawMessage + +// NewDefaultGenesisState generates the default state for the application. +func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState { + return ModuleBasics.DefaultGenesis(cdc) +} From 76f92956b68230758b9a565b33384ca0b3964c17 Mon Sep 17 00:00:00 2001 From: billy rennekamp Date: Thu, 7 Jul 2022 14:14:48 +0200 Subject: [PATCH 2/4] added ccvstaking, ccvdistribution, ccvgov and ccvminting --- app/consumer-democracy/app.go | 144 ++++++++++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 17 deletions(-) diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index 7f60c0dc47..8068cbf3fb 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -50,8 +50,11 @@ import ( feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" "github.com/cosmos/cosmos-sdk/x/params" + paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" + "github.com/cosmos/cosmos-sdk/x/slashing" slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" @@ -77,6 +80,29 @@ import ( tmos "github.com/tendermint/tendermint/libs/os" dbm "github.com/tendermint/tm-db" + // add ccv distribution CALUM + distr "github.com/cosmos/cosmos-sdk/x/distribution" + ccvdistrclient "github.com/cosmos/cosmos-sdk/x/distribution/client" + ccvdistrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + ccvdistrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + ccvdistr "github.com/cosmos/interchain-security/x/ccv/distribution" + + // add ccv staking BILY + ccvstakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + ccvstakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ccvstaking "github.com/cosmos/interchain-security/x/ccv/staking" + + // add gov Billy + ccvgov "github.com/cosmos/cosmos-sdk/x/gov" + ccvgovkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + ccvgovtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + // add mint + ccvmint "github.com/cosmos/cosmos-sdk/x/mint" + ccvmintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + ccvminttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + + paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" ibcconsumer "github.com/cosmos/interchain-security/x/ccv/consumer" ibcconsumerkeeper "github.com/cosmos/interchain-security/x/ccv/consumer/keeper" ibcconsumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" @@ -87,7 +113,7 @@ import ( ) const ( - AppName = "interchain-security-c" + AppName = "interchain-security-cd" upgradeName = "v07-Theta" AccountAddressPrefix = "cosmos" ) @@ -103,6 +129,13 @@ var ( auth.AppModuleBasic{}, bank.AppModuleBasic{}, capability.AppModuleBasic{}, + ccvstaking.AppModuleBasic{}, + ccvdistr.AppModuleBasic{}, + ccvmint.AppModuleBasic{}, + ccvgov.NewAppModuleBasic( + // TODO: eventually remove upgrade proposal handler and cancel proposal handler + paramsclient.ProposalHandler, ccvdistrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, + ), params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, @@ -120,9 +153,14 @@ var ( // module account permissions maccPerms = map[string][]string{ authtypes.FeeCollectorName: nil, + ccvstakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + ccvstakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + ccvdistrtypes.ModuleName: nil, + ccvminttypes.ModuleName: {authtypes.Minter}, ibcconsumertypes.ConsumerRedistributeName: nil, ibcconsumertypes.ConsumerToSendToProviderName: nil, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + ccvgovtypes.ModuleName: {authtypes.Burner}, } ) @@ -153,21 +191,20 @@ type App struct { // nolint: golint AccountKeeper authkeeper.AccountKeeper BankKeeper bankkeeper.Keeper CapabilityKeeper *capabilitykeeper.Keeper + StakingKeeper ccvstakingkeeper.Keeper SlashingKeeper slashingkeeper.Keeper - - // NOTE the distribution keeper should either be removed - // from consumer chain or set to use an independant - // different fee-pool from the consumer chain ConsumerKeeper - - CrisisKeeper crisiskeeper.Keeper - UpgradeKeeper upgradekeeper.Keeper - ParamsKeeper paramskeeper.Keeper - IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly - EvidenceKeeper evidencekeeper.Keeper - TransferKeeper ibctransferkeeper.Keeper - FeeGrantKeeper feegrantkeeper.Keeper - AuthzKeeper authzkeeper.Keeper - ConsumerKeeper ibcconsumerkeeper.Keeper + MintKeeper ccvmintkeeper.Keeper + DistrKeeper ccvdistrkeeper.Keeper + GovKeeper ccvgovkeeper.Keeper + CrisisKeeper crisiskeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + EvidenceKeeper evidencekeeper.Keeper + TransferKeeper ibctransferkeeper.Keeper + FeeGrantKeeper feegrantkeeper.Keeper + AuthzKeeper authzkeeper.Keeper + ConsumerKeeper ibcconsumerkeeper.Keeper // make scoped keepers public for test purposes ScopedIBCKeeper capabilitykeeper.ScopedKeeper @@ -215,11 +252,12 @@ func New( bApp.SetInterfaceRegistry(interfaceRegistry) keys := sdk.NewKVStoreKeys( - authtypes.StoreKey, banktypes.StoreKey, slashingtypes.StoreKey, + authtypes.StoreKey, banktypes.StoreKey, ccvstakingtypes.StoreKey, slashingtypes.StoreKey, + ccvgovtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, feegrant.StoreKey, authzkeeper.StoreKey, - ibcconsumertypes.StoreKey, + ibcconsumertypes.StoreKey, ccvdistrtypes.StoreKey, ccvminttypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -292,12 +330,55 @@ func New( keys[feegrant.StoreKey], app.AccountKeeper, ) + + ccvstakingKeeper := ccvstakingkeeper.NewKeeper( + appCodec, + keys[ccvstakingtypes.StoreKey], + tkeys[ccvstakingtypes.TStoreKey], + app.AccountKeeper, + app.BankKeeper, + app.GetSubspace(ccvstakingtypes.ModuleName), + ) + + app.MintKeeper = ccvmintkeeper.NewKeeper( + appCodec, keys[ccvminttypes.StoreKey], app.GetSubspace(ccvminttypes.ModuleName), &ccvstakingKeeper, + app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, + ) + + // register the proposal types + ccvgovRouter := ccvgovtypes.NewRouter() + ccvgovRouter.AddRoute(ccvgovtypes.RouterKey, ccvgovtypes.ProposalHandler). + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). + AddRoute(ccvdistrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). + // TODO: remove upgrade handler from gov once admin module or decision for only signaling proposal is made. + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)) + govKeeper := ccvgovkeeper.NewKeeper( + appCodec, keys[ccvgovtypes.StoreKey], app.GetSubspace(ccvgovtypes.ModuleName), app.AccountKeeper, app.BankKeeper, + &ccvstakingKeeper, ccvgovRouter, + ) + + app.GovKeeper = *govKeeper.SetHooks( + ccvgovtypes.NewMultiGovHooks( + // register the governance hooks + ), + ) + app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, keys[slashingtypes.StoreKey], &app.ConsumerKeeper, app.GetSubspace(slashingtypes.ModuleName), ) + app.DistrKeeper = ccvdistrkeeper.NewKeeper( + appCodec, + keys[ccvdistrtypes.StoreKey], + app.GetSubspace(ccvdistrtypes.ModuleName), + app.AccountKeeper, + app.BankKeeper, + &ccvstakingKeeper, + authtypes.FeeCollectorName, + app.ModuleAccountAddrs(), + ) app.CrisisKeeper = crisiskeeper.NewKeeper( app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, @@ -311,6 +392,14 @@ func New( homePath, app.BaseApp, ) + + // register the staking hooks + // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks + // NOTE: slashing hook was removed since it's only relevant for consumerKeeper + app.StakingKeeper = *ccvstakingKeeper.SetHooks( + ccvstakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks()), + ) + app.IBCKeeper = ibckeeper.NewKeeper( appCodec, keys[ibchost.StoreKey], @@ -392,8 +481,12 @@ func New( capability.NewAppModule(appCodec, *app.CapabilityKeeper), crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.ConsumerKeeper), + ccvdistr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, authtypes.FeeCollectorName), + ccvstaking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), + ccvmint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), upgrade.NewAppModule(app.UpgradeKeeper), evidence.NewAppModule(app.EvidenceKeeper), + ccvgov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), ibc.NewAppModule(app.IBCKeeper), @@ -412,10 +505,13 @@ func New( upgradetypes.ModuleName, capabilitytypes.ModuleName, crisistypes.ModuleName, + ccvminttypes.ModuleName, + ccvstakingtypes.ModuleName, ibctransfertypes.ModuleName, ibchost.ModuleName, authtypes.ModuleName, banktypes.ModuleName, + ccvgovtypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, @@ -426,6 +522,8 @@ func New( ) app.MM.SetOrderEndBlockers( crisistypes.ModuleName, + ccvgovtypes.ModuleName, + ccvstakingtypes.ModuleName, ibctransfertypes.ModuleName, ibchost.ModuleName, feegrant.ModuleName, @@ -434,6 +532,7 @@ func New( authtypes.ModuleName, banktypes.ModuleName, slashingtypes.ModuleName, + ccvminttypes.ModuleName, evidencetypes.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, @@ -450,7 +549,10 @@ func New( app.MM.SetOrderInitGenesis( capabilitytypes.ModuleName, banktypes.ModuleName, + ccvstakingtypes.ModuleName, + ccvminttypes.ModuleName, slashingtypes.ModuleName, + ccvgovtypes.ModuleName, crisistypes.ModuleName, ibchost.ModuleName, evidencetypes.ModuleName, @@ -480,7 +582,11 @@ func New( bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + ccvgov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + ccvmint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), + ccvdistr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, authtypes.FeeCollectorName), + ccvstaking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), params.NewAppModule(app.ParamsKeeper), evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), transferModule, @@ -736,7 +842,11 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(authtypes.ModuleName) paramsKeeper.Subspace(banktypes.ModuleName) + paramsKeeper.Subspace(ccvstakingtypes.ModuleName) + paramsKeeper.Subspace(ccvminttypes.ModuleName) + paramsKeeper.Subspace(ccvdistrtypes.ModuleName) paramsKeeper.Subspace(slashingtypes.ModuleName) + paramsKeeper.Subspace(ccvgovtypes.ModuleName).WithKeyTable(ccvgovtypes.ParamKeyTable()) paramsKeeper.Subspace(crisistypes.ModuleName) paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(ibchost.ModuleName) From 485f3874adb91e49b181ec82b0e23454421ecfcb Mon Sep 17 00:00:00 2001 From: billy rennekamp Date: Thu, 7 Jul 2022 14:29:00 +0200 Subject: [PATCH 3/4] add cmd interchain-security-cdd --- Makefile | 5 +++-- cmd/interchain-security-cdd/main.go | 32 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 cmd/interchain-security-cdd/main.go diff --git a/Makefile b/Makefile index b64c07de77..859be37a63 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,9 @@ install: go.sum export GOFLAGS='-buildmode=pie' export CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2" export CGO_LDFLAGS="-Wl,-z,relro,-z,now -fstack-protector" - go install $(BUILD_FLAGS) ./cmd/interchain-security-pd - go install $(BUILD_FLAGS) ./cmd/interchain-security-cd + # go install $(BUILD_FLAGS) ./cmd/interchain-security-pd + # go install $(BUILD_FLAGS) ./cmd/interchain-security-cd + go install $(BUILD_FLAGS) ./cmd/interchain-security-cdd test: go test ./... diff --git a/cmd/interchain-security-cdd/main.go b/cmd/interchain-security-cdd/main.go new file mode 100644 index 0000000000..6b9bbffe60 --- /dev/null +++ b/cmd/interchain-security-cdd/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "os" + + "github.com/cosmos/cosmos-sdk/server" + svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + app "github.com/cosmos/interchain-security/app/consumer-democracy" + "github.com/tendermint/spm/cosmoscmd" +) + +func main() { + rootCmd, _ := cosmoscmd.NewRootCmd( + app.AppName, + app.AccountAddressPrefix, + app.DefaultNodeHome, + app.AppName, + app.ModuleBasics, + app.New, + // this line is used by starport scaffolding # root/arguments + ) + + if err := svrcmd.Execute(rootCmd, app.DefaultNodeHome); err != nil { + switch e := err.(type) { + case server.ErrorCode: + os.Exit(e.Code) + + default: + os.Exit(1) + } + } +} From c8a0fec28d842e1ac6de02748b27a5260671b00b Mon Sep 17 00:00:00 2001 From: billy rennekamp Date: Thu, 7 Jul 2022 14:48:13 +0200 Subject: [PATCH 4/4] distribution tokens should be coming from ConsumerRedistributeName not feeCollector --- x/ccv/distribution/module.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/x/ccv/distribution/module.go b/x/ccv/distribution/module.go index f0a0371e02..6c384bb208 100644 --- a/x/ccv/distribution/module.go +++ b/x/ccv/distribution/module.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/distribution/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" abci "github.com/tendermint/tendermint/abci/types" @@ -77,12 +78,12 @@ func (am AppModule) AllocateTokens( // fetch and clear the collected fees for distribution, since this is // called in BeginBlock, collected fees will be from the previous block // (and distributed to the previous proposer) - feeCollector := am.accountKeeper.GetModuleAccount(ctx, am.feeCollectorName) + feeCollector := am.accountKeeper.GetModuleAccount(ctx, consumertypes.ConsumerRedistributeName) feesCollectedInt := am.bankKeeper.GetAllBalances(ctx, feeCollector.GetAddress()) feesCollected := sdk.NewDecCoinsFromCoins(feesCollectedInt...) // transfer collected fees to the distribution module account - err := am.bankKeeper.SendCoinsFromModuleToModule(ctx, am.feeCollectorName, distrtypes.ModuleName, feesCollectedInt) + err := am.bankKeeper.SendCoinsFromModuleToModule(ctx, consumertypes.ConsumerRedistributeName, distrtypes.ModuleName, feesCollectedInt) if err != nil { panic(err) }