From 53177cf6866cc60965990c2a344ec7dabc50fb46 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 25 Aug 2024 14:19:36 +0000 Subject: [PATCH 01/52] feat(appchain): scaffold coordinator --- .../appchain/coordinator/v1/genesis.proto | 14 + .../appchain/coordinator/v1/params.proto | 9 + .../appchain/coordinator/v1/query.proto | 24 + .../exocore/appchain/coordinator/v1/tx.proto | 8 + x/appchain/common/types/codec.go | 10 + x/appchain/coordinator/client/cli/query.go | 28 + x/appchain/coordinator/client/cli/tx.go | 26 + x/appchain/coordinator/keeper/abci.go | 12 + x/appchain/coordinator/keeper/genesis.go | 18 + x/appchain/coordinator/keeper/grpc_query.go | 25 + x/appchain/coordinator/keeper/keeper.go | 19 + x/appchain/coordinator/keeper/msg_server.go | 17 + x/appchain/coordinator/keeper/params.go | 25 + x/appchain/coordinator/module.go | 172 ++++++ x/appchain/coordinator/types/codec.go | 24 + x/appchain/coordinator/types/genesis.go | 21 + x/appchain/coordinator/types/genesis.pb.go | 325 +++++++++++ x/appchain/coordinator/types/keys.go | 32 ++ x/appchain/coordinator/types/params.go | 16 + x/appchain/coordinator/types/params.pb.go | 266 +++++++++ x/appchain/coordinator/types/query.pb.go | 533 ++++++++++++++++++ x/appchain/coordinator/types/query.pb.gw.go | 153 +++++ x/appchain/coordinator/types/tx.pb.go | 84 +++ x/appchain/coordinator/types/types.go | 1 + 24 files changed, 1862 insertions(+) create mode 100644 proto/exocore/appchain/coordinator/v1/genesis.proto create mode 100644 proto/exocore/appchain/coordinator/v1/params.proto create mode 100644 proto/exocore/appchain/coordinator/v1/query.proto create mode 100644 proto/exocore/appchain/coordinator/v1/tx.proto create mode 100644 x/appchain/common/types/codec.go create mode 100644 x/appchain/coordinator/client/cli/query.go create mode 100644 x/appchain/coordinator/client/cli/tx.go create mode 100644 x/appchain/coordinator/keeper/abci.go create mode 100644 x/appchain/coordinator/keeper/genesis.go create mode 100644 x/appchain/coordinator/keeper/grpc_query.go create mode 100644 x/appchain/coordinator/keeper/keeper.go create mode 100644 x/appchain/coordinator/keeper/msg_server.go create mode 100644 x/appchain/coordinator/keeper/params.go create mode 100644 x/appchain/coordinator/module.go create mode 100644 x/appchain/coordinator/types/codec.go create mode 100644 x/appchain/coordinator/types/genesis.go create mode 100644 x/appchain/coordinator/types/genesis.pb.go create mode 100644 x/appchain/coordinator/types/keys.go create mode 100644 x/appchain/coordinator/types/params.go create mode 100644 x/appchain/coordinator/types/params.pb.go create mode 100644 x/appchain/coordinator/types/query.pb.go create mode 100644 x/appchain/coordinator/types/query.pb.gw.go create mode 100644 x/appchain/coordinator/types/tx.pb.go create mode 100644 x/appchain/coordinator/types/types.go diff --git a/proto/exocore/appchain/coordinator/v1/genesis.proto b/proto/exocore/appchain/coordinator/v1/genesis.proto new file mode 100644 index 000000000..15f5743be --- /dev/null +++ b/proto/exocore/appchain/coordinator/v1/genesis.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package exocore.appchain.coordinator.v1; + +import "exocore/appchain/coordinator/v1/params.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; + +// GenesisState is the genesis state for the appchain coordinator module. +message GenesisState { + // Params is the parameters for the appchain coordinator module. + Params params = 1 [(gogoproto.nullable) = false]; +} diff --git a/proto/exocore/appchain/coordinator/v1/params.proto b/proto/exocore/appchain/coordinator/v1/params.proto new file mode 100644 index 000000000..71ada75e3 --- /dev/null +++ b/proto/exocore/appchain/coordinator/v1/params.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package exocore.appchain.coordinator.v1; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; + +// Params is the parameters for the appchain coordinator module. +message Params { +} diff --git a/proto/exocore/appchain/coordinator/v1/query.proto b/proto/exocore/appchain/coordinator/v1/query.proto new file mode 100644 index 000000000..cbb09617c --- /dev/null +++ b/proto/exocore/appchain/coordinator/v1/query.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +package exocore.appchain.coordinator.v1; + +import "exocore/appchain/coordinator/v1/params.proto"; +import "google/api/annotations.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; + +// Query defines the gRPC querier service. +service Query { + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http) = { + get: "/appchain/coordinator/params" + }; + } +} + +message QueryParamsRequest {} + +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} \ No newline at end of file diff --git a/proto/exocore/appchain/coordinator/v1/tx.proto b/proto/exocore/appchain/coordinator/v1/tx.proto new file mode 100644 index 000000000..80b95b500 --- /dev/null +++ b/proto/exocore/appchain/coordinator/v1/tx.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +package exocore.appchain.coordinator.v1; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; + +// Msg defines the Msg service. +service Msg {} \ No newline at end of file diff --git a/x/appchain/common/types/codec.go b/x/appchain/common/types/codec.go new file mode 100644 index 000000000..b1f519ac0 --- /dev/null +++ b/x/appchain/common/types/codec.go @@ -0,0 +1,10 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" +) + +var ( + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) diff --git a/x/appchain/coordinator/client/cli/query.go b/x/appchain/coordinator/client/cli/query.go new file mode 100644 index 000000000..d45de5d5d --- /dev/null +++ b/x/appchain/coordinator/client/cli/query.go @@ -0,0 +1,28 @@ +package cli + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string) *cobra.Command { + // Group dogfood queries under a subcommand + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf( + "Querying commands for the %s module", + types.ModuleName, + ), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + return cmd +} diff --git a/x/appchain/coordinator/client/cli/tx.go b/x/appchain/coordinator/client/cli/tx.go new file mode 100644 index 000000000..a7913172f --- /dev/null +++ b/x/appchain/coordinator/client/cli/tx.go @@ -0,0 +1,26 @@ +package cli + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + "github.com/cosmos/cosmos-sdk/client" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf( + "%s transactions subcommands", + types.ModuleName, + ), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + return cmd +} diff --git a/x/appchain/coordinator/keeper/abci.go b/x/appchain/coordinator/keeper/abci.go new file mode 100644 index 000000000..cbc3ac339 --- /dev/null +++ b/x/appchain/coordinator/keeper/abci.go @@ -0,0 +1,12 @@ +package keeper + +import ( + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) BeginBlock(sdk.Context) {} + +func (k Keeper) EndBlock(sdk.Context) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/appchain/coordinator/keeper/genesis.go b/x/appchain/coordinator/keeper/genesis.go new file mode 100644 index 000000000..8411f4023 --- /dev/null +++ b/x/appchain/coordinator/keeper/genesis.go @@ -0,0 +1,18 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) InitGenesis(ctx sdk.Context, gs types.GenesisState) []abci.ValidatorUpdate { + k.SetParams(ctx, gs.Params) + return []abci.ValidatorUpdate{} +} + +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + return &types.GenesisState{ + Params: k.GetParams(ctx), + } +} diff --git a/x/appchain/coordinator/keeper/grpc_query.go b/x/appchain/coordinator/keeper/grpc_query.go new file mode 100644 index 000000000..4ba53ad3a --- /dev/null +++ b/x/appchain/coordinator/keeper/grpc_query.go @@ -0,0 +1,25 @@ +package keeper + +import ( + "context" + + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ types.QueryServer = Keeper{} + +func (k Keeper) Params( + goCtx context.Context, + req *types.QueryParamsRequest, +) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + + return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil +} diff --git a/x/appchain/coordinator/keeper/keeper.go b/x/appchain/coordinator/keeper/keeper.go new file mode 100644 index 000000000..9a73b1fba --- /dev/null +++ b/x/appchain/coordinator/keeper/keeper.go @@ -0,0 +1,19 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" +) + +type Keeper struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey +} + +// NewKeeper creates a new coordinator keeper. +func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey) Keeper { + return Keeper{ + cdc: cdc, + storeKey: storeKey, + } +} diff --git a/x/appchain/coordinator/keeper/msg_server.go b/x/appchain/coordinator/keeper/msg_server.go new file mode 100644 index 000000000..9adaac256 --- /dev/null +++ b/x/appchain/coordinator/keeper/msg_server.go @@ -0,0 +1,17 @@ +package keeper + +import "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + +// msgServer is a wrapper around the Keeper (which is the actual implementation) and +// satisfies the MsgServer interface. +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +// interface guard +var _ types.MsgServer = msgServer{} diff --git a/x/appchain/coordinator/keeper/params.go b/x/appchain/coordinator/keeper/params.go new file mode 100644 index 000000000..13c1c3e9c --- /dev/null +++ b/x/appchain/coordinator/keeper/params.go @@ -0,0 +1,25 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SetParams sets the appchain coordinator parameters. +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(¶ms) + store.Set(types.ParamsKey(), bz) +} + +// GetParams gets the appchain coordinator parameters. +func (k Keeper) GetParams(ctx sdk.Context) types.Params { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ParamsKey()) + if bz == nil { + return types.DefaultParams() + } + var params types.Params + k.cdc.MustUnmarshal(bz, ¶ms) + return params +} diff --git a/x/appchain/coordinator/module.go b/x/appchain/coordinator/module.go new file mode 100644 index 000000000..efaed5a7e --- /dev/null +++ b/x/appchain/coordinator/module.go @@ -0,0 +1,172 @@ +package dogfood + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/client/cli" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/keeper" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface that defines the independent methods a +// Cosmos SDK module needs to implement. +type AppModuleBasic struct { + cdc codec.BinaryCodec +} + +func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic { + return AppModuleBasic{cdc: cdc} +} + +// Name returns the name of the module as a string +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the amino codec for the module, which is used to marshal +// and unmarshal structs to/from []byte in order to persist them in the module's KVStore +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers a module's interface types and their concrete implementations as +// proto.Message +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns a default GenesisState for the module, marshaled to json.RawMessage. +// The default GenesisState need to be defined by the module developer and is primarily used for +// testing +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis used to validate the GenesisState, given in its json.RawMessage form +func (AppModuleBasic) ValidateGenesis( + cdc codec.JSONCodec, + _ client.TxEncodingConfig, + bz json.RawMessage, +) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module +func (AppModuleBasic) RegisterGRPCGatewayRoutes( + clientCtx client.Context, + mux *runtime.ServeMux, +) { + if err := types.RegisterQueryHandlerClient( + context.Background(), mux, types.NewQueryClient(clientCtx), + ); err != nil { + // this panic is safe to do because it means an error in setting up the module. + panic(err) + } +} + +// GetTxCmd returns the root Tx command for the module. The subcommands of this root command are +// used by end-users to generate new transactions containing messages defined in the module +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the root query command for the module. The subcommands of this root +// command are used by end-users to generate new queries to the subset of the state defined by +// the module +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd(types.StoreKey) +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface that defines the inter-dependent methods that +// modules need to implement +type AppModule struct { + AppModuleBasic + // keeper of the module receives the cdc codec separately. + keeper keeper.Keeper +} + +func NewAppModule( + cdc codec.Codec, + keeper keeper.Keeper, +) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + keeper: keeper, + } +} + +// RegisterServices registers a gRPC query service to respond to the module-specific gRPC +// queries +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// RegisterInvariants registers the invariants of the module. If an invariant deviates from its +// predicted value, the InvariantRegistry triggers appropriate logic (most often the chain will +// be halted) +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// InitGenesis performs the module's genesis initialization. It returns no validator updates. +func (am AppModule) InitGenesis( + ctx sdk.Context, + cdc codec.JSONCodec, + gs json.RawMessage, +) []abci.ValidatorUpdate { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(gs, &genState) + + return am.keeper.InitGenesis(ctx, genState) +} + +// ExportGenesis returns the module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(genState) +} + +// ConsensusVersion is a sequence number for state-breaking change of the module. It should be +// incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty +// versions, the initial version should be set to 1 +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// BeginBlock contains the logic that is automatically triggered at the beginning of each block +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + am.keeper.BeginBlock(ctx) +} + +// EndBlock contains the logic that is automatically triggered at the end of each block +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return am.keeper.EndBlock(ctx) +} diff --git a/x/appchain/coordinator/types/codec.go b/x/appchain/coordinator/types/codec.go new file mode 100644 index 000000000..8883bdf68 --- /dev/null +++ b/x/appchain/coordinator/types/codec.go @@ -0,0 +1,24 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + + // this line is used by starport scaffolding # 1 + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterCodec(cdc *codec.LegacyAmino) { + // this line is used by starport scaffolding # 2 +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + // this line is used by starport scaffolding # 3 + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + Amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) diff --git a/x/appchain/coordinator/types/genesis.go b/x/appchain/coordinator/types/genesis.go new file mode 100644 index 000000000..255e60642 --- /dev/null +++ b/x/appchain/coordinator/types/genesis.go @@ -0,0 +1,21 @@ +package types + +// DefaultGenesis returns the default genesis state. +func DefaultGenesis() *GenesisState { + return NewGenesis(DefaultParams()) +} + +// NewGenesis creates a new genesis state with the provided parameters and +// data. +func NewGenesis(params Params) *GenesisState { + return &GenesisState{Params: params} +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + return nil +} diff --git a/x/appchain/coordinator/types/genesis.pb.go b/x/appchain/coordinator/types/genesis.pb.go new file mode 100644 index 000000000..66bc614e9 --- /dev/null +++ b/x/appchain/coordinator/types/genesis.pb.go @@ -0,0 +1,325 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/coordinator/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState is the genesis state for the appchain coordinator module. +type GenesisState struct { + // Params is the parameters for the appchain coordinator module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_5e26c64c99ed3693, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "exocore.appchain.coordinator.v1.GenesisState") +} + +func init() { + proto.RegisterFile("exocore/appchain/coordinator/v1/genesis.proto", fileDescriptor_5e26c64c99ed3693) +} + +var fileDescriptor_5e26c64c99ed3693 = []byte{ + // 219 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4d, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, + 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, + 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x87, 0x2a, 0xd7, 0x83, 0x29, + 0xd7, 0x43, 0x52, 0xae, 0x57, 0x66, 0x28, 0xa5, 0x43, 0xc8, 0xbc, 0x82, 0xc4, 0xa2, 0xc4, 0x5c, + 0xa8, 0x71, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0xa6, 0x3e, 0x88, 0x05, 0x11, 0x55, 0x0a, + 0xe5, 0xe2, 0x71, 0x87, 0xd8, 0x1a, 0x5c, 0x92, 0x58, 0x92, 0x2a, 0xe4, 0xca, 0xc5, 0x06, 0xd1, + 0x25, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0xa4, 0xae, 0x47, 0xc0, 0x15, 0x7a, 0x01, 0x60, 0xe5, + 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x41, 0x35, 0x3b, 0x45, 0x9c, 0x78, 0x24, 0xc7, 0x78, + 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, + 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x5d, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, + 0xae, 0xbe, 0x2b, 0xc4, 0x68, 0xbf, 0xd4, 0x92, 0xf2, 0xfc, 0xa2, 0x6c, 0x7d, 0x98, 0x77, 0x2a, + 0xb0, 0x7b, 0xa8, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x6e, 0x63, 0x40, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x84, 0xc9, 0x8b, 0x50, 0x4d, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/coordinator/types/keys.go b/x/appchain/coordinator/types/keys.go new file mode 100644 index 000000000..00cd54a80 --- /dev/null +++ b/x/appchain/coordinator/types/keys.go @@ -0,0 +1,32 @@ +package types + +const ( + // ModuleName defines the module name + ModuleName = "coordinator" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // RouterKey defines the module's message routing key + RouterKey = ModuleName + + // MemStoreKey defines the in-memory store key + MemStoreKey = "mem_coordinator" + + // PortId is the default port id that the module binds to + PortId = "coordinator" + + // SubscriberRewardsPool is the address that receives the rewards from the subscriber + // chains. Technically, it is possible for the subscriber chain to send these rewards + // directly to the FeeCollector, but this intermediate step allows the coordinator + // module to ensure that the rewards are actually sent to us. + SubscriberRewardsPool = "subscriber_rewards_pool" +) + +const ( + ParamsBytePrefix byte = iota + 1 +) + +func ParamsKey() []byte { + return []byte{ParamsBytePrefix} +} diff --git a/x/appchain/coordinator/types/params.go b/x/appchain/coordinator/types/params.go new file mode 100644 index 000000000..21722dc9b --- /dev/null +++ b/x/appchain/coordinator/types/params.go @@ -0,0 +1,16 @@ +package types + +// DefaultParams returns the default parameters for the module. +func DefaultParams() Params { + return Params{} +} + +// NewParams creates a new Params object +func NewParams() Params { + return Params{} +} + +// Validate checks that the parameters have valid values. +func (p Params) Validate() error { + return nil +} diff --git a/x/appchain/coordinator/types/params.pb.go b/x/appchain/coordinator/types/params.pb.go new file mode 100644 index 000000000..34b6e2c73 --- /dev/null +++ b/x/appchain/coordinator/types/params.pb.go @@ -0,0 +1,266 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/coordinator/v1/params.proto + +package types + +import ( + fmt "fmt" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Params is the parameters for the appchain coordinator module. +type Params struct { +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_153952e3bb2d49c4, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Params)(nil), "exocore.appchain.coordinator.v1.Params") +} + +func init() { + proto.RegisterFile("exocore/appchain/coordinator/v1/params.proto", fileDescriptor_153952e3bb2d49c4) +} + +var fileDescriptor_153952e3bb2d49c4 = []byte{ + // 158 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x49, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, + 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, + 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x87, 0xaa, 0xd6, 0x83, 0xa9, 0xd6, + 0x43, 0x52, 0xad, 0x57, 0x66, 0xa8, 0xc4, 0xc1, 0xc5, 0x16, 0x00, 0xd6, 0xe0, 0x14, 0x71, 0xe2, + 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, + 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x76, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, + 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xae, 0x10, 0xf3, 0xfc, 0x52, 0x4b, 0xca, 0xf3, 0x8b, 0xb2, 0xf5, + 0x61, 0x8e, 0xa9, 0xc0, 0xee, 0x9c, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x5b, 0x8c, + 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x46, 0x85, 0x8c, 0x39, 0xbb, 0x00, 0x00, 0x00, +} + +func (m *Params) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/coordinator/types/query.pb.go b/x/appchain/coordinator/types/query.pb.go new file mode 100644 index 000000000..7a99171a7 --- /dev/null +++ b/x/appchain/coordinator/types/query.pb.go @@ -0,0 +1,533 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/coordinator/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c71eb5ef95876a4b, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +type QueryParamsResponse struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c71eb5ef95876a4b, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "exocore.appchain.coordinator.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "exocore.appchain.coordinator.v1.QueryParamsResponse") +} + +func init() { + proto.RegisterFile("exocore/appchain/coordinator/v1/query.proto", fileDescriptor_c71eb5ef95876a4b) +} + +var fileDescriptor_c71eb5ef95876a4b = []byte{ + // 299 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, + 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, + 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x87, 0x2a, 0xd6, 0x83, 0x29, 0xd6, 0x43, + 0x52, 0xac, 0x57, 0x66, 0x28, 0xa5, 0x43, 0xc8, 0xb4, 0x82, 0xc4, 0xa2, 0xc4, 0xdc, 0x62, 0x88, + 0x71, 0x52, 0x32, 0xe9, 0xf9, 0xf9, 0xe9, 0x39, 0x20, 0xc5, 0x99, 0xfa, 0x89, 0x79, 0x79, 0xf9, + 0x25, 0x89, 0x25, 0x99, 0xf9, 0x79, 0x30, 0x59, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0x30, 0x53, 0x1f, + 0xc4, 0x82, 0x88, 0x2a, 0x89, 0x70, 0x09, 0x05, 0x82, 0x5c, 0x14, 0x00, 0x36, 0x28, 0x28, 0xb5, + 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x29, 0x86, 0x4b, 0x18, 0x45, 0xb4, 0xb8, 0x20, 0x3f, 0xaf, 0x38, + 0x55, 0xc8, 0x95, 0x8b, 0x0d, 0x62, 0xa1, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0xba, 0x1e, + 0x01, 0x0f, 0xe8, 0x41, 0x0c, 0x70, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0xd9, 0x68, + 0x31, 0x23, 0x17, 0x2b, 0xd8, 0x78, 0xa1, 0x99, 0x8c, 0x5c, 0x6c, 0x10, 0x25, 0x42, 0xc6, 0x04, + 0xcd, 0xc2, 0x74, 0xa7, 0x94, 0x09, 0x69, 0x9a, 0x20, 0xde, 0x50, 0x52, 0x69, 0xba, 0xfc, 0x64, + 0x32, 0x93, 0x9c, 0x90, 0x0c, 0xf6, 0x60, 0x85, 0xb8, 0xd2, 0x29, 0xe2, 0xc4, 0x23, 0x39, 0xc6, + 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, + 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xec, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, + 0x73, 0xf5, 0x5d, 0x21, 0xf6, 0xfb, 0xa5, 0x96, 0x94, 0xe7, 0x17, 0x65, 0xeb, 0xc3, 0xe2, 0xab, + 0x02, 0xbb, 0xd1, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0xa0, 0x37, 0x06, 0x04, 0x00, + 0x00, 0xff, 0xff, 0x29, 0x90, 0x68, 0x5f, 0x2c, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/exocore.appchain.coordinator.v1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/exocore.appchain.coordinator.v1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "exocore.appchain.coordinator.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "exocore/appchain/coordinator/v1/query.proto", +} + +func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/coordinator/types/query.pb.gw.go b/x/appchain/coordinator/types/query.pb.gw.go new file mode 100644 index 000000000..d113a2bb2 --- /dev/null +++ b/x/appchain/coordinator/types/query.pb.gw.go @@ -0,0 +1,153 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: exocore/appchain/coordinator/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"appchain", "coordinator", "params"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage +) diff --git a/x/appchain/coordinator/types/tx.pb.go b/x/appchain/coordinator/types/tx.pb.go new file mode 100644 index 000000000..9135b7536 --- /dev/null +++ b/x/appchain/coordinator/types/tx.pb.go @@ -0,0 +1,84 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/coordinator/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func init() { + proto.RegisterFile("exocore/appchain/coordinator/v1/tx.proto", fileDescriptor_23c4660f55e25cbc) +} + +var fileDescriptor_23c4660f55e25cbc = []byte{ + // 154 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x48, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, + 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, + 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x87, 0xaa, 0xd4, 0x83, 0xa9, 0xd4, 0x43, 0x52, 0xa9, 0x57, + 0x66, 0x68, 0xc4, 0xca, 0xc5, 0xec, 0x5b, 0x9c, 0xee, 0x14, 0x71, 0xe2, 0x91, 0x1c, 0xe3, 0x85, + 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, + 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x76, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, + 0xfa, 0xae, 0x10, 0xc3, 0xfc, 0x52, 0x4b, 0xca, 0xf3, 0x8b, 0xb2, 0xf5, 0x61, 0xae, 0xa8, 0xc0, + 0xee, 0x8e, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x43, 0x8c, 0x01, 0x01, 0x00, 0x00, + 0xff, 0xff, 0x5e, 0x8c, 0x36, 0x21, 0xb4, 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "exocore.appchain.coordinator.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "exocore/appchain/coordinator/v1/tx.proto", +} diff --git a/x/appchain/coordinator/types/types.go b/x/appchain/coordinator/types/types.go new file mode 100644 index 000000000..ab1254f4c --- /dev/null +++ b/x/appchain/coordinator/types/types.go @@ -0,0 +1 @@ +package types From 8ee12537742bca2ca0c100aaa3efafbc537fcf5a Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 25 Aug 2024 14:19:58 +0000 Subject: [PATCH 02/52] feat(appchain): scaffold subscriber --- .../appchain/subscriber/v1/genesis.proto | 14 + .../appchain/subscriber/v1/params.proto | 9 + .../appchain/subscriber/v1/query.proto | 24 + proto/exocore/appchain/subscriber/v1/tx.proto | 8 + x/appchain/subscriber/client/cli/query.go | 28 + x/appchain/subscriber/client/cli/tx.go | 26 + x/appchain/subscriber/keeper/abci.go | 12 + x/appchain/subscriber/keeper/genesis.go | 18 + x/appchain/subscriber/keeper/grpc_query.go | 25 + x/appchain/subscriber/keeper/keeper.go | 19 + x/appchain/subscriber/keeper/msg_server.go | 17 + x/appchain/subscriber/keeper/params.go | 25 + x/appchain/subscriber/module.go | 172 ++++++ x/appchain/subscriber/types/codec.go | 24 + x/appchain/subscriber/types/genesis.go | 21 + x/appchain/subscriber/types/genesis.pb.go | 325 +++++++++++ x/appchain/subscriber/types/keys.go | 30 + x/appchain/subscriber/types/params.go | 16 + x/appchain/subscriber/types/params.pb.go | 266 +++++++++ x/appchain/subscriber/types/query.pb.go | 533 ++++++++++++++++++ x/appchain/subscriber/types/query.pb.gw.go | 153 +++++ x/appchain/subscriber/types/tx.pb.go | 84 +++ x/appchain/subscriber/types/types.go | 1 + 23 files changed, 1850 insertions(+) create mode 100644 proto/exocore/appchain/subscriber/v1/genesis.proto create mode 100644 proto/exocore/appchain/subscriber/v1/params.proto create mode 100644 proto/exocore/appchain/subscriber/v1/query.proto create mode 100644 proto/exocore/appchain/subscriber/v1/tx.proto create mode 100644 x/appchain/subscriber/client/cli/query.go create mode 100644 x/appchain/subscriber/client/cli/tx.go create mode 100644 x/appchain/subscriber/keeper/abci.go create mode 100644 x/appchain/subscriber/keeper/genesis.go create mode 100644 x/appchain/subscriber/keeper/grpc_query.go create mode 100644 x/appchain/subscriber/keeper/keeper.go create mode 100644 x/appchain/subscriber/keeper/msg_server.go create mode 100644 x/appchain/subscriber/keeper/params.go create mode 100644 x/appchain/subscriber/module.go create mode 100644 x/appchain/subscriber/types/codec.go create mode 100644 x/appchain/subscriber/types/genesis.go create mode 100644 x/appchain/subscriber/types/genesis.pb.go create mode 100644 x/appchain/subscriber/types/keys.go create mode 100644 x/appchain/subscriber/types/params.go create mode 100644 x/appchain/subscriber/types/params.pb.go create mode 100644 x/appchain/subscriber/types/query.pb.go create mode 100644 x/appchain/subscriber/types/query.pb.gw.go create mode 100644 x/appchain/subscriber/types/tx.pb.go create mode 100644 x/appchain/subscriber/types/types.go diff --git a/proto/exocore/appchain/subscriber/v1/genesis.proto b/proto/exocore/appchain/subscriber/v1/genesis.proto new file mode 100644 index 000000000..10f84d55f --- /dev/null +++ b/proto/exocore/appchain/subscriber/v1/genesis.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package exocore.appchain.subscriber.v1; + +import "exocore/appchain/subscriber/v1/params.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; + +// GenesisState is the genesis state for the appchain subscriber module. +message GenesisState { + // Params is the parameters for the appchain subscriber module. + Params params = 1 [(gogoproto.nullable) = false]; +} diff --git a/proto/exocore/appchain/subscriber/v1/params.proto b/proto/exocore/appchain/subscriber/v1/params.proto new file mode 100644 index 000000000..1089ca0e8 --- /dev/null +++ b/proto/exocore/appchain/subscriber/v1/params.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package exocore.appchain.subscriber.v1; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; + +// Params is the parameters for the appchain subscriber module. +message Params { +} diff --git a/proto/exocore/appchain/subscriber/v1/query.proto b/proto/exocore/appchain/subscriber/v1/query.proto new file mode 100644 index 000000000..a45b4795c --- /dev/null +++ b/proto/exocore/appchain/subscriber/v1/query.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +package exocore.appchain.subscriber.v1; + +import "exocore/appchain/subscriber/v1/params.proto"; +import "google/api/annotations.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; + +// Query defines the gRPC querier service. +service Query { + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http) = { + get: "/appchain/subscriber/params" + }; + } +} + +message QueryParamsRequest {} + +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} \ No newline at end of file diff --git a/proto/exocore/appchain/subscriber/v1/tx.proto b/proto/exocore/appchain/subscriber/v1/tx.proto new file mode 100644 index 000000000..ead375b09 --- /dev/null +++ b/proto/exocore/appchain/subscriber/v1/tx.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +package exocore.appchain.subscriber.v1; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; + +// Msg defines the Msg service. +service Msg {} \ No newline at end of file diff --git a/x/appchain/subscriber/client/cli/query.go b/x/appchain/subscriber/client/cli/query.go new file mode 100644 index 000000000..f30834c68 --- /dev/null +++ b/x/appchain/subscriber/client/cli/query.go @@ -0,0 +1,28 @@ +package cli + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string) *cobra.Command { + // Group dogfood queries under a subcommand + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf( + "Querying commands for the %s module", + types.ModuleName, + ), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + return cmd +} diff --git a/x/appchain/subscriber/client/cli/tx.go b/x/appchain/subscriber/client/cli/tx.go new file mode 100644 index 000000000..fb8862638 --- /dev/null +++ b/x/appchain/subscriber/client/cli/tx.go @@ -0,0 +1,26 @@ +package cli + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + "github.com/cosmos/cosmos-sdk/client" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf( + "%s transactions subcommands", + types.ModuleName, + ), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + return cmd +} diff --git a/x/appchain/subscriber/keeper/abci.go b/x/appchain/subscriber/keeper/abci.go new file mode 100644 index 000000000..cbc3ac339 --- /dev/null +++ b/x/appchain/subscriber/keeper/abci.go @@ -0,0 +1,12 @@ +package keeper + +import ( + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) BeginBlock(sdk.Context) {} + +func (k Keeper) EndBlock(sdk.Context) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/appchain/subscriber/keeper/genesis.go b/x/appchain/subscriber/keeper/genesis.go new file mode 100644 index 000000000..3e353f09e --- /dev/null +++ b/x/appchain/subscriber/keeper/genesis.go @@ -0,0 +1,18 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) InitGenesis(ctx sdk.Context, gs types.GenesisState) []abci.ValidatorUpdate { + k.SetParams(ctx, gs.Params) + return []abci.ValidatorUpdate{} +} + +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + return &types.GenesisState{ + Params: k.GetParams(ctx), + } +} diff --git a/x/appchain/subscriber/keeper/grpc_query.go b/x/appchain/subscriber/keeper/grpc_query.go new file mode 100644 index 000000000..6f523fe13 --- /dev/null +++ b/x/appchain/subscriber/keeper/grpc_query.go @@ -0,0 +1,25 @@ +package keeper + +import ( + "context" + + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ types.QueryServer = Keeper{} + +func (k Keeper) Params( + goCtx context.Context, + req *types.QueryParamsRequest, +) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + + return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil +} diff --git a/x/appchain/subscriber/keeper/keeper.go b/x/appchain/subscriber/keeper/keeper.go new file mode 100644 index 000000000..9a73b1fba --- /dev/null +++ b/x/appchain/subscriber/keeper/keeper.go @@ -0,0 +1,19 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" +) + +type Keeper struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey +} + +// NewKeeper creates a new coordinator keeper. +func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey) Keeper { + return Keeper{ + cdc: cdc, + storeKey: storeKey, + } +} diff --git a/x/appchain/subscriber/keeper/msg_server.go b/x/appchain/subscriber/keeper/msg_server.go new file mode 100644 index 000000000..a5bdd5dd0 --- /dev/null +++ b/x/appchain/subscriber/keeper/msg_server.go @@ -0,0 +1,17 @@ +package keeper + +import "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + +// msgServer is a wrapper around the Keeper (which is the actual implementation) and +// satisfies the MsgServer interface. +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +// interface guard +var _ types.MsgServer = msgServer{} diff --git a/x/appchain/subscriber/keeper/params.go b/x/appchain/subscriber/keeper/params.go new file mode 100644 index 000000000..a16ced7aa --- /dev/null +++ b/x/appchain/subscriber/keeper/params.go @@ -0,0 +1,25 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SetParams sets the appchain coordinator parameters. +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(¶ms) + store.Set(types.ParamsKey(), bz) +} + +// GetParams gets the appchain coordinator parameters. +func (k Keeper) GetParams(ctx sdk.Context) types.Params { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ParamsKey()) + if bz == nil { + return types.DefaultParams() + } + var params types.Params + k.cdc.MustUnmarshal(bz, ¶ms) + return params +} diff --git a/x/appchain/subscriber/module.go b/x/appchain/subscriber/module.go new file mode 100644 index 000000000..ede8b7a0f --- /dev/null +++ b/x/appchain/subscriber/module.go @@ -0,0 +1,172 @@ +package dogfood + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/client/cli" + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/keeper" + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface that defines the independent methods a +// Cosmos SDK module needs to implement. +type AppModuleBasic struct { + cdc codec.BinaryCodec +} + +func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic { + return AppModuleBasic{cdc: cdc} +} + +// Name returns the name of the module as a string +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the amino codec for the module, which is used to marshal +// and unmarshal structs to/from []byte in order to persist them in the module's KVStore +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers a module's interface types and their concrete implementations as +// proto.Message +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns a default GenesisState for the module, marshaled to json.RawMessage. +// The default GenesisState need to be defined by the module developer and is primarily used for +// testing +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis used to validate the GenesisState, given in its json.RawMessage form +func (AppModuleBasic) ValidateGenesis( + cdc codec.JSONCodec, + _ client.TxEncodingConfig, + bz json.RawMessage, +) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module +func (AppModuleBasic) RegisterGRPCGatewayRoutes( + clientCtx client.Context, + mux *runtime.ServeMux, +) { + if err := types.RegisterQueryHandlerClient( + context.Background(), mux, types.NewQueryClient(clientCtx), + ); err != nil { + // this panic is safe to do because it means an error in setting up the module. + panic(err) + } +} + +// GetTxCmd returns the root Tx command for the module. The subcommands of this root command are +// used by end-users to generate new transactions containing messages defined in the module +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the root query command for the module. The subcommands of this root +// command are used by end-users to generate new queries to the subset of the state defined by +// the module +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd(types.StoreKey) +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface that defines the inter-dependent methods that +// modules need to implement +type AppModule struct { + AppModuleBasic + // keeper of the module receives the cdc codec separately. + keeper keeper.Keeper +} + +func NewAppModule( + cdc codec.Codec, + keeper keeper.Keeper, +) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + keeper: keeper, + } +} + +// RegisterServices registers a gRPC query service to respond to the module-specific gRPC +// queries +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// RegisterInvariants registers the invariants of the module. If an invariant deviates from its +// predicted value, the InvariantRegistry triggers appropriate logic (most often the chain will +// be halted) +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// InitGenesis performs the module's genesis initialization. It returns no validator updates. +func (am AppModule) InitGenesis( + ctx sdk.Context, + cdc codec.JSONCodec, + gs json.RawMessage, +) []abci.ValidatorUpdate { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(gs, &genState) + + return am.keeper.InitGenesis(ctx, genState) +} + +// ExportGenesis returns the module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(genState) +} + +// ConsensusVersion is a sequence number for state-breaking change of the module. It should be +// incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty +// versions, the initial version should be set to 1 +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// BeginBlock contains the logic that is automatically triggered at the beginning of each block +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + am.keeper.BeginBlock(ctx) +} + +// EndBlock contains the logic that is automatically triggered at the end of each block +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return am.keeper.EndBlock(ctx) +} diff --git a/x/appchain/subscriber/types/codec.go b/x/appchain/subscriber/types/codec.go new file mode 100644 index 000000000..8883bdf68 --- /dev/null +++ b/x/appchain/subscriber/types/codec.go @@ -0,0 +1,24 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + + // this line is used by starport scaffolding # 1 + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterCodec(cdc *codec.LegacyAmino) { + // this line is used by starport scaffolding # 2 +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + // this line is used by starport scaffolding # 3 + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + Amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) diff --git a/x/appchain/subscriber/types/genesis.go b/x/appchain/subscriber/types/genesis.go new file mode 100644 index 000000000..255e60642 --- /dev/null +++ b/x/appchain/subscriber/types/genesis.go @@ -0,0 +1,21 @@ +package types + +// DefaultGenesis returns the default genesis state. +func DefaultGenesis() *GenesisState { + return NewGenesis(DefaultParams()) +} + +// NewGenesis creates a new genesis state with the provided parameters and +// data. +func NewGenesis(params Params) *GenesisState { + return &GenesisState{Params: params} +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + return nil +} diff --git a/x/appchain/subscriber/types/genesis.pb.go b/x/appchain/subscriber/types/genesis.pb.go new file mode 100644 index 000000000..3acb96aaf --- /dev/null +++ b/x/appchain/subscriber/types/genesis.pb.go @@ -0,0 +1,325 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/subscriber/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState is the genesis state for the appchain subscriber module. +type GenesisState struct { + // Params is the parameters for the appchain subscriber module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_f608de439fd2c5db, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "exocore.appchain.subscriber.v1.GenesisState") +} + +func init() { + proto.RegisterFile("exocore/appchain/subscriber/v1/genesis.proto", fileDescriptor_f608de439fd2c5db) +} + +var fileDescriptor_f608de439fd2c5db = []byte{ + // 217 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x49, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x2e, 0x4d, + 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, + 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0xaa, 0xd6, 0x83, 0xa9, 0xd6, + 0x43, 0xa8, 0xd6, 0x2b, 0x33, 0x94, 0xd2, 0x26, 0x60, 0x5a, 0x41, 0x62, 0x51, 0x62, 0x2e, 0xd4, + 0x30, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0x30, 0x53, 0x1f, 0xc4, 0x82, 0x88, 0x2a, 0x85, 0x70, + 0xf1, 0xb8, 0x43, 0xec, 0x0c, 0x2e, 0x49, 0x2c, 0x49, 0x15, 0x72, 0xe1, 0x62, 0x83, 0xe8, 0x92, + 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, 0x52, 0xd3, 0xc3, 0xef, 0x06, 0xbd, 0x00, 0xb0, 0x6a, 0x27, + 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0x7a, 0x9d, 0xc2, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, + 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, + 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x36, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, + 0xdf, 0x15, 0x62, 0xb2, 0x5f, 0x6a, 0x49, 0x79, 0x7e, 0x51, 0xb6, 0x3e, 0xcc, 0x33, 0x15, 0x58, + 0xbd, 0x53, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x76, 0xb5, 0x31, 0x20, 0x00, 0x00, 0xff, + 0xff, 0xa2, 0xcb, 0xbe, 0x33, 0x48, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/subscriber/types/keys.go b/x/appchain/subscriber/types/keys.go new file mode 100644 index 000000000..e67ac4d65 --- /dev/null +++ b/x/appchain/subscriber/types/keys.go @@ -0,0 +1,30 @@ +package types + +const ( + // ModuleName defines the module name + ModuleName = "subscriber" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // RouterKey defines the module's message routing key + RouterKey = ModuleName + + // MemStoreKey defines the in-memory store key + MemStoreKey = "mem_subscriber" + + // PortID is the default port id that module binds to + PortID = "subscriber" + + SubscriberRedistributeName = "subscriber_redistribute" + + SubscriberToSendToCoordinatorName = "subscriber_to_send_to_coordinator" +) + +const ( + ParamsBytePrefix byte = iota + 1 +) + +func ParamsKey() []byte { + return []byte{ParamsBytePrefix} +} diff --git a/x/appchain/subscriber/types/params.go b/x/appchain/subscriber/types/params.go new file mode 100644 index 000000000..21722dc9b --- /dev/null +++ b/x/appchain/subscriber/types/params.go @@ -0,0 +1,16 @@ +package types + +// DefaultParams returns the default parameters for the module. +func DefaultParams() Params { + return Params{} +} + +// NewParams creates a new Params object +func NewParams() Params { + return Params{} +} + +// Validate checks that the parameters have valid values. +func (p Params) Validate() error { + return nil +} diff --git a/x/appchain/subscriber/types/params.pb.go b/x/appchain/subscriber/types/params.pb.go new file mode 100644 index 000000000..c2a6b3d10 --- /dev/null +++ b/x/appchain/subscriber/types/params.pb.go @@ -0,0 +1,266 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/subscriber/v1/params.proto + +package types + +import ( + fmt "fmt" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Params is the parameters for the appchain subscriber module. +type Params struct { +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_f35e5b6a0b1989b5, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Params)(nil), "exocore.appchain.subscriber.v1.Params") +} + +func init() { + proto.RegisterFile("exocore/appchain/subscriber/v1/params.proto", fileDescriptor_f35e5b6a0b1989b5) +} + +var fileDescriptor_f35e5b6a0b1989b5 = []byte{ + // 157 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x2e, 0x4d, + 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, + 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0x2a, 0xd6, 0x83, 0x29, 0xd6, 0x43, + 0x28, 0xd6, 0x2b, 0x33, 0x54, 0xe2, 0xe0, 0x62, 0x0b, 0x00, 0xab, 0x77, 0x0a, 0x3f, 0xf1, 0x48, + 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, + 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xdb, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, + 0xe4, 0xfc, 0x5c, 0x7d, 0x57, 0x88, 0x71, 0x7e, 0xa9, 0x25, 0xe5, 0xf9, 0x45, 0xd9, 0xfa, 0x30, + 0xa7, 0x54, 0x60, 0x75, 0x4c, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x25, 0xc6, 0x80, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0xcc, 0xe3, 0x34, 0xb8, 0x00, 0x00, 0x00, +} + +func (m *Params) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowParams + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/subscriber/types/query.pb.go b/x/appchain/subscriber/types/query.pb.go new file mode 100644 index 000000000..57f15a01f --- /dev/null +++ b/x/appchain/subscriber/types/query.pb.go @@ -0,0 +1,533 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/subscriber/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_351939062175e6f7, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +type QueryParamsResponse struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_351939062175e6f7, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "exocore.appchain.subscriber.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "exocore.appchain.subscriber.v1.QueryParamsResponse") +} + +func init() { + proto.RegisterFile("exocore/appchain/subscriber/v1/query.proto", fileDescriptor_351939062175e6f7) +} + +var fileDescriptor_351939062175e6f7 = []byte{ + // 298 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4a, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x2e, 0x4d, + 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, + 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0xaa, 0xd5, 0x83, 0xa9, 0xd5, 0x43, 0xa8, + 0xd5, 0x2b, 0x33, 0x94, 0xd2, 0x26, 0x60, 0x56, 0x41, 0x62, 0x51, 0x62, 0x6e, 0x31, 0xc4, 0x30, + 0x29, 0x99, 0xf4, 0xfc, 0xfc, 0xf4, 0x1c, 0x90, 0xda, 0x4c, 0xfd, 0xc4, 0xbc, 0xbc, 0xfc, 0x92, + 0xc4, 0x92, 0xcc, 0xfc, 0x3c, 0x98, 0xac, 0x48, 0x7a, 0x7e, 0x7a, 0x3e, 0x98, 0xa9, 0x0f, 0x62, + 0x41, 0x44, 0x95, 0x44, 0xb8, 0x84, 0x02, 0x41, 0xee, 0x09, 0x00, 0x1b, 0x14, 0x94, 0x5a, 0x58, + 0x9a, 0x5a, 0x5c, 0xa2, 0x14, 0xcd, 0x25, 0x8c, 0x22, 0x5a, 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x2a, + 0xe4, 0xc2, 0xc5, 0x06, 0xb1, 0x50, 0x82, 0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x4d, 0x0f, 0xbf, + 0xf3, 0xf5, 0x20, 0xfa, 0x9d, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x82, 0xea, 0x35, 0x5a, 0xc0, + 0xc8, 0xc5, 0x0a, 0x36, 0x5d, 0x68, 0x1a, 0x23, 0x17, 0x1b, 0x44, 0x89, 0x90, 0x11, 0x21, 0xa3, + 0x30, 0x5d, 0x29, 0x65, 0x4c, 0x92, 0x1e, 0x88, 0x1f, 0x94, 0x94, 0x9b, 0x2e, 0x3f, 0x99, 0xcc, + 0x24, 0x2b, 0x24, 0x8d, 0x35, 0x48, 0x21, 0x4e, 0x74, 0x0a, 0x3f, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, + 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, + 0xc6, 0x63, 0x39, 0x86, 0x28, 0xdb, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, + 0x7d, 0x57, 0x88, 0xed, 0x7e, 0xa9, 0x25, 0xe5, 0xf9, 0x45, 0xd9, 0xfa, 0xb0, 0xa8, 0xaa, 0xc0, + 0x6a, 0x72, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0xd4, 0x8d, 0x01, 0x01, 0x00, 0x00, + 0xff, 0xff, 0x7a, 0x5f, 0x4e, 0xf2, 0x24, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/exocore.appchain.subscriber.v1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/exocore.appchain.subscriber.v1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "exocore.appchain.subscriber.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "exocore/appchain/subscriber/v1/query.proto", +} + +func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/subscriber/types/query.pb.gw.go b/x/appchain/subscriber/types/query.pb.gw.go new file mode 100644 index 000000000..98be0e96a --- /dev/null +++ b/x/appchain/subscriber/types/query.pb.gw.go @@ -0,0 +1,153 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: exocore/appchain/subscriber/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"appchain", "subscriber", "params"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage +) diff --git a/x/appchain/subscriber/types/tx.pb.go b/x/appchain/subscriber/types/tx.pb.go new file mode 100644 index 000000000..ee98ebb3d --- /dev/null +++ b/x/appchain/subscriber/types/tx.pb.go @@ -0,0 +1,84 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/subscriber/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func init() { + proto.RegisterFile("exocore/appchain/subscriber/v1/tx.proto", fileDescriptor_42123d357df4763b) +} + +var fileDescriptor_42123d357df4763b = []byte{ + // 153 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4f, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x2e, 0x4d, + 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, + 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0x2a, 0xd4, 0x83, 0x29, 0xd4, 0x43, 0x28, 0xd4, 0x2b, 0x33, + 0x34, 0x62, 0xe5, 0x62, 0xf6, 0x2d, 0x4e, 0x77, 0x0a, 0x3f, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, + 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, + 0x63, 0x39, 0x86, 0x28, 0xdb, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, + 0x57, 0x88, 0x59, 0x7e, 0xa9, 0x25, 0xe5, 0xf9, 0x45, 0xd9, 0xfa, 0x30, 0x37, 0x54, 0x60, 0x75, + 0x45, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x19, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xc2, 0x1b, 0x1b, 0x11, 0xb1, 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "exocore.appchain.subscriber.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "exocore/appchain/subscriber/v1/tx.proto", +} diff --git a/x/appchain/subscriber/types/types.go b/x/appchain/subscriber/types/types.go new file mode 100644 index 000000000..ab1254f4c --- /dev/null +++ b/x/appchain/subscriber/types/types.go @@ -0,0 +1 @@ +package types From a1158d5a2564092f426cbccbb408bea74b8b6efe Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:44:13 +0000 Subject: [PATCH 03/52] feat(epochs): create number + id structure --- proto/exocore/epochs/v1/epochs.proto | 13 + x/epochs/types/epochs.go | 9 + x/epochs/types/epochs.pb.go | 354 +++++++++++++++++++++++++++ x/epochs/types/identifier.go | 20 ++ 4 files changed, 396 insertions(+) create mode 100644 proto/exocore/epochs/v1/epochs.proto create mode 100644 x/epochs/types/epochs.go create mode 100644 x/epochs/types/epochs.pb.go diff --git a/proto/exocore/epochs/v1/epochs.proto b/proto/exocore/epochs/v1/epochs.proto new file mode 100644 index 000000000..5598e699a --- /dev/null +++ b/proto/exocore/epochs/v1/epochs.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package exocore.epochs.v1; + +option go_package = "github.com/ExocoreNetwork/exocore/x/epochs/types"; + +// Epoch represents a specific epoch with its number and associated identifier. It is not used within this module; rather, it is designed by other modules to replace a time.Duration object. Modules are free to choose whether such a structure represents the beginning or the end of an epoch. +message Epoch { + // epoch_number is the sequential number of the epoch. + uint64 epoch_number = 1; + // epoch_identifier is a descriptive or unique identifier for the epoch (e.g., 'week', 'day', 'hour'). + string epoch_identifier = 2; +} \ No newline at end of file diff --git a/x/epochs/types/epochs.go b/x/epochs/types/epochs.go new file mode 100644 index 000000000..299e10ffc --- /dev/null +++ b/x/epochs/types/epochs.go @@ -0,0 +1,9 @@ +package types + +// NewEpoch creates a new Epoch instance. +func NewEpoch(number uint64, identifier string) Epoch { + return Epoch{ + EpochNumber: number, + EpochIdentifier: identifier, + } +} diff --git a/x/epochs/types/epochs.pb.go b/x/epochs/types/epochs.pb.go new file mode 100644 index 000000000..a65267937 --- /dev/null +++ b/x/epochs/types/epochs.pb.go @@ -0,0 +1,354 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/epochs/v1/epochs.proto + +package types + +import ( + fmt "fmt" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Epoch represents a specific epoch with its number and associated identifier. It is not used within this module; rather, it is designed by other modules to replace a time.Duration object. Modules are free to choose whether such a structure represents the beginning or the end of an epoch. +type Epoch struct { + // epoch_number is the sequential number of the epoch. + EpochNumber uint64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"` + // epoch_identifier is a descriptive or unique identifier for the epoch (e.g., 'week', 'day', 'hour'). + EpochIdentifier string `protobuf:"bytes,2,opt,name=epoch_identifier,json=epochIdentifier,proto3" json:"epoch_identifier,omitempty"` +} + +func (m *Epoch) Reset() { *m = Epoch{} } +func (m *Epoch) String() string { return proto.CompactTextString(m) } +func (*Epoch) ProtoMessage() {} +func (*Epoch) Descriptor() ([]byte, []int) { + return fileDescriptor_9e9e12bffa5727d0, []int{0} +} +func (m *Epoch) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Epoch) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Epoch.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Epoch) XXX_Merge(src proto.Message) { + xxx_messageInfo_Epoch.Merge(m, src) +} +func (m *Epoch) XXX_Size() int { + return m.Size() +} +func (m *Epoch) XXX_DiscardUnknown() { + xxx_messageInfo_Epoch.DiscardUnknown(m) +} + +var xxx_messageInfo_Epoch proto.InternalMessageInfo + +func (m *Epoch) GetEpochNumber() uint64 { + if m != nil { + return m.EpochNumber + } + return 0 +} + +func (m *Epoch) GetEpochIdentifier() string { + if m != nil { + return m.EpochIdentifier + } + return "" +} + +func init() { + proto.RegisterType((*Epoch)(nil), "exocore.epochs.v1.Epoch") +} + +func init() { proto.RegisterFile("exocore/epochs/v1/epochs.proto", fileDescriptor_9e9e12bffa5727d0) } + +var fileDescriptor_9e9e12bffa5727d0 = []byte{ + // 188 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2d, 0xc8, 0x4f, 0xce, 0x28, 0xd6, 0x2f, 0x33, 0x84, 0xb2, 0xf4, + 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x04, 0xa1, 0xf2, 0x7a, 0x50, 0xd1, 0x32, 0x43, 0xa5, 0x50, + 0x2e, 0x56, 0x57, 0x10, 0x47, 0x48, 0x91, 0x8b, 0x07, 0x2c, 0x1a, 0x9f, 0x57, 0x9a, 0x9b, 0x94, + 0x5a, 0x24, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x12, 0xc4, 0x0d, 0x16, 0xf3, 0x03, 0x0b, 0x09, 0x69, + 0x72, 0x09, 0x40, 0x94, 0x64, 0xa6, 0xa4, 0xe6, 0x95, 0x64, 0xa6, 0x65, 0xa6, 0x16, 0x49, 0x30, + 0x29, 0x30, 0x6a, 0x70, 0x06, 0xf1, 0x83, 0xc5, 0x3d, 0xe1, 0xc2, 0x4e, 0x5e, 0x27, 0x1e, 0xc9, + 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, + 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x65, 0x90, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, + 0x9c, 0x9f, 0xab, 0xef, 0x0a, 0x71, 0x8e, 0x5f, 0x6a, 0x49, 0x79, 0x7e, 0x51, 0xb6, 0x3e, 0xcc, + 0xf5, 0x15, 0x30, 0xf7, 0x97, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x1d, 0x6f, 0x0c, 0x08, + 0x00, 0x00, 0xff, 0xff, 0xdd, 0x52, 0x0b, 0x1d, 0xde, 0x00, 0x00, 0x00, +} + +func (m *Epoch) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Epoch) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Epoch) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.EpochIdentifier) > 0 { + i -= len(m.EpochIdentifier) + copy(dAtA[i:], m.EpochIdentifier) + i = encodeVarintEpochs(dAtA, i, uint64(len(m.EpochIdentifier))) + i-- + dAtA[i] = 0x12 + } + if m.EpochNumber != 0 { + i = encodeVarintEpochs(dAtA, i, uint64(m.EpochNumber)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintEpochs(dAtA []byte, offset int, v uint64) int { + offset -= sovEpochs(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Epoch) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochNumber != 0 { + n += 1 + sovEpochs(uint64(m.EpochNumber)) + } + l = len(m.EpochIdentifier) + if l > 0 { + n += 1 + l + sovEpochs(uint64(l)) + } + return n +} + +func sovEpochs(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozEpochs(x uint64) (n int) { + return sovEpochs(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Epoch) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEpochs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Epoch: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Epoch: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType) + } + m.EpochNumber = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEpochs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNumber |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEpochs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEpochs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEpochs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EpochIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEpochs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEpochs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipEpochs(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEpochs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEpochs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEpochs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthEpochs + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupEpochs + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthEpochs + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthEpochs = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowEpochs = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupEpochs = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/epochs/types/identifier.go b/x/epochs/types/identifier.go index 1c8f85d45..d68f85675 100644 --- a/x/epochs/types/identifier.go +++ b/x/epochs/types/identifier.go @@ -41,3 +41,23 @@ func ValidateEpochIdentifierString(s string) error { } return nil } + +// ValidateEpoch accepts an Epoch and validates it. The validation performed is that the epoch identifier string is valid, and that the epoch number (uint64) is not zero. +func ValidateEpoch(epoch Epoch) error { + if err := ValidateEpochIdentifierString(epoch.EpochIdentifier); err != nil { + return err + } + if epoch.EpochNumber == 0 { + return fmt.Errorf("epoch number cannot be zero") + } + return nil +} + +// ValidateEpochInterface accepts an interface and validates it as an Epoch. +func ValidateEpochInterface(i interface{}) error { + v, ok := i.(Epoch) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + return ValidateEpoch(v) +} From 7c1922a52621fb6998b96be44369fec406c1cdd4 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:45:26 +0000 Subject: [PATCH 04/52] feat(appchain): add coordinator params --- proto/buf.lock | 18 +- proto/buf.yaml | 2 + .../appchain/coordinator/v1/params.proto | 19 ++ x/appchain/common/types/params.go | 8 + x/appchain/common/types/shared_params.go | 54 +++ x/appchain/coordinator/types/params.go | 108 +++++- x/appchain/coordinator/types/params.pb.go | 320 +++++++++++++++++- x/appchain/coordinator/types/params_test.go | 142 ++++++++ 8 files changed, 653 insertions(+), 18 deletions(-) create mode 100644 x/appchain/common/types/params.go create mode 100644 x/appchain/common/types/shared_params.go create mode 100644 x/appchain/coordinator/types/params_test.go diff --git a/proto/buf.lock b/proto/buf.lock index d025fc2f3..da8729af2 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -4,8 +4,8 @@ deps: - remote: buf.build owner: cosmos repository: cosmos-proto - commit: 1935555c206d4afb9e94615dfd0fad31 - digest: shake256:c74d91a3ac7ae07d579e90eee33abf9b29664047ac8816500cf22c081fec0d72d62c89ce0bebafc1f6fec7aa5315be72606717740ca95007248425102c365377 + commit: 04467658e59e44bbb22fe568206e1f70 + digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466 - remote: buf.build owner: cosmos repository: cosmos-sdk @@ -16,8 +16,18 @@ deps: repository: gogo-proto commit: 88ef6483f90f478fb938c37dde52ece3 digest: shake256:89c45df2aa11e0cff97b0d695436713db3d993d76792e9f8dc1ae90e6ab9a9bec55503d48ceedd6b86069ab07d3041b32001b2bfe0227fa725dd515ff381e5ba + - remote: buf.build + owner: cosmos + repository: ibc + commit: fbb44f5ad3194450af479a615fa715d9 + digest: shake256:3fbf41c96089017ebf3b5143f78de0d531f604cb11da1bc98b2104eb6dd295b8a49f5f35c60b8389ba50bfa08959da905109324099e75ece9afd8e4087b14019 + - remote: buf.build + owner: cosmos + repository: ics23 + commit: 55085f7c710a45f58fa09947208eb70b + digest: shake256:9bf0bc495b5a11c88d163d39ef521bc4b00bc1374a05758c91d82821bdc61f09e8c2c51dda8452529bf80137f34d852561eacbe9550a59015d51cecb0dacb628 - remote: buf.build owner: googleapis repository: googleapis - commit: e874a0be2bf140a5a4c7d4122c635823 - digest: shake256:4fe3036b4d706f6ee2b13c730bd04777f021dfd02ed27e6e40480acfe664a7548238312ee0727fd77648a38d227e296d43f4a38a34cdd46068156211016d9657 + commit: 8bc2c51e08c447cd8886cdea48a73e14 + digest: shake256:a969155953a5cedc5b2df5b42c368f2bc66ff8ce1804bc96e0f14ff2ee8a893687963058909df844d1643cdbc98ff099d2daa6bc9f9f5b8886c49afdc60e19af diff --git a/proto/buf.yaml b/proto/buf.yaml index 00eff3659..8a0ff17a3 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -2,8 +2,10 @@ version: v1 name: buf.build/evmos/evmos deps: - buf.build/cosmos/cosmos-sdk:v0.47.0 + - buf.build/cosmos/ibc:fbb44f5ad3194450af479a615fa715d9 - buf.build/cosmos/cosmos-proto - buf.build/cosmos/gogo-proto + - buf.build/cosmos/ics23:b1abd8678aab07165efd453c96796a179eb3131f - buf.build/googleapis/googleapis lint: use: diff --git a/proto/exocore/appchain/coordinator/v1/params.proto b/proto/exocore/appchain/coordinator/v1/params.proto index 71ada75e3..ba68f5373 100644 --- a/proto/exocore/appchain/coordinator/v1/params.proto +++ b/proto/exocore/appchain/coordinator/v1/params.proto @@ -2,8 +2,27 @@ syntax = "proto3"; package exocore.appchain.coordinator.v1; +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; +import "ibc/lightclients/tendermint/v1/tendermint.proto"; +import "exocore/epochs/v1/epochs.proto"; + option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; // Params is the parameters for the appchain coordinator module. message Params { + // template_client is the IBC template client. + ibc.lightclients.tendermint.v1.ClientState template_client = 1; + // trusting_period_fraction is the multiplier applied on the subscriber's unbonding duration to determine the IBC trusting period. + string trusting_period_fraction = 2; + // ibc_timeout_period is the timeout period for IBC packets. While our system is largely created with epochs as a unit of time (and not standard durations), this is an exception since it is used directly by the IBC codebase. + google.protobuf.Duration ibc_timeout_period = 3 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.customname) = "IBCTimeoutPeriod" ]; + // init_timeout_period is the period within which the subscriber chain must make a connection with the coordinator, after being spawned. + exocore.epochs.v1.Epoch init_timeout_period = 4 + [ (gogoproto.nullable) = false ]; + // vsc_timeout_period is the period within which the subscriber chain must respond to a VSC request, after it is sent. + exocore.epochs.v1.Epoch vsc_timeout_period = 5 + [ (gogoproto.nullable) = false, (gogoproto.customname) = "VSCTimeoutPeriod" ]; + // TODO: slashing and reward related parameters } diff --git a/x/appchain/common/types/params.go b/x/appchain/common/types/params.go new file mode 100644 index 000000000..88fb13fd4 --- /dev/null +++ b/x/appchain/common/types/params.go @@ -0,0 +1,8 @@ +package types + +import "time" + +const ( + // Within the dogfood module, the default unbonding duration is 7 epochs, where 1 epoch = 1 day. This means a maximum of 8 days to unbond. We go lower than that here. + DefaultSubscriberUnbondingPeriod = 24 * 7 * time.Hour +) diff --git a/x/appchain/common/types/shared_params.go b/x/appchain/common/types/shared_params.go new file mode 100644 index 000000000..789bc9369 --- /dev/null +++ b/x/appchain/common/types/shared_params.go @@ -0,0 +1,54 @@ +package types + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + // DefaultIBCTimeoutPeriod is the default timeout period for IBC packets. + DefaultIBCTimeoutPeriod = 4 * 7 * 24 * time.Hour +) + +// CalculateTrustPeriod calculates the trust period as the unbonding period multiplied by the trust period fraction, truncated to an integer. +func CalculateTrustPeriod(unbondingPeriod time.Duration, trustPeriodFraction string) (time.Duration, error) { + trustDec, err := sdk.NewDecFromStr(trustPeriodFraction) + if err != nil { + return time.Duration(0), err + } + trustPeriod := time.Duration(trustDec.MulInt64(unbondingPeriod.Nanoseconds()).TruncateInt64()) + return trustPeriod, nil +} + +// ValidateStringFraction validates that the given string is a valid fraction in the range [0, 1]. +func ValidateStringFraction(i interface{}) error { + str, ok := i.(string) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + dec, err := sdk.NewDecFromStr(str) + if err != nil { + return err + } + if dec.IsNegative() { + return fmt.Errorf("param cannot be negative, got %s", str) + } + if dec.Sub(sdk.NewDec(1)).IsPositive() { + return fmt.Errorf("param cannot be greater than 1, got %s", str) + } + return nil +} + +// ValidateDuration validates that the given duration is positive. +func ValidateDuration(i interface{}) error { + period, ok := i.(time.Duration) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if period <= time.Duration(0) { + return fmt.Errorf("duration must be positive") + } + return nil +} diff --git a/x/appchain/coordinator/types/params.go b/x/appchain/coordinator/types/params.go index 21722dc9b..48b13c860 100644 --- a/x/appchain/coordinator/types/params.go +++ b/x/appchain/coordinator/types/params.go @@ -1,16 +1,118 @@ package types +import ( + fmt "fmt" + time "time" + + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" +) + +const ( + // DefaultTrustingPeriodFraction is the default fraction used to compure the TrustingPeriod as the UnbondingPeriod (of the subcriber chain) * TrustingPeriodFraction. + DefaultTrustingPeriodFraction = "0.66" + + // DefaultIBCTimeoutPeriod is defined in common/types/shared_params.go +) + +var ( + // DefaultInitTimeoutPeriod is the default timeout period for the initial connection handshake. To estimate a time of 1 week, we use a 7-day duration, but add one day for rounding it up. For example, if a message is sent out in the middle of epoch N, it should ideally timeout exactly 7 days after that, which is the middle of epoch N+7. Since we don't track that, we instead use 8 days. + // A value of 2 weeks was chosen here to ensure that the chain is dropped if it doesn't initialize a connection within a reasonable time frame. + DefaultInitTimeoutPeriod = epochstypes.NewEpoch(2, "week") + + // DefaultVSCTimeoutPeriod is the default timeout period for the validator set change packet acknowledgment. + // If a chain goes offline, we will not receive any such packets. To that end, a longer period than the initialization time is chosen for the chain to recover. If it does not recover within this time frame, it will be dropped. + // The duration is, however, intentionally not kept too permissive. + DefaultVSCTimeoutPeriod = epochstypes.NewEpoch(4, "week") +) + // DefaultParams returns the default parameters for the module. func DefaultParams() Params { - return Params{} + return NewParams( + ibctmtypes.NewClientState( + "", // chainID + ibctmtypes.DefaultTrustLevel, + 0, // trusting period + 0, // unbonding period + 10*time.Second, // replaced later so irrelevant + clienttypes.Height{}, // latest(initial) height + commitmenttypes.GetSDKSpecs(), + []string{"upgrade", "upgradedIBCState"}, + ), + DefaultTrustingPeriodFraction, + commontypes.DefaultIBCTimeoutPeriod, + DefaultInitTimeoutPeriod, + DefaultVSCTimeoutPeriod, + ) } // NewParams creates a new Params object -func NewParams() Params { - return Params{} +func NewParams( + cs *ibctmtypes.ClientState, + trustingPeriodFraction string, + ibcTimeoutPeriod time.Duration, + initTimeoutPeriod epochstypes.Epoch, + vscTimeoutPeriod epochstypes.Epoch, +) Params { + return Params{ + TemplateClient: cs, + TrustingPeriodFraction: trustingPeriodFraction, + IBCTimeoutPeriod: ibcTimeoutPeriod, + InitTimeoutPeriod: initTimeoutPeriod, + VSCTimeoutPeriod: vscTimeoutPeriod, + } } // Validate checks that the parameters have valid values. func (p Params) Validate() error { + if p.TemplateClient == nil { + return fmt.Errorf("template client is nil") + } + if err := ValidateTemplateClient(*p.TemplateClient); err != nil { + return err + } + if err := commontypes.ValidateStringFraction(p.TrustingPeriodFraction); err != nil { + return fmt.Errorf("trusting period fraction is invalid: %s", err) + } + if err := commontypes.ValidateDuration(p.IBCTimeoutPeriod); err != nil { + return fmt.Errorf("IBC timeout period is invalid: %s", err) + } + if err := epochstypes.ValidateEpoch(p.InitTimeoutPeriod); err != nil { + return fmt.Errorf("init timeout period is invalid: %s", err) + } + if err := epochstypes.ValidateEpoch(p.VSCTimeoutPeriod); err != nil { + return fmt.Errorf("VSC timeout period is invalid: %s", err) + } + return nil +} + +// ValidateTemplateClient validates the client state +func ValidateTemplateClient(i interface{}) error { + cs, ok := i.(ibctmtypes.ClientState) + if !ok { + return fmt.Errorf("invalid parameter type: %T, expected: %T", i, ibctmtypes.ClientState{}) + } + + // copy clientstate to prevent changing original pointer + copiedClient := cs + + // populate zeroed fields with valid fields + copiedClient.ChainId = "chainid" + + trustPeriod, err := commontypes.CalculateTrustPeriod(commontypes.DefaultSubscriberUnbondingPeriod, DefaultTrustingPeriodFraction) + if err != nil { + return fmt.Errorf("invalid DefaultTrustingPeriodFraction: %T", err) + } + copiedClient.TrustingPeriod = trustPeriod + + copiedClient.UnbondingPeriod = commontypes.DefaultSubscriberUnbondingPeriod + copiedClient.LatestHeight = clienttypes.NewHeight(0, 1) + + if err := copiedClient.Validate(); err != nil { + return err + } return nil } diff --git a/x/appchain/coordinator/types/params.pb.go b/x/appchain/coordinator/types/params.pb.go index 34b6e2c73..6f64ea43e 100644 --- a/x/appchain/coordinator/types/params.pb.go +++ b/x/appchain/coordinator/types/params.pb.go @@ -5,16 +5,23 @@ package types import ( fmt "fmt" + types "github.com/ExocoreNetwork/exocore/x/epochs/types" + _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + _ "google.golang.org/protobuf/types/known/durationpb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -24,6 +31,16 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params is the parameters for the appchain coordinator module. type Params struct { + // template_client is the IBC template client. + TemplateClient *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=template_client,json=templateClient,proto3" json:"template_client,omitempty"` + // trusting_period_fraction is the multiplier applied on the subscriber's unbonding duration to determine the IBC trusting period. + TrustingPeriodFraction string `protobuf:"bytes,2,opt,name=trusting_period_fraction,json=trustingPeriodFraction,proto3" json:"trusting_period_fraction,omitempty"` + // ibc_timeout_period is the timeout period for IBC packets. While our system is largely created with epochs as a unit of time (and not standard durations), this is an exception since it is used directly by the IBC codebase. + IBCTimeoutPeriod time.Duration `protobuf:"bytes,3,opt,name=ibc_timeout_period,json=ibcTimeoutPeriod,proto3,stdduration" json:"ibc_timeout_period"` + // init_timeout_period is the period within which the subscriber chain must make a connection with the coordinator, after being spawned. + InitTimeoutPeriod types.Epoch `protobuf:"bytes,4,opt,name=init_timeout_period,json=initTimeoutPeriod,proto3" json:"init_timeout_period"` + // vsc_timeout_period is the period within which the subscriber chain must respond to a VSC request, after it is sent. + VSCTimeoutPeriod types.Epoch `protobuf:"bytes,5,opt,name=vsc_timeout_period,json=vscTimeoutPeriod,proto3" json:"vsc_timeout_period"` } func (m *Params) Reset() { *m = Params{} } @@ -59,6 +76,41 @@ func (m *Params) XXX_DiscardUnknown() { var xxx_messageInfo_Params proto.InternalMessageInfo +func (m *Params) GetTemplateClient() *_07_tendermint.ClientState { + if m != nil { + return m.TemplateClient + } + return nil +} + +func (m *Params) GetTrustingPeriodFraction() string { + if m != nil { + return m.TrustingPeriodFraction + } + return "" +} + +func (m *Params) GetIBCTimeoutPeriod() time.Duration { + if m != nil { + return m.IBCTimeoutPeriod + } + return 0 +} + +func (m *Params) GetInitTimeoutPeriod() types.Epoch { + if m != nil { + return m.InitTimeoutPeriod + } + return types.Epoch{} +} + +func (m *Params) GetVSCTimeoutPeriod() types.Epoch { + if m != nil { + return m.VSCTimeoutPeriod + } + return types.Epoch{} +} + func init() { proto.RegisterType((*Params)(nil), "exocore.appchain.coordinator.v1.Params") } @@ -68,17 +120,35 @@ func init() { } var fileDescriptor_153952e3bb2d49c4 = []byte{ - // 158 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x49, 0xad, 0xc8, 0x4f, - 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, - 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, - 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x87, 0xaa, 0xd6, 0x83, 0xa9, 0xd6, - 0x43, 0x52, 0xad, 0x57, 0x66, 0xa8, 0xc4, 0xc1, 0xc5, 0x16, 0x00, 0xd6, 0xe0, 0x14, 0x71, 0xe2, - 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, - 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x76, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, - 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xae, 0x10, 0xf3, 0xfc, 0x52, 0x4b, 0xca, 0xf3, 0x8b, 0xb2, 0xf5, - 0x61, 0x8e, 0xa9, 0xc0, 0xee, 0x9c, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x5b, 0x8c, - 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x46, 0x85, 0x8c, 0x39, 0xbb, 0x00, 0x00, 0x00, + // 438 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0xc1, 0x6e, 0xd4, 0x30, + 0x14, 0xdc, 0xd0, 0x52, 0x89, 0x20, 0xc1, 0x12, 0x10, 0x0a, 0x15, 0xca, 0x56, 0x9c, 0x2a, 0x81, + 0x6c, 0x2d, 0x5c, 0x38, 0x71, 0xd8, 0x52, 0x24, 0x2e, 0x55, 0x95, 0x56, 0x08, 0x71, 0x59, 0x1c, + 0xaf, 0x9b, 0x7d, 0x62, 0xe3, 0x67, 0x39, 0x2f, 0xa1, 0xfc, 0x05, 0x47, 0x7e, 0x83, 0xbf, 0xe8, + 0xb1, 0x47, 0x4e, 0x05, 0xed, 0xfe, 0x08, 0x8a, 0x1d, 0x8b, 0x5d, 0x40, 0xea, 0xcd, 0x7e, 0x33, + 0x6f, 0x66, 0x32, 0x71, 0xfc, 0x4c, 0x9d, 0xa3, 0x44, 0xab, 0xb8, 0x30, 0x46, 0xce, 0x05, 0x68, + 0x2e, 0x11, 0xed, 0x0c, 0xb4, 0x20, 0xb4, 0xbc, 0x1d, 0x73, 0x23, 0xac, 0xa8, 0x6a, 0x66, 0x2c, + 0x12, 0x26, 0xa3, 0x9e, 0xcd, 0x02, 0x9b, 0xad, 0xb1, 0x59, 0x3b, 0xde, 0x7d, 0x50, 0x62, 0x89, + 0x8e, 0xcb, 0xbb, 0x93, 0x5f, 0xdb, 0xcd, 0x4a, 0xc4, 0x72, 0xa1, 0xb8, 0xbb, 0x15, 0xcd, 0x19, + 0x9f, 0x35, 0x56, 0x10, 0xa0, 0xee, 0x71, 0x0e, 0x85, 0xe4, 0x0b, 0x28, 0xe7, 0x24, 0x17, 0xa0, + 0x34, 0xd5, 0x9c, 0x94, 0x9e, 0x29, 0x5b, 0x81, 0xa6, 0x2e, 0xc3, 0x9f, 0x5b, 0x10, 0x0c, 0xa9, + 0x95, 0x41, 0x39, 0xaf, 0x3b, 0x8e, 0x3f, 0x79, 0xfc, 0xc9, 0xf7, 0xad, 0x78, 0xe7, 0xd8, 0x05, + 0x4f, 0x4e, 0xe3, 0xbb, 0xa4, 0x2a, 0xb3, 0x10, 0xa4, 0xa6, 0x5e, 0x3d, 0x8d, 0xf6, 0xa2, 0xfd, + 0xdb, 0xcf, 0x9f, 0x32, 0x28, 0x24, 0x5b, 0x77, 0x65, 0x6b, 0x3e, 0xed, 0x98, 0x1d, 0xb8, 0xe9, + 0x09, 0x09, 0x52, 0xf9, 0x9d, 0xa0, 0xe1, 0x87, 0xc9, 0xcb, 0x38, 0x25, 0xdb, 0xd4, 0x04, 0xba, + 0x9c, 0x1a, 0x65, 0x01, 0x67, 0xd3, 0x33, 0x2b, 0x64, 0xf7, 0x4d, 0xe9, 0x8d, 0xbd, 0x68, 0xff, + 0x56, 0xfe, 0x30, 0xe0, 0xc7, 0x0e, 0x7e, 0xd3, 0xa3, 0x89, 0x8a, 0x13, 0x28, 0xe4, 0x94, 0xa0, + 0x52, 0xd8, 0x50, 0xbf, 0x9c, 0x6e, 0xb9, 0x48, 0x8f, 0x98, 0x2f, 0x8a, 0x85, 0xa2, 0xd8, 0xeb, + 0xbe, 0xa8, 0xc9, 0xe3, 0x8b, 0xab, 0xd1, 0x60, 0x79, 0x35, 0x1a, 0xbe, 0x9d, 0x1c, 0x9c, 0xfa, + 0x5d, 0x2f, 0xfc, 0xed, 0xe7, 0x28, 0xca, 0x87, 0x50, 0xc8, 0x8d, 0x69, 0x72, 0x14, 0xdf, 0x07, + 0x0d, 0xf4, 0xb7, 0xcf, 0xb6, 0xf3, 0x49, 0x59, 0xf8, 0x8f, 0x7d, 0x6b, 0xed, 0x98, 0x1d, 0x76, + 0xa7, 0xc9, 0x76, 0x67, 0x93, 0xdf, 0xeb, 0x56, 0x37, 0xf5, 0x3e, 0xc6, 0x49, 0x5b, 0xff, 0x13, + 0xfb, 0xe6, 0x35, 0x72, 0x69, 0x48, 0xfd, 0xee, 0x64, 0x33, 0x75, 0x3e, 0x6c, 0xeb, 0xcd, 0xc4, + 0x93, 0xf7, 0x17, 0xcb, 0x2c, 0xba, 0x5c, 0x66, 0xd1, 0xaf, 0x65, 0x16, 0x7d, 0x5d, 0x65, 0x83, + 0xcb, 0x55, 0x36, 0xf8, 0xb1, 0xca, 0x06, 0x1f, 0x5e, 0x95, 0x40, 0xf3, 0xa6, 0x60, 0x12, 0x2b, + 0x7e, 0xe8, 0x9d, 0x8e, 0x14, 0x7d, 0x46, 0xfb, 0x89, 0x87, 0x77, 0x70, 0xfe, 0xff, 0xf7, 0x4b, + 0x5f, 0x8c, 0xaa, 0x8b, 0x1d, 0x57, 0xe7, 0x8b, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb0, 0xa3, + 0x9c, 0xaa, 0xec, 0x02, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -101,6 +171,53 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.VSCTimeoutPeriod.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size, err := m.InitTimeoutPeriod.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + n3, err3 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.IBCTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.IBCTimeoutPeriod):]) + if err3 != nil { + return 0, err3 + } + i -= n3 + i = encodeVarintParams(dAtA, i, uint64(n3)) + i-- + dAtA[i] = 0x1a + if len(m.TrustingPeriodFraction) > 0 { + i -= len(m.TrustingPeriodFraction) + copy(dAtA[i:], m.TrustingPeriodFraction) + i = encodeVarintParams(dAtA, i, uint64(len(m.TrustingPeriodFraction))) + i-- + dAtA[i] = 0x12 + } + if m.TemplateClient != nil { + { + size, err := m.TemplateClient.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -121,6 +238,20 @@ func (m *Params) Size() (n int) { } var l int _ = l + if m.TemplateClient != nil { + l = m.TemplateClient.Size() + n += 1 + l + sovParams(uint64(l)) + } + l = len(m.TrustingPeriodFraction) + if l > 0 { + n += 1 + l + sovParams(uint64(l)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.IBCTimeoutPeriod) + n += 1 + l + sovParams(uint64(l)) + l = m.InitTimeoutPeriod.Size() + n += 1 + l + sovParams(uint64(l)) + l = m.VSCTimeoutPeriod.Size() + n += 1 + l + sovParams(uint64(l)) return n } @@ -159,6 +290,173 @@ func (m *Params) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TemplateClient", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TemplateClient == nil { + m.TemplateClient = &_07_tendermint.ClientState{} + } + if err := m.TemplateClient.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TrustingPeriodFraction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TrustingPeriodFraction = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IBCTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.IBCTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.InitTimeoutPeriod.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VSCTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.VSCTimeoutPeriod.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/appchain/coordinator/types/params_test.go b/x/appchain/coordinator/types/params_test.go new file mode 100644 index 000000000..526600d05 --- /dev/null +++ b/x/appchain/coordinator/types/params_test.go @@ -0,0 +1,142 @@ +package types_test + +import ( + "strings" + "testing" + time "time" + + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + "github.com/stretchr/testify/require" +) + +func TestValidate(t *testing.T) { + cases := []struct { + name string + params types.Params + expResult bool + expError string + malleate func(params *types.Params) + }{ + { + name: "default params", + params: types.DefaultParams(), + expResult: true, + }, + { + name: "nil client", + params: types.DefaultParams(), + malleate: func(params *types.Params) { + params.TemplateClient = nil + }, + expResult: false, + expError: "template client is nil", + }, + { + name: "invalid client", + params: types.DefaultParams(), + malleate: func(params *types.Params) { + params.TemplateClient.UpgradePath = []string{ + "", // empty string is invalid + } + }, + expResult: false, + expError: "key in upgrade path at index 0 cannot be empty", + }, + { + name: "invalid trust period fraction", + params: types.DefaultParams(), + malleate: func(params *types.Params) { + params.TrustingPeriodFraction = "1.5" + }, + expResult: false, + expError: "trusting period fraction is invalid", + }, + { + name: "invalid IBC timeout duration", + params: types.DefaultParams(), + malleate: func(params *types.Params) { + params.IBCTimeoutPeriod = time.Duration(-1) + }, + expResult: false, + expError: "IBC timeout period is invalid", + }, + { + name: "invalid init timeout period", + params: types.DefaultParams(), + malleate: func(params *types.Params) { + params.InitTimeoutPeriod = epochstypes.NewEpoch(0, "week") + }, + expResult: false, + expError: "init timeout period is invalid", + }, + { + name: "invalid BSC timeout period", + params: types.DefaultParams(), + malleate: func(params *types.Params) { + params.VSCTimeoutPeriod = epochstypes.NewEpoch(0, "week") + }, + expResult: false, + expError: "VSC timeout period is invalid", + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + if tc.malleate != nil { + tc.malleate(&tc.params) + } + // first, validate the test case itself + if tc.expResult && tc.expError != "" { + t.Fatal("invalid test case: expected success but got error") + } else if !tc.expResult && tc.expError == "" { + t.Fatal("invalid test case: expected error but got success") + } + // then run the test case + err := tc.params.Validate() + if tc.expResult && err != nil { + t.Fatalf("expected no error, got %s", err) + } + if !tc.expResult { + if err == nil { + t.Fatal("expected error, got none") + } else { + if !strings.Contains(err.Error(), tc.expError) { + t.Fatalf("expected error %q, got %q", tc.expError, err.Error()) + } + } + } + }) + } +} + +func TestInvalidParams(t *testing.T) { + // Example of an invalid Init Timeout Period (0 epochs) + params := types.Params{ + InitTimeoutPeriod: epochstypes.NewEpoch(0, "week"), + } + err := params.Validate() + require.Error(t, err, "Params with 0 epoch InitTimeoutPeriod should return an error") + + // Invalid Trusting Period Fraction (>1) + params = types.Params{ + TrustingPeriodFraction: "1.5", + } + err = params.Validate() + require.Error(t, err, "Params with TrustingPeriodFraction > 1 should return an error") +} + +func TestEdgeCaseParams(t *testing.T) { + // Edge case with a very large number of epochs + params := types.Params{ + InitTimeoutPeriod: epochstypes.NewEpoch(1<<62, "week"), + } + err := params.Validate() + require.NoError(t, err, "Params with a very large number of epochs should still be valid") + + // Trusting Period Fraction equal to 1 + params = types.Params{ + TrustingPeriodFraction: "1.0", + } + err = params.Validate() + require.NoError(t, err, "Params with TrustingPeriodFraction equal to 1 should be valid") +} From f1bca4dcedc449ac2b79deb599da9af7a217f8f8 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:21:41 +0000 Subject: [PATCH 05/52] fix(epochs): invalidate negative duration --- x/epochs/types/genesis.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/epochs/types/genesis.go b/x/epochs/types/genesis.go index ec14eefa3..f23053232 100644 --- a/x/epochs/types/genesis.go +++ b/x/epochs/types/genesis.go @@ -45,8 +45,8 @@ func (epoch EpochInfo) Validate() error { if epoch.Identifier == "" { return errors.New("epoch identifier should NOT be empty") } - if epoch.Duration == 0 { - return errors.New("epoch duration should NOT be 0") + if epoch.Duration <= 0 { + return errors.New("epoch duration should NOT be non-positive") } if epoch.CurrentEpoch < 0 { return errors.New("epoch CurrentEpoch must be non-negative") From 9f9e994d8695ca56a717e085f90906016133a82b Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:22:16 +0000 Subject: [PATCH 06/52] fix(avs): stateful validation of staking assets --- x/avs/keeper/keeper.go | 15 +++++++++++++++ x/avs/types/errors.go | 4 ++++ x/avs/types/expected_keepers.go | 1 + 3 files changed, 20 insertions(+) diff --git a/x/avs/keeper/keeper.go b/x/avs/keeper/keeper.go index 9f4a549ff..81f87eb1d 100644 --- a/x/avs/keeper/keeper.go +++ b/x/avs/keeper/keeper.go @@ -57,6 +57,15 @@ func (k Keeper) GetOperatorKeeper() types.OperatorKeeper { return k.operatorKeeper } +func (k Keeper) ValidateAssetIDs(ctx sdk.Context, assetIDs []string) error { + for _, assetID := range assetIDs { + if !k.assetsKeeper.IsStakingAsset(ctx, assetID) { + return errorsmod.Wrap(types.ErrInvalidAssetID, fmt.Sprintf("Invalid assetID: %s", assetID)) + } + } + return nil +} + func (k Keeper) AVSInfoUpdate(ctx sdk.Context, params *types.AVSRegisterOrDeregisterParams) error { avsInfo, _ := k.GetAVSInfo(ctx, params.AvsAddress) action := params.Action @@ -78,6 +87,9 @@ func (k Keeper) AVSInfoUpdate(ctx sdk.Context, params *types.AVSRegisterOrDeregi // TODO: handle this better startingEpoch = uint64(epoch.CurrentEpoch) } + if err := k.ValidateAssetIDs(ctx, params.AssetID); err != nil { + return err + } // The caller must ensure that the relevant addresses are set to be the appropriate format (hex/bech32) avs := &types.AVSInfo{ Name: params.AvsName, @@ -152,6 +164,9 @@ func (k Keeper) AVSInfoUpdate(ctx sdk.Context, params *types.AVSRegisterOrDeregi } if params.AssetID != nil { avs.AssetIDs = params.AssetID + if err := k.ValidateAssetIDs(ctx, params.AssetID); err != nil { + return err + } } if params.UnbondingPeriod > 0 { diff --git a/x/avs/types/errors.go b/x/avs/types/errors.go index 046975df5..c2366e1b1 100644 --- a/x/avs/types/errors.go +++ b/x/avs/types/errors.go @@ -56,4 +56,8 @@ var ( ModuleName, 13, "The task already exists", ) + ErrInvalidAssetID = errorsmod.Register( + ModuleName, 14, + "Invalid asset ID", + ) ) diff --git a/x/avs/types/expected_keepers.go b/x/avs/types/expected_keepers.go index b0c69e1fd..538d3b776 100644 --- a/x/avs/types/expected_keepers.go +++ b/x/avs/types/expected_keepers.go @@ -49,4 +49,5 @@ type AssetsKeeper interface { GetStakingAssetInfo( ctx sdk.Context, assetID string, ) (info *assetstype.StakingAssetInfo, err error) + IsStakingAsset(sdk.Context, string) bool } From 0e1cd065abece75d61a490b1c406c5bbc7bf7a5f Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:23:42 +0000 Subject: [PATCH 07/52] refactor(dogfood): carve `sortByPower` out --- utils/utils.go | 42 ++++++++++++++++++++++++++++++++++++++++ x/dogfood/keeper/abci.go | 37 ++--------------------------------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/utils/utils.go b/utils/utils.go index d5407af47..3ddfcc289 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,13 +1,17 @@ package utils import ( + "bytes" + "sort" "strings" "github.com/evmos/evmos/v14/crypto/ethsecp256k1" + operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( @@ -111,3 +115,41 @@ func IsSupportedKey(pubkey cryptotypes.PubKey) bool { // return "", errorsmod.Wrapf(errortypes.ErrInvalidAddress, "invalid input address: %s", address) // } // } + +// SortByPower sorts operators, their pubkeys, and their powers by the powers. +// the sorting is descending, so the highest power is first. If the powers are equal, +// the operator address (bytes, not string!) is used as a tiebreaker. The bytes +// are preferred since that is how the operator module stores them, indexed by +// the bytes. +func SortByPower( + operatorAddrs []sdk.AccAddress, + pubKeys []operatortypes.WrappedConsKey, + powers []int64, +) ([]sdk.AccAddress, []operatortypes.WrappedConsKey, []int64) { + // Create a slice of indices + indices := make([]int, len(powers)) + for i := range indices { + indices[i] = i + } + + // Sort the indices slice based on the powers slice + sort.SliceStable(indices, func(i, j int) bool { + if powers[indices[i]] == powers[indices[j]] { + // ascending order of operator address as tiebreaker + return bytes.Compare(operatorAddrs[indices[i]], operatorAddrs[indices[j]]) < 0 + } + // descending order of power + return powers[indices[i]] > powers[indices[j]] + }) + + // Reorder all slices using the sorted indices + sortedOperatorAddrs := make([]sdk.AccAddress, len(operatorAddrs)) + sortedPubKeys := make([]operatortypes.WrappedConsKey, len(pubKeys)) + sortedPowers := make([]int64, len(powers)) + for i, idx := range indices { + sortedOperatorAddrs[i] = operatorAddrs[idx] + sortedPubKeys[i] = pubKeys[idx] + sortedPowers[i] = powers[idx] + } + return sortedOperatorAddrs, sortedPubKeys, sortedPowers +} diff --git a/x/dogfood/keeper/abci.go b/x/dogfood/keeper/abci.go index fbf8160ee..b9f1085da 100644 --- a/x/dogfood/keeper/abci.go +++ b/x/dogfood/keeper/abci.go @@ -1,11 +1,9 @@ package keeper import ( - "sort" - "cosmossdk.io/math" + "github.com/ExocoreNetwork/exocore/utils" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" - operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" abci "github.com/cometbft/cometbft/abci/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -87,7 +85,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { k.Logger(ctx).Error("error getting vote power for chain", "error", err) return []abci.ValidatorUpdate{} } - operators, keys, powers = sortByPower(operators, keys, powers) + operators, keys, powers = utils.SortByPower(operators, keys, powers) maxVals := k.GetMaxValidators(ctx) k.Logger(ctx).Info("max validators", "maxVals", maxVals, "len(operators)", len(operators)) // the capacity of this list is twice the maximum number of validators. @@ -165,34 +163,3 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { // call via wrapper function so that validator info is stored. return k.ApplyValidatorChanges(ctx, res) } - -// sortByPower sorts operators, their pubkeys, and their powers by the powers. -// the sorting is descending, so the highest power is first. -func sortByPower( - operatorAddrs []sdk.AccAddress, - pubKeys []operatortypes.WrappedConsKey, - powers []int64, -) ([]sdk.AccAddress, []operatortypes.WrappedConsKey, []int64) { - // Create a slice of indices - indices := make([]int, len(powers)) - for i := range indices { - indices[i] = i - } - - // Sort the indices slice based on the powers slice - sort.SliceStable(indices, func(i, j int) bool { - return powers[indices[i]] > powers[indices[j]] - }) - - // Reorder all slices using the sorted indices - sortedOperatorAddrs := make([]sdk.AccAddress, len(operatorAddrs)) - sortedPubKeys := make([]operatortypes.WrappedConsKey, len(pubKeys)) - sortedPowers := make([]int64, len(powers)) - for i, idx := range indices { - sortedOperatorAddrs[i] = operatorAddrs[idx] - sortedPubKeys[i] = pubKeys[idx] - sortedPowers[i] = powers[idx] - } - - return sortedOperatorAddrs, sortedPubKeys, sortedPowers -} From 9073b711482c5c60a18ab683630db53fe4a512fc Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:24:04 +0000 Subject: [PATCH 08/52] fix(dogfood): avoid duplicate validation x/avs handles the assetID validation --- x/dogfood/keeper/genesis.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/x/dogfood/keeper/genesis.go b/x/dogfood/keeper/genesis.go index b7ccdff36..6873f4bf8 100644 --- a/x/dogfood/keeper/genesis.go +++ b/x/dogfood/keeper/genesis.go @@ -29,12 +29,7 @@ func (k Keeper) InitGenesis( // is not running. it means that the genesis file is malformed. panic(fmt.Sprintf("epoch info not found %s", epochID)) } - // apply the same logic to the staking assets. - for _, assetID := range genState.Params.AssetIDs { - if !k.restakingKeeper.IsStakingAsset(ctx, assetID) { - panic(fmt.Errorf("staking param %s not found in assets module", assetID)) - } - } + // the staking assets are validated during AVS registration so we skip it here k.SetParams(ctx, genState.Params) // create the AVS var avsAddr common.Address From e06c5297a904cc10083617df410e83a87caa55dc Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:24:28 +0000 Subject: [PATCH 09/52] fix(dogfood): replace with max unbonding duration --- x/dogfood/keeper/validators.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/x/dogfood/keeper/validators.go b/x/dogfood/keeper/validators.go index 9aa93dced..c2d69d0a7 100644 --- a/x/dogfood/keeper/validators.go +++ b/x/dogfood/keeper/validators.go @@ -27,7 +27,12 @@ func (k Keeper) UnbondingTime(ctx sdk.Context) time.Duration { // no need to check for found, as the epoch info is validated at genesis. epoch, _ := k.epochsKeeper.GetEpochInfo(ctx, params.EpochIdentifier) durationPerEpoch := epoch.Duration - return time.Duration(params.EpochsUntilUnbonded) * durationPerEpoch + // the extra 1 is added to account for the current epoch. this is, + // therefore, the maximum time it takes for unbonding. if the tx + // is sent towards the end of the current epoch, the actual time + // will be closer to 7 days; if it is sent towards the beginning, + // the actual time will be closer to 8 days. + return time.Duration(params.EpochsUntilUnbonded+1) * durationPerEpoch } // ApplyValidatorChanges returns the validator set as is. However, it also From 04e0d675401aed91cb9d3f008bd7cb6d01330eda Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:25:02 +0000 Subject: [PATCH 10/52] doc(app): add comment about slashing frac storage --- app/app.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/app.go b/app/app.go index 186cada1e..204655085 100644 --- a/app/app.go +++ b/app/app.go @@ -584,6 +584,8 @@ func NewExocoreApp( // the validator signature rate and informs the staking keeper to perform the requisite // slashing. all its other operations are offloaded to Exocore keepers via the dogfood or // the operator module. + // NOTE: the slashing keeper stores the parameters (slash rate) for the dogfood + // keeper, since all slashing (for this chain) begins within this keeper. app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, app.LegacyAmino(), keys[slashingtypes.StoreKey], app.StakingKeeper, authAddrString, From 2f594b773406f6df4cdc93c8c826fd147b8e4ca6 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:26:12 +0000 Subject: [PATCH 11/52] feat(appchain): allow sub chain creation - Anyone can create a subchain via a simple transaction. The genesis file is available at the end of the current epoch. - If no operators opt in by that time, it is dropped. - If the state is available, it is queried via CLI and added to the genesis file of the subchain. - The genesis file, with data from other modules, starts the chain once enough vote power is live --- proto/exocore/appchain/common/v1/common.proto | 104 ++ .../appchain/coordinator/v1/coordinator.proto | 23 + .../appchain/coordinator/v1/query.proto | 26 +- .../exocore/appchain/coordinator/v1/tx.proto | 44 +- .../appchain/subscriber/v1/genesis.proto | 4 +- .../appchain/subscriber/v1/params.proto | 9 - .../appchain/subscriber/v1/query.proto | 10 +- x/appchain/common/types/codec.go | 4 +- x/appchain/common/types/common.pb.go | 1465 +++++++++++++++++ x/appchain/common/types/events.go | 16 + x/appchain/common/types/expected_keepers.go | 19 + x/appchain/common/types/params.go | 144 +- x/appchain/common/types/shared_params.go | 12 +- x/appchain/coordinator/client/cli/query.go | 62 +- x/appchain/coordinator/client/cli/tx.go | 26 + x/appchain/coordinator/keeper/grpc_query.go | 18 +- x/appchain/coordinator/keeper/ibc_client.go | 237 +++ x/appchain/coordinator/keeper/identifiers.go | 32 + .../coordinator/keeper/impl_epochs_hooks.go | 70 + x/appchain/coordinator/keeper/keeper.go | 40 +- x/appchain/coordinator/keeper/msg_server.go | 20 +- x/appchain/coordinator/keeper/register.go | 91 + x/appchain/coordinator/keeper/slash.go | 50 + x/appchain/coordinator/keeper/timeout.go | 62 + x/appchain/coordinator/types/codec.go | 2 +- .../coordinator/types/coordinator.pb.go | 513 ++++++ x/appchain/coordinator/types/errors.go | 23 + x/appchain/coordinator/types/events.go | 9 + .../coordinator/types/expected_keepers.go | 34 + x/appchain/coordinator/types/genesis.go | 1 + x/appchain/coordinator/types/keys.go | 83 +- x/appchain/coordinator/types/msg.go | 86 + x/appchain/coordinator/types/query.pb.go | 462 +++++- x/appchain/coordinator/types/query.pb.gw.go | 125 +- x/appchain/coordinator/types/tx.pb.go | 794 ++++++++- x/appchain/coordinator/types/tx.pb.gw.go | 171 ++ x/appchain/subscriber/client/cli/query.go | 2 +- x/appchain/subscriber/keeper/grpc_query.go | 2 +- x/appchain/subscriber/keeper/params.go | 13 +- x/appchain/subscriber/types/codec.go | 2 +- x/appchain/subscriber/types/genesis.go | 8 +- x/appchain/subscriber/types/genesis.pb.go | 28 +- x/appchain/subscriber/types/params.go | 16 - x/appchain/subscriber/types/params.pb.go | 266 --- x/appchain/subscriber/types/query.pb.go | 69 +- x/appchain/subscriber/types/query.pb.gw.go | 24 +- 46 files changed, 4869 insertions(+), 452 deletions(-) create mode 100644 proto/exocore/appchain/common/v1/common.proto create mode 100644 proto/exocore/appchain/coordinator/v1/coordinator.proto delete mode 100644 proto/exocore/appchain/subscriber/v1/params.proto create mode 100644 x/appchain/common/types/common.pb.go create mode 100644 x/appchain/common/types/events.go create mode 100644 x/appchain/common/types/expected_keepers.go create mode 100644 x/appchain/coordinator/keeper/ibc_client.go create mode 100644 x/appchain/coordinator/keeper/identifiers.go create mode 100644 x/appchain/coordinator/keeper/impl_epochs_hooks.go create mode 100644 x/appchain/coordinator/keeper/register.go create mode 100644 x/appchain/coordinator/keeper/slash.go create mode 100644 x/appchain/coordinator/keeper/timeout.go create mode 100644 x/appchain/coordinator/types/coordinator.pb.go create mode 100644 x/appchain/coordinator/types/errors.go create mode 100644 x/appchain/coordinator/types/events.go create mode 100644 x/appchain/coordinator/types/expected_keepers.go create mode 100644 x/appchain/coordinator/types/msg.go create mode 100644 x/appchain/coordinator/types/tx.pb.gw.go delete mode 100644 x/appchain/subscriber/types/params.go delete mode 100644 x/appchain/subscriber/types/params.pb.go diff --git a/proto/exocore/appchain/common/v1/common.proto b/proto/exocore/appchain/common/v1/common.proto new file mode 100644 index 000000000..2ac4270f8 --- /dev/null +++ b/proto/exocore/appchain/common/v1/common.proto @@ -0,0 +1,104 @@ +syntax = "proto3"; + +package exocore.appchain.common.v1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "ibc/lightclients/tendermint/v1/tendermint.proto"; +import "tendermint/abci/types.proto"; +import "amino/amino.proto"; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/common/types"; + +// This file contains all of the types shared within the coordinator module +// and each of the subscriber modules. These types (or parts thereof) are stored +// within the module states but not sent over the wire. + +// Params defines the parameters for the subscriber module. TODO(mm): These must be deny listed +// for edits via governance on the subscriber chain to prevent the subcriber participants +// from unilaterally alterting parameters (like reward %) for their own benefit. +message SubscriberParams { + // Reward related params + + // coordinator_fee_pool_addr_str is the address of the fee pool on the coordinator. + string coordinator_fee_pool_addr_str = 1; + // distribution_transmission_channel is the channel name used to transmit + // the rewards from the subscriber to the coordinator. It is used in the event + // that a channel between coordinator and subscriber exists prior to the + // provision of security from Exocore to the appchain. Until a changeover + // process is implemented, it is currently unused. (TODO) + string distribution_transmission_channel = 2; + // blocks_per_distribution_transmission is the number of blocks after which the minted + // reward is sent to the coordinator. + int64 blocks_per_distribution_transmission = 3; + // subscriber_redistribution_fraction is the %age of the rewards that the subscriber + // should send out. For example, "0.75" means 75% of the rewards are sent out. + string subscriber_redistribution_fraction = 4; + // reward_denom is the denomination of the reward. For now, this is not + // distributed but rather simply tracked. + string reward_denom = 5; + + // IBC related params + + // ibc_timeout_period is the timeout period used for IBC packets (excluding transfers) + // Such a timeout is enforced by IBC itself and not by either of the chains. + google.protobuf.Duration ibc_timeout_period = 6 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, + (gogoproto.customname) = "IBCTimeoutPeriod" ]; + // transfer_timeout_period is the timeout period used for IBC transfers. + google.protobuf.Duration transfer_timeout_period = 7 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + + // Params relevant to chain operation + // unbonding_duration is the subscriber chain's unbonding duration. it should be less + // than the coordinator chain's unbonding duration. + // for now, we don't support the subscriber chain using x/epochs as a unit of time; however, + // when we do, this duration should be the best approximation of that mechanism, with + // 1 epoch added to account for the current epoch. (TODO) + google.protobuf.Duration unbonding_period = 8 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // HistoricalEntries is the number of historical entries to persist in the + // historical stats module. It is the same as that defined in the staking module, + // however, we use the signed version so that negative values can be caught. + int64 historical_entries = 9; + + // These are params related to the slashing module. Requests are received + // from the subscriber and slashed according to these params. Since signing + // can only be tracked by the subscriber chain, we do not have any parameters + // here that can be used to configure the signing window and the number of + // blocks that should be signed in it. Conversely, the subscriber chain + // does not do anything with these parameters (even though they are shared) + // since slashing is done by the coordinator chain. + // Operators should refer to the genesis file of the subscriber chain to + // check their comfort with these values before onboarding the chain. + + // slash_fraction_downtime is the fraction of the stake that is slashed when a validator is found to be offline. + string slash_fraction_downtime = 15; + // downtime_jail_duration is the duration of the jail period for a validator + // after they have been found to be offline for too long. + google.protobuf.Duration downtime_jail_duration = 16 + [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdduration) = true]; + // slash_fraction_double_sign is the fraction of the stake that is slashed when a validator is found to have double signed. + string slash_fraction_double_sign = 17; +} + +// SubscriberGenesisState is the genesis state of a subscriber at the time of +// it being provisioned by Exocore, as stored in the coordinator module. +message SubscriberGenesisState { + // params is the parameters of the subscriber module, as generated. + SubscriberParams params = 1 [(gogoproto.nullable) = false]; + // coordinator is the coordinator information for the subscriber. + CoordinatorInfo coordinator = 2 [ (gogoproto.nullable) = false ]; +} + +// CoordinatorInfo is the information about the coordinator chain that is stored within the subscriber chain's subscriber module. +message CoordinatorInfo { + // client_state is the client state of the coordinator chain. + ibc.lightclients.tendermint.v1.ClientState client_state = 1; + // consensus_state is the consensus state of the coordinator chain. + ibc.lightclients.tendermint.v1.ConsensusState consensus_state = 2; + // initial_val_set is the initial validator set of the coordinator chain. + repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 + [ (gogoproto.nullable) = false ]; +} \ No newline at end of file diff --git a/proto/exocore/appchain/coordinator/v1/coordinator.proto b/proto/exocore/appchain/coordinator/v1/coordinator.proto new file mode 100644 index 000000000..e948adbd9 --- /dev/null +++ b/proto/exocore/appchain/coordinator/v1/coordinator.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package exocore.appchain.coordinator.v1; + +import "exocore/appchain/coordinator/v1/tx.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; + +// PendingSubscriberChainRequests is a helper structure to store a list of +// subscriber chain requests that are pending activation. +message PendingSubscriberChainRequests { + // list is the list of subscriber chain requests that are pending activation. + repeated .exocore.appchain.coordinator.v1.RegisterSubscriberChainRequest list = 1 + [(gogoproto.nullable) = false]; +} + +// ChainIDs is a helper structure to store a list of chain IDs. +message ChainIDs { + // list is the list of chain IDs. + repeated string list = 1; +} + diff --git a/proto/exocore/appchain/coordinator/v1/query.proto b/proto/exocore/appchain/coordinator/v1/query.proto index cbb09617c..06e565719 100644 --- a/proto/exocore/appchain/coordinator/v1/query.proto +++ b/proto/exocore/appchain/coordinator/v1/query.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package exocore.appchain.coordinator.v1; +import "exocore/appchain/common/v1/common.proto"; import "exocore/appchain/coordinator/v1/params.proto"; import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; @@ -10,15 +11,38 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/ty // Query defines the gRPC querier service. service Query { - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + // QueryParams returns the appchain coordinator module parameters. + rpc QueryParams(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http) = { get: "/appchain/coordinator/params" }; } + // QuerySubscriberGenesis returns the genesis state for a subscriber chain. + rpc QuerySubscriberGenesis(QuerySubscriberGenesisRequest) returns (QuerySubscriberGenesisResponse) { + option (google.api.http) = { + get: "/exocore/appchain/coordinator/v1/subscriber_genesis/{chain}" + }; + } } +// QueryParamsRequest is the request type for the Query.QueryParams RPC method. message QueryParamsRequest {} +// QueryParamsResponse is the response type for the Query.QueryParams RPC method. message QueryParamsResponse { + // params is the parameters for the appchain coordinator module. Params params = 1 [(gogoproto.nullable) = false]; +} + +// QuerySubscriberGenesisRequest is the request type for the Query.QuerySubscriberGenesis RPC method. +message QuerySubscriberGenesisRequest { + // chain is the chain ID of the subscriber chain. we intentionally don't use ChainID so that + // the query can work (it does not support custom names). + string chain = 1; +} + +// QuerySubscriberGenesisResponse is the response type for the Query.QuerySubscriberGenesis RPC method. +message QuerySubscriberGenesisResponse { + exocore.appchain.common.v1.SubscriberGenesisState subscriber_genesis = 1 + [ (gogoproto.nullable) = false ]; } \ No newline at end of file diff --git a/proto/exocore/appchain/coordinator/v1/tx.proto b/proto/exocore/appchain/coordinator/v1/tx.proto index 80b95b500..b36e0851c 100644 --- a/proto/exocore/appchain/coordinator/v1/tx.proto +++ b/proto/exocore/appchain/coordinator/v1/tx.proto @@ -2,7 +2,49 @@ syntax = "proto3"; package exocore.appchain.coordinator.v1; +import "cosmos/msg/v1/msg.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "exocore/appchain/common/v1/common.proto"; + option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; // Msg defines the Msg service. -service Msg {} \ No newline at end of file +service Msg { + option (cosmos.msg.v1.service) = true; + // RegisterSubscriberChain registers a subscriber chain with the coordinator. By default, it is activated at the next epoch. + rpc RegisterSubscriberChain(RegisterSubscriberChainRequest) returns (RegisterSubscriberChainResponse) { + option (google.api.http).post = "/exocore/appchain/coordinator/v1/tx/RegisterSubscriberChain"; + } +} + +// RegisterSubscriberChainRequest is the request type for the RegisterSubscriberChain message. +message RegisterSubscriberChainRequest { + option (cosmos.msg.v1.signer) = "FromAddress"; + // from_address is the address of the transaction signer. any transactions + // originating from this address may be used to edit the chain. at some point + // in the future this will be offloaded to the governance module on the + // subscriber chain. (TODO) + string from_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // chain_id is the unique identifier for the chain, serving as the primary key. + string chain_id = 2 [(gogoproto.customname) = "ChainID"]; + // epoch_identifier specifies the unit of epoch (week, hour, day). It must be registered in the x/epochs module. + // This epoch is the identifier used by the coordinator to send validator set updates to the subscriber at the + // end of each epoch. The subscriber chain's genesis is made available at the end of the current epoch + // (marked by this identifier). + string epoch_identifier = 3; + // asset_ids lists the IDs of assets accepted by the subscriber chain. + repeated string asset_ids = 4 [(gogoproto.customname) = "AssetIDs"]; + // min_self_delegation_usd is the minimum self-delegation in USD required to be a validator on the chain. + uint64 min_self_delegation_usd = 5; + // max_validators is the maximum number of validators allowed on the chain. + uint32 max_validators = 6; + // subscriber_params are the parameters used by the subscriber module + // on the subscriber chain. + exocore.appchain.common.v1.SubscriberParams subscriber_params = 7 [(gogoproto.nullable) = false]; +} + +// RegisterSubscriberChainResponse defines the response structure for executing a +// RegisterSubscriberChain message. +message RegisterSubscriberChainResponse {} \ No newline at end of file diff --git a/proto/exocore/appchain/subscriber/v1/genesis.proto b/proto/exocore/appchain/subscriber/v1/genesis.proto index 10f84d55f..222813eb4 100644 --- a/proto/exocore/appchain/subscriber/v1/genesis.proto +++ b/proto/exocore/appchain/subscriber/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package exocore.appchain.subscriber.v1; -import "exocore/appchain/subscriber/v1/params.proto"; +import "exocore/appchain/common/v1/common.proto"; import "gogoproto/gogo.proto"; option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; @@ -10,5 +10,5 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/typ // GenesisState is the genesis state for the appchain subscriber module. message GenesisState { // Params is the parameters for the appchain subscriber module. - Params params = 1 [(gogoproto.nullable) = false]; + exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false]; } diff --git a/proto/exocore/appchain/subscriber/v1/params.proto b/proto/exocore/appchain/subscriber/v1/params.proto deleted file mode 100644 index 1089ca0e8..000000000 --- a/proto/exocore/appchain/subscriber/v1/params.proto +++ /dev/null @@ -1,9 +0,0 @@ -syntax = "proto3"; - -package exocore.appchain.subscriber.v1; - -option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; - -// Params is the parameters for the appchain subscriber module. -message Params { -} diff --git a/proto/exocore/appchain/subscriber/v1/query.proto b/proto/exocore/appchain/subscriber/v1/query.proto index a45b4795c..8082f8e7a 100644 --- a/proto/exocore/appchain/subscriber/v1/query.proto +++ b/proto/exocore/appchain/subscriber/v1/query.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package exocore.appchain.subscriber.v1; -import "exocore/appchain/subscriber/v1/params.proto"; +import "exocore/appchain/common/v1/common.proto"; import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; @@ -10,15 +10,19 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/typ // Query defines the gRPC querier service. service Query { - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + // QueryParams returns the appchain subscriber module parameters. + rpc QueryParams(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http) = { get: "/appchain/subscriber/params" }; } } +// QueryParamsRequest is the request type for the Query.QueryParams RPC method. message QueryParamsRequest {} +// QueryParamsResponse is the response type for the Query.QueryParams RPC method. message QueryParamsResponse { - Params params = 1 [(gogoproto.nullable) = false]; + // params is the parameters for the appchain subscriber module. + exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false]; } \ No newline at end of file diff --git a/x/appchain/common/types/codec.go b/x/appchain/common/types/codec.go index b1f519ac0..e4d4b4af5 100644 --- a/x/appchain/common/types/codec.go +++ b/x/appchain/common/types/codec.go @@ -5,6 +5,4 @@ import ( cdctypes "github.com/cosmos/cosmos-sdk/codec/types" ) -var ( - ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) -) +var ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) diff --git a/x/appchain/common/types/common.pb.go b/x/appchain/common/types/common.pb.go new file mode 100644 index 000000000..c56d81bf3 --- /dev/null +++ b/x/appchain/common/types/common.pb.go @@ -0,0 +1,1465 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/common/v1/common.proto + +package types + +import ( + fmt "fmt" + types "github.com/cometbft/cometbft/abci/types" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" + time "time" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Params defines the parameters for the subscriber module. TODO(mm): These must be deny listed +// for edits via governance on the subscriber chain to prevent the subcriber participants +// from unilaterally alterting parameters (like reward %) for their own benefit. +type SubscriberParams struct { + // coordinator_fee_pool_addr_str is the address of the fee pool on the coordinator. + CoordinatorFeePoolAddrStr string `protobuf:"bytes,1,opt,name=coordinator_fee_pool_addr_str,json=coordinatorFeePoolAddrStr,proto3" json:"coordinator_fee_pool_addr_str,omitempty"` + // distribution_transmission_channel is the channel name used to transmit + // the rewards from the subscriber to the coordinator. It is used in the event + // that a channel between coordinator and subscriber exists prior to the + // provision of security from Exocore to the appchain. Until a changeover + // process is implemented, it is currently unused. (TODO) + DistributionTransmissionChannel string `protobuf:"bytes,2,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` + // blocks_per_distribution_transmission is the number of blocks after which the minted + // reward is sent to the coordinator. + BlocksPerDistributionTransmission int64 `protobuf:"varint,3,opt,name=blocks_per_distribution_transmission,json=blocksPerDistributionTransmission,proto3" json:"blocks_per_distribution_transmission,omitempty"` + // subscriber_redistribution_fraction is the %age of the rewards that the subscriber + // should send out. For example, "0.75" means 75% of the rewards are sent out. + SubscriberRedistributionFraction string `protobuf:"bytes,4,opt,name=subscriber_redistribution_fraction,json=subscriberRedistributionFraction,proto3" json:"subscriber_redistribution_fraction,omitempty"` + // reward_denom is the denomination of the reward. For now, this is not + // distributed but rather simply tracked. + RewardDenom string `protobuf:"bytes,5,opt,name=reward_denom,json=rewardDenom,proto3" json:"reward_denom,omitempty"` + // ibc_timeout_period is the timeout period used for IBC packets (excluding transfers) + // Such a timeout is enforced by IBC itself and not by either of the chains. + IBCTimeoutPeriod time.Duration `protobuf:"bytes,6,opt,name=ibc_timeout_period,json=ibcTimeoutPeriod,proto3,stdduration" json:"ibc_timeout_period"` + // transfer_timeout_period is the timeout period used for IBC transfers. + TransferTimeoutPeriod time.Duration `protobuf:"bytes,7,opt,name=transfer_timeout_period,json=transferTimeoutPeriod,proto3,stdduration" json:"transfer_timeout_period"` + // Params relevant to chain operation + // unbonding_duration is the subscriber chain's unbonding duration. it should be less + // than the coordinator chain's unbonding duration. + // for now, we don't support the subscriber chain using x/epochs as a unit of time; however, + // when we do, this duration should be the best approximation of that mechanism, with + // 1 epoch added to account for the current epoch. (TODO) + UnbondingPeriod time.Duration `protobuf:"bytes,8,opt,name=unbonding_period,json=unbondingPeriod,proto3,stdduration" json:"unbonding_period"` + // HistoricalEntries is the number of historical entries to persist in the + // historical stats module. It is the same as that defined in the staking module, + // however, we use the signed version so that negative values can be caught. + HistoricalEntries int64 `protobuf:"varint,9,opt,name=historical_entries,json=historicalEntries,proto3" json:"historical_entries,omitempty"` + // slash_fraction_downtime is the fraction of the stake that is slashed when a validator is found to be offline. + SlashFractionDowntime string `protobuf:"bytes,15,opt,name=slash_fraction_downtime,json=slashFractionDowntime,proto3" json:"slash_fraction_downtime,omitempty"` + // downtime_jail_duration is the duration of the jail period for a validator + // after they have been found to be offline for too long. + DowntimeJailDuration time.Duration `protobuf:"bytes,16,opt,name=downtime_jail_duration,json=downtimeJailDuration,proto3,stdduration" json:"downtime_jail_duration"` + // slash_fraction_double_sign is the fraction of the stake that is slashed when a validator is found to have double signed. + SlashFractionDoubleSign string `protobuf:"bytes,17,opt,name=slash_fraction_double_sign,json=slashFractionDoubleSign,proto3" json:"slash_fraction_double_sign,omitempty"` +} + +func (m *SubscriberParams) Reset() { *m = SubscriberParams{} } +func (m *SubscriberParams) String() string { return proto.CompactTextString(m) } +func (*SubscriberParams) ProtoMessage() {} +func (*SubscriberParams) Descriptor() ([]byte, []int) { + return fileDescriptor_71cb7b22d050d7a3, []int{0} +} +func (m *SubscriberParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SubscriberParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SubscriberParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SubscriberParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_SubscriberParams.Merge(m, src) +} +func (m *SubscriberParams) XXX_Size() int { + return m.Size() +} +func (m *SubscriberParams) XXX_DiscardUnknown() { + xxx_messageInfo_SubscriberParams.DiscardUnknown(m) +} + +var xxx_messageInfo_SubscriberParams proto.InternalMessageInfo + +func (m *SubscriberParams) GetCoordinatorFeePoolAddrStr() string { + if m != nil { + return m.CoordinatorFeePoolAddrStr + } + return "" +} + +func (m *SubscriberParams) GetDistributionTransmissionChannel() string { + if m != nil { + return m.DistributionTransmissionChannel + } + return "" +} + +func (m *SubscriberParams) GetBlocksPerDistributionTransmission() int64 { + if m != nil { + return m.BlocksPerDistributionTransmission + } + return 0 +} + +func (m *SubscriberParams) GetSubscriberRedistributionFraction() string { + if m != nil { + return m.SubscriberRedistributionFraction + } + return "" +} + +func (m *SubscriberParams) GetRewardDenom() string { + if m != nil { + return m.RewardDenom + } + return "" +} + +func (m *SubscriberParams) GetIBCTimeoutPeriod() time.Duration { + if m != nil { + return m.IBCTimeoutPeriod + } + return 0 +} + +func (m *SubscriberParams) GetTransferTimeoutPeriod() time.Duration { + if m != nil { + return m.TransferTimeoutPeriod + } + return 0 +} + +func (m *SubscriberParams) GetUnbondingPeriod() time.Duration { + if m != nil { + return m.UnbondingPeriod + } + return 0 +} + +func (m *SubscriberParams) GetHistoricalEntries() int64 { + if m != nil { + return m.HistoricalEntries + } + return 0 +} + +func (m *SubscriberParams) GetSlashFractionDowntime() string { + if m != nil { + return m.SlashFractionDowntime + } + return "" +} + +func (m *SubscriberParams) GetDowntimeJailDuration() time.Duration { + if m != nil { + return m.DowntimeJailDuration + } + return 0 +} + +func (m *SubscriberParams) GetSlashFractionDoubleSign() string { + if m != nil { + return m.SlashFractionDoubleSign + } + return "" +} + +// SubscriberGenesisState is the genesis state of a subscriber at the time of +// it being provisioned by Exocore, as stored in the coordinator module. +type SubscriberGenesisState struct { + // params is the parameters of the subscriber module, as generated. + Params SubscriberParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // coordinator is the coordinator information for the subscriber. + Coordinator CoordinatorInfo `protobuf:"bytes,2,opt,name=coordinator,proto3" json:"coordinator"` +} + +func (m *SubscriberGenesisState) Reset() { *m = SubscriberGenesisState{} } +func (m *SubscriberGenesisState) String() string { return proto.CompactTextString(m) } +func (*SubscriberGenesisState) ProtoMessage() {} +func (*SubscriberGenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_71cb7b22d050d7a3, []int{1} +} +func (m *SubscriberGenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SubscriberGenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SubscriberGenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SubscriberGenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_SubscriberGenesisState.Merge(m, src) +} +func (m *SubscriberGenesisState) XXX_Size() int { + return m.Size() +} +func (m *SubscriberGenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_SubscriberGenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_SubscriberGenesisState proto.InternalMessageInfo + +func (m *SubscriberGenesisState) GetParams() SubscriberParams { + if m != nil { + return m.Params + } + return SubscriberParams{} +} + +func (m *SubscriberGenesisState) GetCoordinator() CoordinatorInfo { + if m != nil { + return m.Coordinator + } + return CoordinatorInfo{} +} + +// CoordinatorInfo is the information about the coordinator chain that is stored within the subscriber chain's subscriber module. +type CoordinatorInfo struct { + // client_state is the client state of the coordinator chain. + ClientState *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty"` + // consensus_state is the consensus state of the coordinator chain. + ConsensusState *_07_tendermint.ConsensusState `protobuf:"bytes,2,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty"` + // initial_val_set is the initial validator set of the coordinator chain. + InitialValSet []types.ValidatorUpdate `protobuf:"bytes,3,rep,name=initial_val_set,json=initialValSet,proto3" json:"initial_val_set"` +} + +func (m *CoordinatorInfo) Reset() { *m = CoordinatorInfo{} } +func (m *CoordinatorInfo) String() string { return proto.CompactTextString(m) } +func (*CoordinatorInfo) ProtoMessage() {} +func (*CoordinatorInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_71cb7b22d050d7a3, []int{2} +} +func (m *CoordinatorInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CoordinatorInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CoordinatorInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CoordinatorInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_CoordinatorInfo.Merge(m, src) +} +func (m *CoordinatorInfo) XXX_Size() int { + return m.Size() +} +func (m *CoordinatorInfo) XXX_DiscardUnknown() { + xxx_messageInfo_CoordinatorInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_CoordinatorInfo proto.InternalMessageInfo + +func (m *CoordinatorInfo) GetClientState() *_07_tendermint.ClientState { + if m != nil { + return m.ClientState + } + return nil +} + +func (m *CoordinatorInfo) GetConsensusState() *_07_tendermint.ConsensusState { + if m != nil { + return m.ConsensusState + } + return nil +} + +func (m *CoordinatorInfo) GetInitialValSet() []types.ValidatorUpdate { + if m != nil { + return m.InitialValSet + } + return nil +} + +func init() { + proto.RegisterType((*SubscriberParams)(nil), "exocore.appchain.common.v1.SubscriberParams") + proto.RegisterType((*SubscriberGenesisState)(nil), "exocore.appchain.common.v1.SubscriberGenesisState") + proto.RegisterType((*CoordinatorInfo)(nil), "exocore.appchain.common.v1.CoordinatorInfo") +} + +func init() { + proto.RegisterFile("exocore/appchain/common/v1/common.proto", fileDescriptor_71cb7b22d050d7a3) +} + +var fileDescriptor_71cb7b22d050d7a3 = []byte{ + // 829 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x95, 0x41, 0x6f, 0x1c, 0x35, + 0x14, 0xc7, 0x33, 0x4d, 0x09, 0xad, 0xb7, 0x65, 0x37, 0x56, 0xdb, 0x4c, 0x17, 0xd8, 0xdd, 0x44, + 0x48, 0x44, 0x14, 0x66, 0xd4, 0x20, 0x21, 0x21, 0x2e, 0x90, 0xa4, 0x45, 0x8d, 0x50, 0x88, 0x76, + 0x4b, 0x91, 0x40, 0xc2, 0xf2, 0x78, 0xbc, 0xb3, 0x8f, 0xce, 0xd8, 0x23, 0xdb, 0x93, 0x94, 0xaf, + 0xc0, 0x89, 0x23, 0x1f, 0x81, 0x23, 0x57, 0xbe, 0x41, 0x8f, 0x3d, 0x72, 0x2a, 0x28, 0x39, 0xf0, + 0x1d, 0x38, 0x21, 0x7b, 0x3c, 0xd9, 0xd9, 0xad, 0x42, 0x7a, 0x19, 0xd9, 0x7e, 0xff, 0xf7, 0xf3, + 0x7b, 0xb6, 0xdf, 0x1b, 0xf4, 0x3e, 0x7f, 0x26, 0x99, 0x54, 0x3c, 0xa6, 0x65, 0xc9, 0x66, 0x14, + 0x44, 0xcc, 0x64, 0x51, 0x48, 0x11, 0x1f, 0xdf, 0xf7, 0xa3, 0xa8, 0x54, 0xd2, 0x48, 0xdc, 0xf7, + 0xc2, 0xa8, 0x11, 0x46, 0xde, 0x7c, 0x7c, 0xbf, 0x7f, 0x2b, 0x93, 0x99, 0x74, 0xb2, 0xd8, 0x8e, + 0x6a, 0x8f, 0xfe, 0x20, 0x93, 0x32, 0xcb, 0x79, 0xec, 0x66, 0x49, 0x35, 0x8d, 0xd3, 0x4a, 0x51, + 0x03, 0x0d, 0xb1, 0x3f, 0x5c, 0xb6, 0x1b, 0x28, 0xb8, 0x36, 0xb4, 0x28, 0xbd, 0x20, 0x86, 0x84, + 0xc5, 0x39, 0x64, 0x33, 0xc3, 0x72, 0xe0, 0xc2, 0xe8, 0xd8, 0x70, 0x91, 0x72, 0x55, 0x80, 0x30, + 0x36, 0xbe, 0xf9, 0xcc, 0x3b, 0xbc, 0xdd, 0xb2, 0xd3, 0x84, 0x41, 0x6c, 0x7e, 0x2a, 0xb9, 0xf6, + 0xc6, 0x75, 0x5a, 0x80, 0x90, 0xb1, 0xfb, 0xd6, 0x4b, 0x5b, 0xff, 0xae, 0xa1, 0xde, 0xa4, 0x4a, + 0x34, 0x53, 0x90, 0x70, 0x75, 0x44, 0x15, 0x2d, 0x34, 0xfe, 0x1c, 0xbd, 0xcb, 0xa4, 0x54, 0x29, + 0x08, 0x6a, 0xa4, 0x22, 0x53, 0xce, 0x49, 0x29, 0x65, 0x4e, 0x68, 0x9a, 0x2a, 0xa2, 0x8d, 0x0a, + 0x83, 0x51, 0xb0, 0x7d, 0x7d, 0x7c, 0xb7, 0x25, 0x7a, 0xc8, 0xf9, 0x91, 0x94, 0xf9, 0x17, 0x69, + 0xaa, 0x26, 0x46, 0xe1, 0x03, 0xb4, 0x99, 0x82, 0x36, 0x0a, 0x92, 0xca, 0xa6, 0x4b, 0x8c, 0xa2, + 0x42, 0x17, 0xa0, 0xb5, 0x9d, 0xb0, 0x19, 0x15, 0x82, 0xe7, 0xe1, 0x15, 0x47, 0x19, 0xb6, 0x85, + 0x8f, 0x5b, 0xba, 0xbd, 0x5a, 0x86, 0xbf, 0x46, 0xef, 0x25, 0xb9, 0x64, 0x4f, 0x35, 0x29, 0xb9, + 0x22, 0x17, 0x62, 0xc3, 0xd5, 0x51, 0xb0, 0xbd, 0x3a, 0xde, 0xac, 0xb5, 0x47, 0x5c, 0xed, 0x5f, + 0xc0, 0xc5, 0x5f, 0xa1, 0x2d, 0x7d, 0x9e, 0x32, 0x51, 0x7c, 0x01, 0x39, 0x55, 0x94, 0xd9, 0x41, + 0x78, 0xd5, 0x45, 0x37, 0x9a, 0x2b, 0xc7, 0x0b, 0xc2, 0x87, 0x5e, 0x87, 0x37, 0xd1, 0x0d, 0xc5, + 0x4f, 0xa8, 0x4a, 0x49, 0xca, 0x85, 0x2c, 0xc2, 0x37, 0x9c, 0x5f, 0xa7, 0x5e, 0xdb, 0xb7, 0x4b, + 0x98, 0x23, 0x0c, 0x09, 0x23, 0xf6, 0x72, 0x65, 0x65, 0x6c, 0x1a, 0x20, 0xd3, 0x70, 0x6d, 0x14, + 0x6c, 0x77, 0x76, 0xee, 0x46, 0xf5, 0x1b, 0x88, 0x9a, 0x37, 0x10, 0xed, 0xfb, 0x37, 0xb2, 0xfb, + 0xce, 0xf3, 0x97, 0xc3, 0x95, 0xd3, 0x97, 0xc3, 0xde, 0xa3, 0xdd, 0xbd, 0xc7, 0xb5, 0xef, 0x91, + 0x73, 0xfd, 0xf5, 0xaf, 0x61, 0x30, 0xee, 0x41, 0xc2, 0x16, 0x56, 0xf1, 0xf7, 0x68, 0xc3, 0x1d, + 0xc8, 0x94, 0xab, 0xe5, 0xbd, 0xde, 0xbc, 0x6c, 0xaf, 0x6b, 0x76, 0x2f, 0xc7, 0xbd, 0xdd, 0x30, + 0x16, 0xe1, 0x87, 0xa8, 0x57, 0x89, 0x44, 0x8a, 0x14, 0x44, 0xd6, 0x50, 0xaf, 0xbd, 0x3e, 0xb5, + 0x7b, 0xee, 0xec, 0x79, 0x1f, 0x21, 0x3c, 0x03, 0x6d, 0xa4, 0x02, 0x46, 0x73, 0xc2, 0x85, 0x51, + 0xc0, 0x75, 0x78, 0xdd, 0xdd, 0xe1, 0xfa, 0xdc, 0xf2, 0xa0, 0x36, 0xe0, 0x4f, 0xd0, 0x86, 0xce, + 0xa9, 0x9e, 0x9d, 0xdf, 0x0f, 0x49, 0xe5, 0x89, 0xb0, 0x59, 0x86, 0x5d, 0x77, 0xe0, 0xb7, 0x9d, + 0xb9, 0xb9, 0x95, 0x7d, 0x6f, 0xc4, 0x3f, 0xa0, 0x3b, 0x8d, 0x90, 0xfc, 0x48, 0x21, 0x27, 0x4d, + 0x05, 0x86, 0xbd, 0xcb, 0x82, 0xbf, 0xd9, 0x04, 0xff, 0xdb, 0x3f, 0xbf, 0x7f, 0x10, 0x8c, 0x6f, + 0x35, 0x9c, 0x03, 0x0a, 0x79, 0x23, 0xc2, 0x9f, 0xa1, 0xfe, 0x2b, 0x71, 0x55, 0x49, 0xce, 0x89, + 0x86, 0x4c, 0x84, 0xeb, 0x2e, 0xb4, 0x8d, 0xa5, 0xd0, 0xac, 0x7d, 0x02, 0x99, 0xd8, 0xfa, 0x23, + 0x40, 0x77, 0xe6, 0xc5, 0xf7, 0x25, 0x17, 0x5c, 0x83, 0x9e, 0x18, 0x6a, 0x38, 0x3e, 0x40, 0x6b, + 0xa5, 0x2b, 0x46, 0x57, 0x6b, 0x9d, 0x9d, 0x0f, 0xa3, 0x8b, 0x9b, 0x4f, 0xb4, 0x5c, 0xc0, 0xbb, + 0x57, 0x6d, 0xe8, 0x63, 0x4f, 0xc0, 0x13, 0xd4, 0x69, 0x55, 0xaa, 0x2b, 0xbb, 0xce, 0xce, 0xbd, + 0xff, 0x03, 0xee, 0xcd, 0xe5, 0x8f, 0xc4, 0x54, 0x7a, 0x5e, 0x9b, 0xb2, 0xf5, 0xf3, 0x15, 0xd4, + 0x5d, 0x92, 0xe1, 0x43, 0x74, 0xa3, 0x6e, 0x53, 0x44, 0xdb, 0x24, 0x7c, 0xe8, 0xf7, 0x22, 0x48, + 0x58, 0xd4, 0x6e, 0x62, 0x51, 0xab, 0x6d, 0xd9, 0xdd, 0xdc, 0xaa, 0xcb, 0x7b, 0xdc, 0x61, 0xf3, + 0x09, 0xfe, 0x16, 0x75, 0x99, 0x14, 0x9a, 0x0b, 0x5d, 0x69, 0x8f, 0xac, 0x83, 0x8f, 0x2e, 0x45, + 0x36, 0x6e, 0x35, 0xf5, 0x2d, 0xb6, 0x30, 0xc7, 0x87, 0xa8, 0x0b, 0x02, 0x0c, 0xd0, 0x9c, 0x1c, + 0xd3, 0x9c, 0x68, 0x6e, 0xc2, 0xd5, 0xd1, 0xea, 0x76, 0x67, 0x67, 0xd4, 0xe6, 0xd8, 0xfe, 0x19, + 0x3d, 0xa1, 0x39, 0xa4, 0x36, 0xc3, 0x6f, 0xca, 0x94, 0x1a, 0xee, 0x8f, 0xe2, 0xa6, 0x77, 0x7f, + 0x42, 0xf3, 0x09, 0x37, 0xbb, 0x93, 0xe7, 0xa7, 0x83, 0xe0, 0xc5, 0xe9, 0x20, 0xf8, 0xfb, 0x74, + 0x10, 0xfc, 0x72, 0x36, 0x58, 0x79, 0x71, 0x36, 0x58, 0xf9, 0xf3, 0x6c, 0xb0, 0xf2, 0xdd, 0xa7, + 0x19, 0x98, 0x59, 0x95, 0xd8, 0xb3, 0x8d, 0x1f, 0xd4, 0x07, 0x7e, 0xc8, 0xcd, 0x89, 0x54, 0x4f, + 0xe3, 0xe6, 0xb7, 0xf3, 0xec, 0x95, 0x1f, 0x8f, 0xeb, 0xd9, 0xc9, 0x9a, 0x7b, 0x92, 0x1f, 0xff, + 0x17, 0x00, 0x00, 0xff, 0xff, 0x31, 0x97, 0x3c, 0x0f, 0xa0, 0x06, 0x00, 0x00, +} + +func (m *SubscriberParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SubscriberParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SubscriberParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SlashFractionDoubleSign) > 0 { + i -= len(m.SlashFractionDoubleSign) + copy(dAtA[i:], m.SlashFractionDoubleSign) + i = encodeVarintCommon(dAtA, i, uint64(len(m.SlashFractionDoubleSign))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x8a + } + n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.DowntimeJailDuration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.DowntimeJailDuration):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintCommon(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + if len(m.SlashFractionDowntime) > 0 { + i -= len(m.SlashFractionDowntime) + copy(dAtA[i:], m.SlashFractionDowntime) + i = encodeVarintCommon(dAtA, i, uint64(len(m.SlashFractionDowntime))) + i-- + dAtA[i] = 0x7a + } + if m.HistoricalEntries != 0 { + i = encodeVarintCommon(dAtA, i, uint64(m.HistoricalEntries)) + i-- + dAtA[i] = 0x48 + } + n2, err2 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintCommon(dAtA, i, uint64(n2)) + i-- + dAtA[i] = 0x42 + n3, err3 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.TransferTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TransferTimeoutPeriod):]) + if err3 != nil { + return 0, err3 + } + i -= n3 + i = encodeVarintCommon(dAtA, i, uint64(n3)) + i-- + dAtA[i] = 0x3a + n4, err4 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.IBCTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.IBCTimeoutPeriod):]) + if err4 != nil { + return 0, err4 + } + i -= n4 + i = encodeVarintCommon(dAtA, i, uint64(n4)) + i-- + dAtA[i] = 0x32 + if len(m.RewardDenom) > 0 { + i -= len(m.RewardDenom) + copy(dAtA[i:], m.RewardDenom) + i = encodeVarintCommon(dAtA, i, uint64(len(m.RewardDenom))) + i-- + dAtA[i] = 0x2a + } + if len(m.SubscriberRedistributionFraction) > 0 { + i -= len(m.SubscriberRedistributionFraction) + copy(dAtA[i:], m.SubscriberRedistributionFraction) + i = encodeVarintCommon(dAtA, i, uint64(len(m.SubscriberRedistributionFraction))) + i-- + dAtA[i] = 0x22 + } + if m.BlocksPerDistributionTransmission != 0 { + i = encodeVarintCommon(dAtA, i, uint64(m.BlocksPerDistributionTransmission)) + i-- + dAtA[i] = 0x18 + } + if len(m.DistributionTransmissionChannel) > 0 { + i -= len(m.DistributionTransmissionChannel) + copy(dAtA[i:], m.DistributionTransmissionChannel) + i = encodeVarintCommon(dAtA, i, uint64(len(m.DistributionTransmissionChannel))) + i-- + dAtA[i] = 0x12 + } + if len(m.CoordinatorFeePoolAddrStr) > 0 { + i -= len(m.CoordinatorFeePoolAddrStr) + copy(dAtA[i:], m.CoordinatorFeePoolAddrStr) + i = encodeVarintCommon(dAtA, i, uint64(len(m.CoordinatorFeePoolAddrStr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SubscriberGenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SubscriberGenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SubscriberGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Coordinator.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *CoordinatorInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CoordinatorInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CoordinatorInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.InitialValSet) > 0 { + for iNdEx := len(m.InitialValSet) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.InitialValSet[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.ConsensusState != nil { + { + size, err := m.ConsensusState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.ClientState != nil { + { + size, err := m.ClientState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintCommon(dAtA []byte, offset int, v uint64) int { + offset -= sovCommon(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *SubscriberParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.CoordinatorFeePoolAddrStr) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + l = len(m.DistributionTransmissionChannel) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + if m.BlocksPerDistributionTransmission != 0 { + n += 1 + sovCommon(uint64(m.BlocksPerDistributionTransmission)) + } + l = len(m.SubscriberRedistributionFraction) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + l = len(m.RewardDenom) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.IBCTimeoutPeriod) + n += 1 + l + sovCommon(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TransferTimeoutPeriod) + n += 1 + l + sovCommon(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod) + n += 1 + l + sovCommon(uint64(l)) + if m.HistoricalEntries != 0 { + n += 1 + sovCommon(uint64(m.HistoricalEntries)) + } + l = len(m.SlashFractionDowntime) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.DowntimeJailDuration) + n += 2 + l + sovCommon(uint64(l)) + l = len(m.SlashFractionDoubleSign) + if l > 0 { + n += 2 + l + sovCommon(uint64(l)) + } + return n +} + +func (m *SubscriberGenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovCommon(uint64(l)) + l = m.Coordinator.Size() + n += 1 + l + sovCommon(uint64(l)) + return n +} + +func (m *CoordinatorInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ClientState != nil { + l = m.ClientState.Size() + n += 1 + l + sovCommon(uint64(l)) + } + if m.ConsensusState != nil { + l = m.ConsensusState.Size() + n += 1 + l + sovCommon(uint64(l)) + } + if len(m.InitialValSet) > 0 { + for _, e := range m.InitialValSet { + l = e.Size() + n += 1 + l + sovCommon(uint64(l)) + } + } + return n +} + +func sovCommon(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozCommon(x uint64) (n int) { + return sovCommon(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *SubscriberParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubscriberParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubscriberParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CoordinatorFeePoolAddrStr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CoordinatorFeePoolAddrStr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DistributionTransmissionChannel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlocksPerDistributionTransmission", wireType) + } + m.BlocksPerDistributionTransmission = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlocksPerDistributionTransmission |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubscriberRedistributionFraction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubscriberRedistributionFraction = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RewardDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RewardDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IBCTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.IBCTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TransferTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.TransferTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnbondingPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.UnbondingPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HistoricalEntries", wireType) + } + m.HistoricalEntries = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HistoricalEntries |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashFractionDowntime", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SlashFractionDowntime = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DowntimeJailDuration", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.DowntimeJailDuration, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 17: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashFractionDoubleSign", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SlashFractionDoubleSign = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SubscriberGenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubscriberGenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubscriberGenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Coordinator", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Coordinator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CoordinatorInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CoordinatorInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CoordinatorInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ClientState == nil { + m.ClientState = &_07_tendermint.ClientState{} + } + if err := m.ClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsensusState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConsensusState == nil { + m.ConsensusState = &_07_tendermint.ConsensusState{} + } + if err := m.ConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitialValSet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.InitialValSet = append(m.InitialValSet, types.ValidatorUpdate{}) + if err := m.InitialValSet[len(m.InitialValSet)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipCommon(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCommon + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCommon + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCommon + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthCommon + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupCommon + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthCommon + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthCommon = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowCommon = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupCommon = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/common/types/events.go b/x/appchain/common/types/events.go new file mode 100644 index 000000000..cd5ceced1 --- /dev/null +++ b/x/appchain/common/types/events.go @@ -0,0 +1,16 @@ +package types + +const ( + // EventTypeTimeout = "timeout" + AttributeKeyAckSuccess = "success" + AttributeKeyAck = "acknowledgement" + AttributeKeyAckError = "error" + AttributeChainID = "chain_id" + AttributeValidatorAddress = "validator_address" + AttributeValSetUpdateId = "valset_update_id" + AttributeInfractionType = "infraction_type" + + EventTypeChannelEstablished = "channel_established" + EventTypePacket = "common_packet" + EventTypeTimeout = "common_timeout" +) diff --git a/x/appchain/common/types/expected_keepers.go b/x/appchain/common/types/expected_keepers.go new file mode 100644 index 000000000..57f9416ae --- /dev/null +++ b/x/appchain/common/types/expected_keepers.go @@ -0,0 +1,19 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +type ClientKeeper interface { + CreateClient( + sdk.Context, ibcexported.ClientState, ibcexported.ConsensusState, + ) (string, error) + GetClientState(sdk.Context, string) (ibcexported.ClientState, bool) + GetLatestClientConsensusState( + sdk.Context, string, + ) (ibcexported.ConsensusState, bool) + GetSelfConsensusState( + sdk.Context, ibcexported.Height, + ) (ibcexported.ConsensusState, error) +} diff --git a/x/appchain/common/types/params.go b/x/appchain/common/types/params.go index 88fb13fd4..2082a8a15 100644 --- a/x/appchain/common/types/params.go +++ b/x/appchain/common/types/params.go @@ -1,8 +1,148 @@ package types -import "time" +import ( + fmt "fmt" + "time" + + ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" + + sdk "github.com/cosmos/cosmos-sdk/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) const ( - // Within the dogfood module, the default unbonding duration is 7 epochs, where 1 epoch = 1 day. This means a maximum of 8 days to unbond. We go lower than that here. + // CoordinatorFeePoolAddrStr is from the coordinator params. + // DistributionTransmissionChannel is currently blank. + // RewardDenom should be fetched from the add-avs tx. + // IBCTimeoutPeriod is from the coordinator params. + + // DefaultSubscriberUnbondingPeriod is the default unbonding period for a subscriber chain. + // There is no particular rationale to choose this number, since an + // operator can opt-in to or opt-out from all AVSs independently. DefaultSubscriberUnbondingPeriod = 24 * 7 * time.Hour + // DefaultBlocksPerDistributionTransmission is the default number of blocks after which a reward distribution is + // transmitted to the coordinator. TODO: This can be replaced with epochs. + DefaultBlocksPerDistributionTransmission = 1000 + // DefaultSubscriberRedistributionFraction is the default percentage of rewards that are distributed + // to the coordinator. + DefaultSubscriberRedistributionFraction = "0.1" + // DefaultTransferTimeoutPeriod is the default timeout period for IBC transfers. + DefaultTransferTimeoutPeriod = time.Hour ) + +// NewSubscriberParams returns a new subscriber params with the given values. +func NewSubscriberParams( + coordinatorFeePoolAddrStr string, + distributionTransmissionChannel string, + blocksPerDistributionTransmission int64, + subscriberRedistributionFraction string, + rewardDenom string, + ibcTimeoutPeriod time.Duration, + transferTimeoutPeriod time.Duration, + unbondingPeriod time.Duration, + historicalEntries int64, + slashFractionDowntime string, + downtimeJailDuration time.Duration, + slashFractionDoubleSign string, +) SubscriberParams { + return SubscriberParams{ + CoordinatorFeePoolAddrStr: coordinatorFeePoolAddrStr, + DistributionTransmissionChannel: distributionTransmissionChannel, + BlocksPerDistributionTransmission: blocksPerDistributionTransmission, + SubscriberRedistributionFraction: subscriberRedistributionFraction, + RewardDenom: rewardDenom, + IBCTimeoutPeriod: ibcTimeoutPeriod, + TransferTimeoutPeriod: transferTimeoutPeriod, + UnbondingPeriod: unbondingPeriod, + HistoricalEntries: historicalEntries, + SlashFractionDowntime: slashFractionDowntime, + DowntimeJailDuration: downtimeJailDuration, + SlashFractionDoubleSign: slashFractionDoubleSign, + } +} + +// DefaultSubscriberParams returns the default subscriber params. +func DefaultSubscriberParams() SubscriberParams { + return NewSubscriberParams( + "", // this is set by the coordinator, not by the subscriber + "", // this is set by the coordinator, not by the subscriber + DefaultBlocksPerDistributionTransmission, + DefaultSubscriberRedistributionFraction, + "", // this should be set in the transaction to register the subscriber + DefaultIBCTimeoutPeriod, + DefaultTransferTimeoutPeriod, + DefaultSubscriberUnbondingPeriod, + int64(stakingtypes.DefaultHistoricalEntries), + slashingtypes.DefaultSlashFractionDowntime.String(), + DefaultSubscriberUnbondingPeriod, + slashingtypes.DefaultSlashFractionDoubleSign.String(), + ) +} + +// Validate the subscriber params. +func (p SubscriberParams) Validate() error { + // CoordinatorFeePoolAddrStr needs no validations. + if err := ValidateDistributionTransmissionChannel(p.DistributionTransmissionChannel); err != nil { + return fmt.Errorf("distribution transmission channel: %w", err) + } + if err := ValidatePositiveInt64(p.BlocksPerDistributionTransmission); err != nil { + return fmt.Errorf("blocks per distribution transmission: %w", err) + } + if err := ValidateStringFraction(p.SubscriberRedistributionFraction); err != nil { + return fmt.Errorf("subscriber redistribution fraction: %w", err) + } + if err := ValidateDuration(p.TransferTimeoutPeriod); err != nil { + return fmt.Errorf("transfer timeout period: %w", err) + } + if err := ValidatePositiveInt64(p.HistoricalEntries); err != nil { + return fmt.Errorf("historical entries: %w", err) + } + if err := ValidateDenomination(p.RewardDenom); err != nil { + return fmt.Errorf("reward denom: %w", err) + } + if err := ValidateDuration(p.UnbondingPeriod); err != nil { + return fmt.Errorf("unbonding period: %w", err) + } + if err := ValidateDuration(p.IBCTimeoutPeriod); err != nil { + return fmt.Errorf("IBC timeout period: %w", err) + } + if err := ValidateStringFraction(p.SlashFractionDowntime); err != nil { + return fmt.Errorf("slash fraction downtime: %w", err) + } + if err := ValidateStringFraction(p.SlashFractionDoubleSign); err != nil { + return fmt.Errorf("slash fraction double sign: %w", err) + } + // technically duration could still be 0 for downtime, but + // it's not a good idea. + if err := ValidateDuration(p.DowntimeJailDuration); err != nil { + return fmt.Errorf("downtime jail duration: %w", err) + } + return nil +} + +// ValidateDistributionTransmissionChannel validates the distribution transmission channel. +// The channel must be a valid IBC channel identifier, or unset. +func ValidateDistributionTransmissionChannel(i string) error { + if i == "" { + // if it is unset, it means that the channel is yet to be + // created, so we don't need to validate it. + // this is why the function is called DistributionChannel + // and not just Channel + return nil + } + return ibchost.ChannelIdentifierValidator(i) +} + +// ValidatePositiveInt64 validates that the given int64 is positive. +func ValidatePositiveInt64(i int64) error { + if i <= 0 { + return fmt.Errorf("int must be positive") + } + return nil +} + +// ValidateDenomination validates that the given denomination is valid. +func ValidateDenomination(denom string) error { + return sdk.ValidateDenom(denom) +} diff --git a/x/appchain/common/types/shared_params.go b/x/appchain/common/types/shared_params.go index 789bc9369..7e9baefb0 100644 --- a/x/appchain/common/types/shared_params.go +++ b/x/appchain/common/types/shared_params.go @@ -23,11 +23,7 @@ func CalculateTrustPeriod(unbondingPeriod time.Duration, trustPeriodFraction str } // ValidateStringFraction validates that the given string is a valid fraction in the range [0, 1]. -func ValidateStringFraction(i interface{}) error { - str, ok := i.(string) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } +func ValidateStringFraction(str string) error { dec, err := sdk.NewDecFromStr(str) if err != nil { return err @@ -42,11 +38,7 @@ func ValidateStringFraction(i interface{}) error { } // ValidateDuration validates that the given duration is positive. -func ValidateDuration(i interface{}) error { - period, ok := i.(time.Duration) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } +func ValidateDuration(period time.Duration) error { if period <= time.Duration(0) { return fmt.Errorf("duration must be positive") } diff --git a/x/appchain/coordinator/client/cli/query.go b/x/appchain/coordinator/client/cli/query.go index d45de5d5d..5085ede14 100644 --- a/x/appchain/coordinator/client/cli/query.go +++ b/x/appchain/coordinator/client/cli/query.go @@ -6,12 +6,13 @@ import ( "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" ) // GetQueryCmd returns the cli query commands for this module -func GetQueryCmd(queryRoute string) *cobra.Command { +func GetQueryCmd(string) *cobra.Command { // Group dogfood queries under a subcommand cmd := &cobra.Command{ Use: types.ModuleName, @@ -23,6 +24,65 @@ func GetQueryCmd(queryRoute string) *cobra.Command { SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, } + cmd.AddCommand( + CmdQueryParams(), + CmdQuerySubscriberGenesis(), + ) + return cmd +} + +func CmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "shows the parameters of the module", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.QueryParams(cmd.Context(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func CmdQuerySubscriberGenesis() *cobra.Command { + cmd := &cobra.Command{ + Use: "subscriber-genesis [chain-id]", + Short: "Query subscriber chain genesis state by chain id", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + req := &types.QuerySubscriberGenesisRequest{ + Chain: args[0], + } + res, err := queryClient.QuerySubscriberGenesis(cmd.Context(), req) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) return cmd } diff --git a/x/appchain/coordinator/client/cli/tx.go b/x/appchain/coordinator/client/cli/tx.go index a7913172f..60df0eb27 100644 --- a/x/appchain/coordinator/client/cli/tx.go +++ b/x/appchain/coordinator/client/cli/tx.go @@ -7,6 +7,7 @@ import ( "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" ) // GetTxCmd returns the transaction commands for this module @@ -22,5 +23,30 @@ func GetTxCmd() *cobra.Command { RunE: client.ValidateCmd, } + cmd.AddCommand( + CmdRegisterSubscriberChain(), + ) + return cmd +} + +// CmdRegisterSubscriberChain returns the command to register a subscriber chain. +func CmdRegisterSubscriberChain() *cobra.Command { + cmd := &cobra.Command{ + Use: "register-subscriber-chain [json-args]", + Short: "Register a subscriber chain", + Long: "Register a subscriber chain within the appchain coordinator module", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewRegisterSubscriberChainRequest(clientCtx.GetFromAddress().String(), args[0]) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + return cmd } diff --git a/x/appchain/coordinator/keeper/grpc_query.go b/x/appchain/coordinator/keeper/grpc_query.go index 4ba53ad3a..34cfe5801 100644 --- a/x/appchain/coordinator/keeper/grpc_query.go +++ b/x/appchain/coordinator/keeper/grpc_query.go @@ -12,7 +12,8 @@ import ( var _ types.QueryServer = Keeper{} -func (k Keeper) Params( +// QueryParams is the implementation of the QueryServer method +func (k Keeper) QueryParams( goCtx context.Context, req *types.QueryParamsRequest, ) (*types.QueryParamsResponse, error) { @@ -20,6 +21,19 @@ func (k Keeper) Params( return nil, status.Error(codes.InvalidArgument, "invalid request") } ctx := sdk.UnwrapSDKContext(goCtx) - return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil } + +// QuerySubscriberGenesis is the implementation of the QueryServer method +func (k Keeper) QuerySubscriberGenesis( + goCtx context.Context, + req *types.QuerySubscriberGenesisRequest, +) (*types.QuerySubscriberGenesisResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + return &types.QuerySubscriberGenesisResponse{ + SubscriberGenesis: k.GetSubscriberGenesis(ctx, req.Chain), + }, nil +} diff --git a/x/appchain/coordinator/keeper/ibc_client.go b/x/appchain/coordinator/keeper/ibc_client.go new file mode 100644 index 000000000..9026bf9da --- /dev/null +++ b/x/appchain/coordinator/keeper/ibc_client.go @@ -0,0 +1,237 @@ +package keeper + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + "github.com/ExocoreNetwork/exocore/utils" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" + abci "github.com/cometbft/cometbft/abci/types" + tmtypes "github.com/cometbft/cometbft/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" +) + +// CreateClientForSubscriberInCachedCtx is a wrapper function around CreateClientForSubscriber. +func (k Keeper) CreateClientForSubscriberInCachedCtx( + ctx sdk.Context, + req types.RegisterSubscriberChainRequest, +) (cctx sdk.Context, writeCache func(), err error) { + cctx, writeCache = ctx.CacheContext() + err = k.CreateClientForSubscriber(cctx, req) + return +} + +// CreateClientForSubscriber creates a new client for the subscriber chain. +func (k Keeper) CreateClientForSubscriber( + ctx sdk.Context, + req types.RegisterSubscriberChainRequest, +) error { + chainID := req.ChainID + subscriberParams := req.SubscriberParams + // we always deploy a new client for the subscriber chain for our module + // technically, the below can never happen but it is guarded in ICS-20 and therefore, here. + if _, found := k.GetClientForChain(ctx, chainID); found { + // client already exists + return types.ErrDuplicateSubChain.Wrapf("chainID: %s", chainID) + } + // create the client + coordinatorParams := k.GetParams(ctx) + clientState := coordinatorParams.TemplateClient + clientState.ChainId = chainID + // TODO(mm): Make this configurable for switchover use case + clientState.LatestHeight = clienttypes.Height{ + RevisionNumber: clienttypes.ParseChainID(chainID), + RevisionHeight: 1, + } + subscriberUnbondingPeriod := subscriberParams.UnbondingPeriod + trustPeriod, err := commontypes.CalculateTrustPeriod( + // note that this is the client that will live on Exocore + // and we use the counterparty's unbonding period as a base + subscriberUnbondingPeriod, coordinatorParams.TrustingPeriodFraction, + ) + if err != nil { + return err + } + clientState.TrustingPeriod = trustPeriod + clientState.UnbondingPeriod = subscriberUnbondingPeriod + + // create the consensus state for the subscriber + // do remember that the state we are storing here is just for the subscriber module + // on the app chain, and not any other module. so it can have balances outside of this. + subscriberGenesis, validatorSetHash, err := k.MakeSubscriberGenesis(ctx, req) + if err != nil { + return err + } + // this state can be pruned after the initial handshake occurs. + k.SetSubscriberGenesis(ctx, chainID, subscriberGenesis) + k.SetSubSlashFractionDowntime(ctx, chainID, subscriberParams.SlashFractionDowntime) + k.SetSubSlashFractionDoubleSign(ctx, chainID, subscriberParams.SlashFractionDoubleSign) + k.SetSubDowntimeJailDuration(ctx, chainID, subscriberParams.DowntimeJailDuration) + consensusState := ibctmtypes.NewConsensusState( + ctx.BlockTime(), + commitmenttypes.NewMerkleRoot([]byte(ibctmtypes.SentinelRoot)), + validatorSetHash, // use the hash of the updated initial valset + ) + + clientID, err := k.clientKeeper.CreateClient(ctx, clientState, consensusState) + if err != nil { + return err + } + k.SetClientForChain(ctx, chainID, clientID) + + epochInfo, _ := k.epochsKeeper.GetEpochInfo(ctx, req.EpochIdentifier) + initTimeoutPeriod := coordinatorParams.InitTimeoutPeriod + // the CurrentEpoch below is the one that has already ended, so we increment it by 1. + // assume we start with a value of 2 and we are giving 4 full epochs for initialization. + // so when epoch 6 ends, the timeout ends. + initTimeoutPeriod.EpochNumber += uint64(epochInfo.CurrentEpoch) + 1 + k.AppendChainToInitTimeout(ctx, initTimeoutPeriod, chainID) + + k.Logger(ctx).Info( + "subscriber chain registered (client created)", + "chainId", chainID, + "clientId", clientID, + ) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeSubscriberClientCreated, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(commontypes.AttributeChainID, chainID), + sdk.NewAttribute(clienttypes.AttributeKeyClientID, clientID), + sdk.NewAttribute(types.AttributeInitialHeight, clientState.LatestHeight.String()), + sdk.NewAttribute( + types.AttributeInitializationTimeout, + initTimeoutPeriod.String(), + ), + sdk.NewAttribute( + types.AttributeTrustingPeriod, + clientState.TrustingPeriod.String(), + ), + sdk.NewAttribute( + types.AttributeUnbondingPeriod, + clientState.UnbondingPeriod.String(), + ), + ), + ) + + return nil +} + +func (k Keeper) MakeSubscriberGenesis( + ctx sdk.Context, req types.RegisterSubscriberChainRequest, +) (*commontypes.SubscriberGenesisState, []byte, error) { + params := k.GetParams(ctx) + chainID := req.ChainID + chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(chainID) + coordinatorUnbondingPeriod := k.stakingKeeper.UnbondingTime(ctx) + // client state + clientState := params.TemplateClient + clientState.ChainId = chainID + clientState.LatestHeight = clienttypes.GetSelfHeight(ctx) + trustPeriod, err := commontypes.CalculateTrustPeriod( + coordinatorUnbondingPeriod, params.TrustingPeriodFraction, + ) + if err != nil { + return nil, nil, errorsmod.Wrapf( + sdkerrors.ErrInvalidHeight, + "error %s calculating self trusting period for chain %s", + err, chainID, + ) + } + clientState.TrustingPeriod = trustPeriod + clientState.UnbondingPeriod = coordinatorUnbondingPeriod + // consensus state + consState, err := k.clientKeeper.GetSelfConsensusState(ctx, clientState.LatestHeight) + if err != nil { + return nil, nil, errorsmod.Wrapf( + clienttypes.ErrConsensusStateNotFound, + "error %s getting self consensus state for chain %s", + err, chainID, + ) + } + operators, keys := k.operatorKeeper.GetActiveOperatorsForChainID(ctx, chainIDWithoutRevision) + powers, err := k.operatorKeeper.GetVotePowerForChainID( + ctx, operators, chainIDWithoutRevision, + ) + if err != nil { + k.Logger(ctx).Error("error getting vote power for chain", "error", err) + return nil, nil, err + } + operators, keys, powers = utils.SortByPower(operators, keys, powers) + maxVals := req.MaxValidators + validatorUpdates := make([]abci.ValidatorUpdate, 0, maxVals) + for i := range operators { + if i >= int(maxVals) { + break + } + power := powers[i] + if power < 1 { + break + } + wrappedKey := keys[i] + validatorUpdates = append(validatorUpdates, abci.ValidatorUpdate{ + PubKey: *wrappedKey.ToTmProtoKey(), + Power: power, + }) + } + if len(validatorUpdates) == 0 { + return nil, nil, errorsmod.Wrapf( + types.ErrNoOperators, "no operators with stake found for chainID: %s", chainID, + ) + } + // sorted by power (with accAddr as tie breaker) and hence deterministic + updatesAsValSet, err := tmtypes.PB2TM.ValidatorUpdates(validatorUpdates) + if err != nil { + return nil, nil, fmt.Errorf( + "could not create validator set from validator updates: %s", err, + ) + } + return &commontypes.SubscriberGenesisState{ + Params: req.SubscriberParams, + Coordinator: commontypes.CoordinatorInfo{ + ClientState: clientState, + ConsensusState: consState.(*ibctmtypes.ConsensusState), + InitialValSet: validatorUpdates, + }, + }, tmtypes.NewValidatorSet(updatesAsValSet).Hash(), nil +} + +// SetSubscriberGenesis sets the genesis state for the subscriber chain. +func (k Keeper) SetSubscriberGenesis( + ctx sdk.Context, + chainID string, + genesis *commontypes.SubscriberGenesisState, +) { + store := ctx.KVStore(k.storeKey) + key := types.SubscriberGenesisKey(chainID) + store.Set(key, k.cdc.MustMarshal(genesis)) +} + +// GetSubscriberGenesis gets the genesis state for the subscriber chain. +func (k Keeper) GetSubscriberGenesis( + ctx sdk.Context, + chainID string, +) (genesis commontypes.SubscriberGenesisState) { + store := ctx.KVStore(k.storeKey) + key := types.SubscriberGenesisKey(chainID) + k.cdc.MustUnmarshal(store.Get(key), &genesis) + return genesis +} + +// DeleteSubscriberGenesis deletes the genesis state for the subscriber chain. +// It is a pruning function. +func (k Keeper) DeleteSubscriberGenesis( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + key := types.SubscriberGenesisKey(chainID) + store.Delete(key) +} diff --git a/x/appchain/coordinator/keeper/identifiers.go b/x/appchain/coordinator/keeper/identifiers.go new file mode 100644 index 000000000..daea84510 --- /dev/null +++ b/x/appchain/coordinator/keeper/identifiers.go @@ -0,0 +1,32 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SetClientForChain sets the ibc client id for a given chain id. +func (k Keeper) SetClientForChain( + ctx sdk.Context, chainId string, clientId string, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.ClientForChainKey(chainId), []byte(clientId)) +} + +// GetClientForChain gets the ibc client id for a given chain id. +func (k Keeper) GetClientForChain( + ctx sdk.Context, chainId string, +) (string, bool) { + store := ctx.KVStore(k.storeKey) + bytes := store.Get(types.ClientForChainKey(chainId)) + if bytes == nil { + return "", false + } + return string(bytes), true +} + +// DeleteClientForChain deletes the ibc client id for a given chain id. +func (k Keeper) DeleteClientForChain(ctx sdk.Context, chainId string) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.ClientForChainKey(chainId)) +} diff --git a/x/appchain/coordinator/keeper/impl_epochs_hooks.go b/x/appchain/coordinator/keeper/impl_epochs_hooks.go new file mode 100644 index 000000000..489a68a2d --- /dev/null +++ b/x/appchain/coordinator/keeper/impl_epochs_hooks.go @@ -0,0 +1,70 @@ +package keeper + +import ( + avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// EpochsHooksWrapper is the wrapper structure that implements the epochs hooks for the dogfood +// keeper. +type EpochsHooksWrapper struct { + keeper *Keeper +} + +// Interface guard +var _ epochstypes.EpochHooks = EpochsHooksWrapper{} + +// EpochsHooks returns the epochs hooks wrapper. It follows the "accept interfaces, return +// concretes" pattern. +func (k *Keeper) EpochsHooks() EpochsHooksWrapper { + return EpochsHooksWrapper{k} +} + +// AfterEpochEnd is called after an epoch ends. It is called during the BeginBlock function. +func (wrapper EpochsHooksWrapper) AfterEpochEnd( + ctx sdk.Context, identifier string, epoch int64, +) { + // whenever an epoch ends, we should iterate over the list of pending subscriber chains + // to be activated, and then activate them. once activated, we should move them from + // the pending list to the active list. + executable := wrapper.keeper.GetPendingSubChains(ctx, identifier, uint64(epoch)) + for _, subscriber := range executable.List { + cctx, writeFn, err := wrapper.keeper.CreateClientForSubscriberInCachedCtx(ctx, subscriber) + if err != nil { + // within this block, we use the ctx and not the cctx, since the cctx's job is solely + // to guard the client creation. + // no re-attempts will be made for this subscriber + ctx.Logger().Error( + "subscriber client not created", + "chainID", subscriber, + "error", err, + ) + // clear the registered AVS + chainID := avstypes.ChainIDWithoutRevision(subscriber.ChainID) + _, addr := wrapper.keeper.avsKeeper.IsAVSByChainID(ctx, chainID) + wrapper.keeper.avsKeeper.DeleteAVSInfo(ctx, addr) + continue + } + // copy over the events from the cached ctx + ctx.EventManager().EmitEvents(cctx.EventManager().Events()) + writeFn() + wrapper.keeper.Logger(ctx).Info( + "subscriber chain started", + "chainID", subscriber, + // we start at the current block and do not allow scheduling. this is the same + // as any other AVS. + "spawn time", ctx.BlockTime().UTC(), + ) + } + // delete those that were executed (including those that failed) + wrapper.keeper.ClearPendingSubChains(ctx, identifier, uint64(epoch)) + // next, we iterate over the active list and queue the validator set update for them. +} + +// BeforeEpochStart is called before an epoch starts. +func (wrapper EpochsHooksWrapper) BeforeEpochStart( + sdk.Context, string, int64, +) { + // no-op +} diff --git a/x/appchain/coordinator/keeper/keeper.go b/x/appchain/coordinator/keeper/keeper.go index 9a73b1fba..ead9bc645 100644 --- a/x/appchain/coordinator/keeper/keeper.go +++ b/x/appchain/coordinator/keeper/keeper.go @@ -1,19 +1,49 @@ package keeper import ( + "fmt" + + "github.com/cometbft/cometbft/libs/log" + + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) type Keeper struct { - cdc codec.BinaryCodec - storeKey storetypes.StoreKey + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + avsKeeper types.AVSKeeper + epochsKeeper types.EpochsKeeper + operatorKeeper types.OperatorKeeper + stakingKeeper types.StakingKeeper + clientKeeper commontypes.ClientKeeper } // NewKeeper creates a new coordinator keeper. -func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey) Keeper { +func NewKeeper( + cdc codec.BinaryCodec, + storeKey storetypes.StoreKey, + avsKeeper types.AVSKeeper, + epochsKeeper types.EpochsKeeper, + operatorKeeper types.OperatorKeeper, + stakingKeeper types.StakingKeeper, + clientKeeper commontypes.ClientKeeper, +) Keeper { return Keeper{ - cdc: cdc, - storeKey: storeKey, + cdc: cdc, + storeKey: storeKey, + avsKeeper: avsKeeper, + epochsKeeper: epochsKeeper, + operatorKeeper: operatorKeeper, + stakingKeeper: stakingKeeper, + clientKeeper: clientKeeper, } } + +// Logger returns a logger object for use within the module. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} diff --git a/x/appchain/coordinator/keeper/msg_server.go b/x/appchain/coordinator/keeper/msg_server.go index 9adaac256..1fa0c3501 100644 --- a/x/appchain/coordinator/keeper/msg_server.go +++ b/x/appchain/coordinator/keeper/msg_server.go @@ -1,6 +1,14 @@ package keeper -import "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" +import ( + "context" + "fmt" + + errorsmod "cosmossdk.io/errors" + + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) // msgServer is a wrapper around the Keeper (which is the actual implementation) and // satisfies the MsgServer interface. @@ -15,3 +23,13 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { // interface guard var _ types.MsgServer = msgServer{} + +func (m msgServer) RegisterSubscriberChain( + goCtx context.Context, req *types.RegisterSubscriberChainRequest, +) (res *types.RegisterSubscriberChainResponse, err error) { + ctx := sdk.UnwrapSDKContext(goCtx) + if res, err = m.Keeper.AddSubscriberChain(ctx, req); err != nil { + return nil, errorsmod.Wrapf(err, fmt.Sprintf("RegisterSubscriberChain: key is %s", req.ChainID)) + } + return res, nil +} diff --git a/x/appchain/coordinator/keeper/register.go b/x/appchain/coordinator/keeper/register.go new file mode 100644 index 000000000..8a48f896b --- /dev/null +++ b/x/appchain/coordinator/keeper/register.go @@ -0,0 +1,91 @@ +package keeper + +import ( + "math" + + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) AddSubscriberChain( + ctx sdk.Context, + req *types.RegisterSubscriberChainRequest, +) (*types.RegisterSubscriberChainResponse, error) { + if req == nil { + return nil, types.ErrNilRequest + } + // We have already validated + // 1. The unbonding epochs are not 0 + // 2. The chainID is not blank + // 3. The duration is positive. + // 4. Max validators is not 0 + // 5. Asset IDs are valid format, but may not be registered + // 6. Min self delegation is not nil or not negative + // The AVS keeper validates: + // 1. Unique chainID, and it removes the version before this validation + // 2. Epoch is registered in x/epochs + // 3. All the assetIDs are registered in x/assets + // We don't have to check for anything else, but we should store some of this stuff + // within this module (or potentially load it from the AVS module). + epochInfo, found := k.epochsKeeper.GetEpochInfo(ctx, req.EpochIdentifier) + if !found { + return nil, types.ErrInvalidRegistrationParams.Wrapf("epoch not found %s", req.EpochIdentifier) + } + // this value is required by the AVS module when making edits or deleting the AVS. as always, we round it up for the + // current epoch. it can never be 0, because both the durations are positive. + unbondingEpochs := math.Ceil(float64(req.SubscriberParams.UnbondingPeriod) / float64(epochInfo.Duration)) + if _, err := k.avsKeeper.RegisterAVSWithChainID(ctx, &avstypes.AVSRegisterOrDeregisterParams{ + AvsName: req.ChainID, + AssetID: req.AssetIDs, + UnbondingPeriod: uint64(unbondingEpochs), // estimated + MinSelfDelegation: req.MinSelfDelegationUsd, + EpochIdentifier: req.EpochIdentifier, + ChainID: req.ChainID, + // TODO: remove the owner role and make it controllable by subscriber-governance + AvsOwnerAddress: []string{req.FromAddress}, + }); err != nil { + return nil, types.ErrInvalidRegistrationParams.Wrap(err.Error()) + } + // store the data here to generate the genesis state of the subscriber at the end of the current epoch, in the + // AfterEpochEnd hook. + k.AppendPendingSubChain(ctx, req.EpochIdentifier, uint64(epochInfo.CurrentEpoch), req) + return &types.RegisterSubscriberChainResponse{}, nil +} + +// AppendPendingSubChain appends a pending subscriber chain to be started at the epoch-th epochIdentifier. +func (k Keeper) AppendPendingSubChain( + ctx sdk.Context, + epochIdentifier string, + epoch uint64, + req *types.RegisterSubscriberChainRequest, +) { + store := ctx.KVStore(k.storeKey) + key := types.PendingSubscriberChainKey(epochIdentifier, epoch) + prev := k.GetPendingSubChains(ctx, epochIdentifier, epoch) + // it is stored in the order of message processing + prev.List = append(prev.List, *req) + store.Set(key, k.cdc.MustMarshal(&prev)) +} + +// GetPendingSubChains gets the pending subscriber chains to be started at the epoch-th epochIdentifier. +func (k Keeper) GetPendingSubChains( + ctx sdk.Context, epochIdentifier string, epoch uint64, +) types.PendingSubscriberChainRequests { + store := ctx.KVStore(k.storeKey) + key := types.PendingSubscriberChainKey(epochIdentifier, epoch) + var res types.PendingSubscriberChainRequests + if store.Has(key) { + k.cdc.MustUnmarshal(store.Get(key), &res) + } + return res +} + +// ClearPendingSubChains clears the pending subscriber chains to be started at the epoch-th epochIdentifier. +func (k Keeper) ClearPendingSubChains( + ctx sdk.Context, epochIdentifier string, epoch uint64, +) { + store := ctx.KVStore(k.storeKey) + key := types.PendingSubscriberChainKey(epochIdentifier, epoch) + store.Delete(key) +} diff --git a/x/appchain/coordinator/keeper/slash.go b/x/appchain/coordinator/keeper/slash.go new file mode 100644 index 000000000..7c7046e3a --- /dev/null +++ b/x/appchain/coordinator/keeper/slash.go @@ -0,0 +1,50 @@ +package keeper + +import ( + "time" + + types "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// TODO: this file should be in the x/avs keeper instead. + +// SetSubSlashFractionDowntime sets the sub slash fraction downtime for a chain +func (k Keeper) SetSubSlashFractionDowntime(ctx sdk.Context, chainID string, fraction string) { + store := ctx.KVStore(k.storeKey) + store.Set([]byte(types.SubSlashFractionDowntimeKey(chainID)), []byte(fraction)) +} + +// GetSubSlashFractionDowntime gets the sub slash fraction downtime for a chain +func (k Keeper) GetSubSlashFractionDowntime(ctx sdk.Context, chainID string) string { + store := ctx.KVStore(k.storeKey) + key := types.SubSlashFractionDowntimeKey(chainID) + return string(store.Get(key)) +} + +// SetSubSlashFractionDoubleSign sets the sub slash fraction double sign for a chain +func (k Keeper) SetSubSlashFractionDoubleSign(ctx sdk.Context, chainID string, fraction string) { + store := ctx.KVStore(k.storeKey) + store.Set(types.SubSlashFractionDoubleSignKey(chainID), []byte(fraction)) +} + +// GetSubSlashFractionDoubleSign gets the sub slash fraction double sign for a chain +func (k Keeper) GetSubSlashFractionDoubleSign(ctx sdk.Context, chainID string) string { + store := ctx.KVStore(k.storeKey) + key := types.SubSlashFractionDoubleSignKey(chainID) + return string(store.Get(key)) +} + +// SetSubDowntimeJailDuration sets the sub downtime jail duration for a chain +func (k Keeper) SetSubDowntimeJailDuration(ctx sdk.Context, chainID string, duration time.Duration) { + store := ctx.KVStore(k.storeKey) + // duration is always positive + store.Set(types.SubDowntimeJailDurationKey(chainID), sdk.Uint64ToBigEndian(uint64(duration))) +} + +// GetSubDowntimeJailDuration gets the sub downtime jail duration for a chain +func (k Keeper) GetSubDowntimeJailDuration(ctx sdk.Context, chainID string) time.Duration { + store := ctx.KVStore(k.storeKey) + key := types.SubDowntimeJailDurationKey(chainID) + return time.Duration(sdk.BigEndianToUint64(store.Get(key))) +} diff --git a/x/appchain/coordinator/keeper/timeout.go b/x/appchain/coordinator/keeper/timeout.go new file mode 100644 index 000000000..d0a764a91 --- /dev/null +++ b/x/appchain/coordinator/keeper/timeout.go @@ -0,0 +1,62 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// AppendChainToInitTimeout appends a chain to the list of chains which will timeout (if not +// initialized by then) at the end of the epoch. +func (k Keeper) AppendChainToInitTimeout( + ctx sdk.Context, epoch epochstypes.Epoch, chainID string, +) { + prev := k.GetChainsToInitTimeout(ctx, epoch) + prev.List = append(prev.List, chainID) + k.SetChainsToInitTimeout(ctx, epoch, prev) +} + +// GetChainsToInitTimeout returns the list of chains which will timeout (if not initialized by then) +// at the end of the epoch. +func (k Keeper) GetChainsToInitTimeout( + ctx sdk.Context, epoch epochstypes.Epoch, +) (res types.ChainIDs) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.InitTimeoutEpochKey(epoch)) + k.cdc.MustUnmarshal(bz, &res) + return res +} + +// SetChainsToInitTimeout sets the list of chains which will timeout (if not initialized by then) +// at the end of the epoch. +func (k Keeper) SetChainsToInitTimeout( + ctx sdk.Context, epoch epochstypes.Epoch, chains types.ChainIDs, +) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&chains) + store.Set(types.InitTimeoutEpochKey(epoch), bz) +} + +// RemoveChainFromInitTimeout removes a chain from the list of chains which will timeout (if not +// initialized by then) at the end of the epoch. +func (k Keeper) RemoveChainFromInitTimeout( + ctx sdk.Context, epoch epochstypes.Epoch, chainID string, +) { + prev := k.GetChainsToInitTimeout(ctx, epoch) + for i, id := range prev.List { + if id == chainID { + prev.List = append(prev.List[:i], prev.List[i+1:]...) + break + } + } + k.SetChainsToInitTimeout(ctx, epoch, prev) +} + +// ClearChainsToInitTimeout clears the list of chains which will timeout (if not initialized by then) +// at the end of the epoch. +func (k Keeper) ClearChainsToInitTimeout( + ctx sdk.Context, epoch epochstypes.Epoch, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.InitTimeoutEpochKey(epoch)) +} diff --git a/x/appchain/coordinator/types/codec.go b/x/appchain/coordinator/types/codec.go index 8883bdf68..a98707ec8 100644 --- a/x/appchain/coordinator/types/codec.go +++ b/x/appchain/coordinator/types/codec.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/msgservice" ) -func RegisterCodec(cdc *codec.LegacyAmino) { +func RegisterCodec(*codec.LegacyAmino) { // this line is used by starport scaffolding # 2 } diff --git a/x/appchain/coordinator/types/coordinator.pb.go b/x/appchain/coordinator/types/coordinator.pb.go new file mode 100644 index 000000000..ba10cad72 --- /dev/null +++ b/x/appchain/coordinator/types/coordinator.pb.go @@ -0,0 +1,513 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/coordinator/v1/coordinator.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// PendingSubscriberChainRequests is a helper structure to store a list of +// subscriber chain requests that are pending activation. +type PendingSubscriberChainRequests struct { + // list is the list of subscriber chain requests that are pending activation. + List []RegisterSubscriberChainRequest `protobuf:"bytes,1,rep,name=list,proto3" json:"list"` +} + +func (m *PendingSubscriberChainRequests) Reset() { *m = PendingSubscriberChainRequests{} } +func (m *PendingSubscriberChainRequests) String() string { return proto.CompactTextString(m) } +func (*PendingSubscriberChainRequests) ProtoMessage() {} +func (*PendingSubscriberChainRequests) Descriptor() ([]byte, []int) { + return fileDescriptor_fb7bb04617dc0e61, []int{0} +} +func (m *PendingSubscriberChainRequests) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PendingSubscriberChainRequests) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PendingSubscriberChainRequests.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PendingSubscriberChainRequests) XXX_Merge(src proto.Message) { + xxx_messageInfo_PendingSubscriberChainRequests.Merge(m, src) +} +func (m *PendingSubscriberChainRequests) XXX_Size() int { + return m.Size() +} +func (m *PendingSubscriberChainRequests) XXX_DiscardUnknown() { + xxx_messageInfo_PendingSubscriberChainRequests.DiscardUnknown(m) +} + +var xxx_messageInfo_PendingSubscriberChainRequests proto.InternalMessageInfo + +func (m *PendingSubscriberChainRequests) GetList() []RegisterSubscriberChainRequest { + if m != nil { + return m.List + } + return nil +} + +// ChainIDs is a helper structure to store a list of chain IDs. +type ChainIDs struct { + // list is the list of chain IDs. + List []string `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` +} + +func (m *ChainIDs) Reset() { *m = ChainIDs{} } +func (m *ChainIDs) String() string { return proto.CompactTextString(m) } +func (*ChainIDs) ProtoMessage() {} +func (*ChainIDs) Descriptor() ([]byte, []int) { + return fileDescriptor_fb7bb04617dc0e61, []int{1} +} +func (m *ChainIDs) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ChainIDs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChainIDs.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ChainIDs) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChainIDs.Merge(m, src) +} +func (m *ChainIDs) XXX_Size() int { + return m.Size() +} +func (m *ChainIDs) XXX_DiscardUnknown() { + xxx_messageInfo_ChainIDs.DiscardUnknown(m) +} + +var xxx_messageInfo_ChainIDs proto.InternalMessageInfo + +func (m *ChainIDs) GetList() []string { + if m != nil { + return m.List + } + return nil +} + +func init() { + proto.RegisterType((*PendingSubscriberChainRequests)(nil), "exocore.appchain.coordinator.v1.PendingSubscriberChainRequests") + proto.RegisterType((*ChainIDs)(nil), "exocore.appchain.coordinator.v1.ChainIDs") +} + +func init() { + proto.RegisterFile("exocore/appchain/coordinator/v1/coordinator.proto", fileDescriptor_fb7bb04617dc0e61) +} + +var fileDescriptor_fb7bb04617dc0e61 = []byte{ + // 254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0x4c, 0xad, 0xc8, 0x4f, + 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, + 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0x44, 0xe6, 0xea, 0x15, 0x14, + 0xe5, 0x97, 0xe4, 0x0b, 0xc9, 0x43, 0xb5, 0xe8, 0xc1, 0xb4, 0xe8, 0x21, 0xab, 0x29, 0x33, 0x94, + 0xd2, 0x20, 0x64, 0x66, 0x49, 0x05, 0xc4, 0x28, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0x30, 0x53, + 0x1f, 0xc4, 0x82, 0x88, 0x2a, 0x55, 0x73, 0xc9, 0x05, 0xa4, 0xe6, 0xa5, 0x64, 0xe6, 0xa5, 0x07, + 0x97, 0x26, 0x15, 0x27, 0x17, 0x65, 0x26, 0xa5, 0x16, 0x39, 0x83, 0xcc, 0x09, 0x4a, 0x2d, 0x2c, + 0x4d, 0x2d, 0x2e, 0x29, 0x16, 0x8a, 0xe4, 0x62, 0xc9, 0xc9, 0x2c, 0x2e, 0x91, 0x60, 0x54, 0x60, + 0xd6, 0xe0, 0x36, 0xb2, 0xd7, 0x23, 0xe0, 0x22, 0xbd, 0xa0, 0xd4, 0xf4, 0xcc, 0xe2, 0x92, 0xd4, + 0x22, 0xec, 0xe6, 0x39, 0xb1, 0x9c, 0xb8, 0x27, 0xcf, 0x10, 0x04, 0x36, 0x52, 0x49, 0x8e, 0x8b, + 0x03, 0x2c, 0xe7, 0xe9, 0x52, 0x2c, 0x24, 0x84, 0x64, 0x0d, 0x27, 0x44, 0xde, 0x29, 0xe2, 0xc4, + 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, + 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xec, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, + 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x5d, 0x21, 0x0e, 0xf2, 0x4b, 0x2d, 0x29, 0xcf, 0x2f, 0xca, 0xd6, + 0x87, 0x05, 0x48, 0x05, 0xf6, 0x20, 0x29, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0xfb, 0xde, + 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x4d, 0xb2, 0xe2, 0x02, 0x93, 0x01, 0x00, 0x00, +} + +func (m *PendingSubscriberChainRequests) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PendingSubscriberChainRequests) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PendingSubscriberChainRequests) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.List) > 0 { + for iNdEx := len(m.List) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.List[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCoordinator(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ChainIDs) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ChainIDs) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ChainIDs) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.List) > 0 { + for iNdEx := len(m.List) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.List[iNdEx]) + copy(dAtA[i:], m.List[iNdEx]) + i = encodeVarintCoordinator(dAtA, i, uint64(len(m.List[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintCoordinator(dAtA []byte, offset int, v uint64) int { + offset -= sovCoordinator(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *PendingSubscriberChainRequests) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.List) > 0 { + for _, e := range m.List { + l = e.Size() + n += 1 + l + sovCoordinator(uint64(l)) + } + } + return n +} + +func (m *ChainIDs) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.List) > 0 { + for _, s := range m.List { + l = len(s) + n += 1 + l + sovCoordinator(uint64(l)) + } + } + return n +} + +func sovCoordinator(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozCoordinator(x uint64) (n int) { + return sovCoordinator(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PendingSubscriberChainRequests) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PendingSubscriberChainRequests: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PendingSubscriberChainRequests: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field List", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCoordinator + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCoordinator + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.List = append(m.List, RegisterSubscriberChainRequest{}) + if err := m.List[len(m.List)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCoordinator(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCoordinator + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ChainIDs) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ChainIDs: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChainIDs: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field List", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCoordinator + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCoordinator + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.List = append(m.List, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCoordinator(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCoordinator + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipCoordinator(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCoordinator + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCoordinator + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCoordinator + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthCoordinator + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupCoordinator + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthCoordinator + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthCoordinator = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowCoordinator = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupCoordinator = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/coordinator/types/errors.go b/x/appchain/coordinator/types/errors.go new file mode 100644 index 000000000..318378878 --- /dev/null +++ b/x/appchain/coordinator/types/errors.go @@ -0,0 +1,23 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" +) + +const ( + errCodeInvalidParams = iota + 2 + errCodeNilRequest + errCodeDuplicateSubChain + errCodeNoOperators +) + +var ( + // ErrInvalidRegistrationParams is the error returned when the subscriber chain registration params are invalid + ErrInvalidRegistrationParams = errorsmod.Register(ModuleName, errCodeInvalidParams, "invalid registration params") + // ErrNilRequest is the error returned when the request is nil + ErrNilRequest = errorsmod.Register(ModuleName, errCodeNilRequest, "nil request") + // ErrDuplicateSubChain is the error returned when a client for the chain already exists + ErrDuplicateSubChain = errorsmod.Register(ModuleName, errCodeDuplicateSubChain, "subscriber chain already exists") + // ErrNoOperators is the error returned when no qualified operators are available + ErrNoOperators = errorsmod.Register(ModuleName, errCodeNoOperators, "no operators available") +) diff --git a/x/appchain/coordinator/types/events.go b/x/appchain/coordinator/types/events.go new file mode 100644 index 000000000..fd76af38d --- /dev/null +++ b/x/appchain/coordinator/types/events.go @@ -0,0 +1,9 @@ +package types + +const ( + EventTypeSubscriberClientCreated = "subscriber_client_created" + AttributeInitialHeight = "initial_height" + AttributeInitializationTimeout = "initialization_timeout" + AttributeTrustingPeriod = "trusting_period" + AttributeUnbondingPeriod = "unbonding_period" +) diff --git a/x/appchain/coordinator/types/expected_keepers.go b/x/appchain/coordinator/types/expected_keepers.go new file mode 100644 index 000000000..52d8c568a --- /dev/null +++ b/x/appchain/coordinator/types/expected_keepers.go @@ -0,0 +1,34 @@ +package types + +import ( + time "time" + + avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" +) + +// AVSKeeper represents the expected keeper interface for the AVS module. +type AVSKeeper interface { + RegisterAVSWithChainID(sdk.Context, *avstypes.AVSRegisterOrDeregisterParams) (common.Address, error) + IsAVSByChainID(sdk.Context, string) (bool, common.Address) + DeleteAVSInfo(sdk.Context, common.Address) error +} + +// EpochsKeeper represents the expected keeper interface for the epochs module. +type EpochsKeeper interface { + GetEpochInfo(sdk.Context, string) (epochstypes.EpochInfo, bool) +} + +// StakingKeeper represents the expected keeper interface for the staking module. +type StakingKeeper interface { + UnbondingTime(sdk.Context) time.Duration +} + +// OperatorKeeper represents the expected keeper interface for the operator module. +type OperatorKeeper interface { + GetActiveOperatorsForChainID(sdk.Context, string) ([]sdk.AccAddress, []operatortypes.WrappedConsKey) + GetVotePowerForChainID(sdk.Context, []sdk.AccAddress, string) ([]int64, error) +} diff --git a/x/appchain/coordinator/types/genesis.go b/x/appchain/coordinator/types/genesis.go index 255e60642..97f1d627e 100644 --- a/x/appchain/coordinator/types/genesis.go +++ b/x/appchain/coordinator/types/genesis.go @@ -17,5 +17,6 @@ func (gs GenesisState) Validate() error { if err := gs.Params.Validate(); err != nil { return err } + // TODO: validate anything else added here return nil } diff --git a/x/appchain/coordinator/types/keys.go b/x/appchain/coordinator/types/keys.go index 00cd54a80..907000965 100644 --- a/x/appchain/coordinator/types/keys.go +++ b/x/appchain/coordinator/types/keys.go @@ -1,5 +1,10 @@ package types +import ( + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + const ( // ModuleName defines the module name ModuleName = "coordinator" @@ -13,8 +18,8 @@ const ( // MemStoreKey defines the in-memory store key MemStoreKey = "mem_coordinator" - // PortId is the default port id that the module binds to - PortId = "coordinator" + // PortID is the default port id that the module binds to + PortID = "coordinator" // SubscriberRewardsPool is the address that receives the rewards from the subscriber // chains. Technically, it is possible for the subscriber chain to send these rewards @@ -24,9 +29,83 @@ const ( ) const ( + // ParamsBytePrefix is the prefix for the coordinator module's parameters key ParamsBytePrefix byte = iota + 1 + // PendingSubscriberChainBytePrefix is the prefix for the coordinator module's pending subscriber chain key + PendingSubscriberChainBytePrefix + // ClientForChainBytePrefix is the prefix to store mapping from chain to client + ClientForChainBytePrefix + // SubSlashFractionDowntimeBytePrefix is the prefix to store the slashing fraction for downtime + // against a particular chain. + SubSlashFractionDowntimeBytePrefix + // SubSlashFractionDoubleSignBytePrefix is the prefix to store the slashing fraction for double sign + // against a particular chain. + SubSlashFractionDoubleSignBytePrefix + // SubDowntimeJailDurationBytePrefix is the prefix to store the downtime jail duration for a chain + SubDowntimeJailDurationBytePrefix + // SubscriberGenesisBytePrefix is the prefix for the subscriber genesis key + SubscriberGenesisBytePrefix + // InitTimeoutBytePrefix is the prefix for the init timeout key + InitTimeoutBytePrefix ) +// AppendMany appends a variable number of byte slices together +func AppendMany(byteses ...[]byte) (out []byte) { + for _, bytes := range byteses { + out = append(out, bytes...) + } + return out +} + func ParamsKey() []byte { return []byte{ParamsBytePrefix} } + +// PendingSubscriberChainKey is the key used to store subscriber chains, which are scheduled +// to begin with the starting of the epoch with identifier and number. Since the data +// is stored alphabetically, this key structure is apt. +func PendingSubscriberChainKey(epochIdentifier string, epochNumber uint64) []byte { + return AppendMany( + []byte{PendingSubscriberChainBytePrefix}, + []byte(epochIdentifier), + sdk.Uint64ToBigEndian(epochNumber), + ) +} + +// ClientForChainKey returns the key under which the clientId for the given chainId is stored. +func ClientForChainKey(chainId string) []byte { + return append([]byte{ClientForChainBytePrefix}, []byte(chainId)...) +} + +// SubSlashFractionDowntimeKey returns the key under which the slashing fraction for downtime +// against a particular chain is stored. +func SubSlashFractionDowntimeKey(chainId string) []byte { + return append([]byte{SubSlashFractionDowntimeBytePrefix}, []byte(chainId)...) +} + +// SubSlashFractionDoubleSignKey returns the key under which the slashing fraction for double sign +// against a particular chain is stored. +func SubSlashFractionDoubleSignKey(chainId string) []byte { + return append([]byte{SubSlashFractionDoubleSignBytePrefix}, []byte(chainId)...) +} + +// SubDowntimeJailDurationKey returns the key under which the downtime jail duration for a chain +// is stored. +func SubDowntimeJailDurationKey(chainId string) []byte { + return append([]byte{SubDowntimeJailDurationBytePrefix}, []byte(chainId)...) +} + +// SubscriberGenesisKey returns the key under which the genesis state for a subscriber chain is stored. +func SubscriberGenesisKey(chainId string) []byte { + return append([]byte{SubscriberGenesisBytePrefix}, []byte(chainId)...) +} + +// InitTimeoutEpochKey returns the key under which the list of chains which will timeout (if not +// initialized by then) at the beginning of the epoch is stored. +func InitTimeoutEpochKey(epoch epochstypes.Epoch) []byte { + return AppendMany( + []byte{InitTimeoutBytePrefix}, + []byte(epoch.EpochIdentifier), + sdk.Uint64ToBigEndian(epoch.EpochNumber), + ) +} diff --git a/x/appchain/coordinator/types/msg.go b/x/appchain/coordinator/types/msg.go new file mode 100644 index 000000000..953886b96 --- /dev/null +++ b/x/appchain/coordinator/types/msg.go @@ -0,0 +1,86 @@ +package types + +import ( + fmt "fmt" + "strings" + + sdkerrors "cosmossdk.io/errors" + assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" + epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" + "github.com/cometbft/cometbft/libs/json" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const TypeRegisterSubscriberChain = "register_subscriber_chain" + +var _ sdk.Msg = &RegisterSubscriberChainRequest{} + +func (msg *RegisterSubscriberChainRequest) Route() string { + return RouterKey +} + +func (msg *RegisterSubscriberChainRequest) Type() string { + return TypeRegisterSubscriberChain +} + +// GetSignBytes returns the raw bytes for a RegisterSubscriberChainRequest message that +// the expected signer needs to sign. +func (msg *RegisterSubscriberChainRequest) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +// ValidateBasic executes sanity validation on the provided data +// MsgUpdateParams is used to update params, the validation will mostly be stateful which is done by service +func (msg *RegisterSubscriberChainRequest) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.FromAddress); err != nil { + return sdkerrors.Wrap(err, "invalid from address") + } + // the chainID must be non-empty; there is no maximum length imposed + chainID := strings.TrimSpace(msg.ChainID) + if val := len(chainID); val == 0 { + return fmt.Errorf("invalid chain id %s %d", chainID, val) + } + if epochstypes.ValidateEpochIdentifierString(msg.EpochIdentifier) != nil { + return fmt.Errorf("invalid epoch identifier %s", msg.EpochIdentifier) + } + for _, assetID := range msg.AssetIDs { + if _, _, err := assetstypes.ValidateID( + assetID, + true, // the caller must make them lowercase + true, // TODO: we support only Ethereum assets for now. + ); err != nil { + return fmt.Errorf("invalid asset id %s: %s", assetID, err) + } + } + if msg.MaxValidators == 0 { + return fmt.Errorf("invalid max validators %d", msg.MaxValidators) + } + // no need to validate min self delegation, it is a uint64 + if err := msg.SubscriberParams.Validate(); err != nil { + return fmt.Errorf("invalid subscriber params: %s", err) + } + return nil +} + +// GetSigners returns the expected signers for a MsgUpdateParams message +func (msg *RegisterSubscriberChainRequest) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(msg.FromAddress) + if err != nil { + // same behavior as cosmos-sdk + panic(err) + } + return []sdk.AccAddress{addr} +} + +// NewRegisterSubscriberChainRequest creates a new RegisterSubscriberChainRequest using +// the provided creator and json value. +func NewRegisterSubscriberChainRequest(creator, jsonValue string) *RegisterSubscriberChainRequest { + var r RegisterSubscriberChainRequest + if err := json.Unmarshal([]byte(jsonValue), &r); err != nil { + panic(fmt.Sprintf("invalid json %s", err)) + } + // the creator is overwritten + r.FromAddress = creator + return &r +} diff --git a/x/appchain/coordinator/types/query.pb.go b/x/appchain/coordinator/types/query.pb.go index 7a99171a7..34e8bba1d 100644 --- a/x/appchain/coordinator/types/query.pb.go +++ b/x/appchain/coordinator/types/query.pb.go @@ -6,6 +6,7 @@ package types import ( context "context" fmt "fmt" + types "github.com/ExocoreNetwork/exocore/x/appchain/common/types" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" @@ -29,6 +30,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// QueryParamsRequest is the request type for the Query.QueryParams RPC method. type QueryParamsRequest struct { } @@ -65,7 +67,9 @@ func (m *QueryParamsRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo +// QueryParamsResponse is the response type for the Query.QueryParams RPC method. type QueryParamsResponse struct { + // params is the parameters for the appchain coordinator module. Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` } @@ -109,9 +113,103 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } +// QuerySubscriberGenesisRequest is the request type for the Query.QuerySubscriberGenesis RPC method. +type QuerySubscriberGenesisRequest struct { + // chain is the chain ID of the subscriber chain. we intentionally don't use ChainID so that + // the query can work (it does not support custom names). + Chain string `protobuf:"bytes,1,opt,name=chain,proto3" json:"chain,omitempty"` +} + +func (m *QuerySubscriberGenesisRequest) Reset() { *m = QuerySubscriberGenesisRequest{} } +func (m *QuerySubscriberGenesisRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySubscriberGenesisRequest) ProtoMessage() {} +func (*QuerySubscriberGenesisRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c71eb5ef95876a4b, []int{2} +} +func (m *QuerySubscriberGenesisRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySubscriberGenesisRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySubscriberGenesisRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySubscriberGenesisRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySubscriberGenesisRequest.Merge(m, src) +} +func (m *QuerySubscriberGenesisRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySubscriberGenesisRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySubscriberGenesisRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySubscriberGenesisRequest proto.InternalMessageInfo + +func (m *QuerySubscriberGenesisRequest) GetChain() string { + if m != nil { + return m.Chain + } + return "" +} + +// QuerySubscriberGenesisResponse is the response type for the Query.QuerySubscriberGenesis RPC method. +type QuerySubscriberGenesisResponse struct { + SubscriberGenesis types.SubscriberGenesisState `protobuf:"bytes,1,opt,name=subscriber_genesis,json=subscriberGenesis,proto3" json:"subscriber_genesis"` +} + +func (m *QuerySubscriberGenesisResponse) Reset() { *m = QuerySubscriberGenesisResponse{} } +func (m *QuerySubscriberGenesisResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySubscriberGenesisResponse) ProtoMessage() {} +func (*QuerySubscriberGenesisResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c71eb5ef95876a4b, []int{3} +} +func (m *QuerySubscriberGenesisResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySubscriberGenesisResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySubscriberGenesisResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySubscriberGenesisResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySubscriberGenesisResponse.Merge(m, src) +} +func (m *QuerySubscriberGenesisResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySubscriberGenesisResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySubscriberGenesisResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySubscriberGenesisResponse proto.InternalMessageInfo + +func (m *QuerySubscriberGenesisResponse) GetSubscriberGenesis() types.SubscriberGenesisState { + if m != nil { + return m.SubscriberGenesis + } + return types.SubscriberGenesisState{} +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "exocore.appchain.coordinator.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "exocore.appchain.coordinator.v1.QueryParamsResponse") + proto.RegisterType((*QuerySubscriberGenesisRequest)(nil), "exocore.appchain.coordinator.v1.QuerySubscriberGenesisRequest") + proto.RegisterType((*QuerySubscriberGenesisResponse)(nil), "exocore.appchain.coordinator.v1.QuerySubscriberGenesisResponse") } func init() { @@ -119,26 +217,34 @@ func init() { } var fileDescriptor_c71eb5ef95876a4b = []byte{ - // 299 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0xad, 0xc8, 0x4f, - 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, - 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, - 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x87, 0x2a, 0xd6, 0x83, 0x29, 0xd6, 0x43, - 0x52, 0xac, 0x57, 0x66, 0x28, 0xa5, 0x43, 0xc8, 0xb4, 0x82, 0xc4, 0xa2, 0xc4, 0xdc, 0x62, 0x88, - 0x71, 0x52, 0x32, 0xe9, 0xf9, 0xf9, 0xe9, 0x39, 0x20, 0xc5, 0x99, 0xfa, 0x89, 0x79, 0x79, 0xf9, - 0x25, 0x89, 0x25, 0x99, 0xf9, 0x79, 0x30, 0x59, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0x30, 0x53, 0x1f, - 0xc4, 0x82, 0x88, 0x2a, 0x89, 0x70, 0x09, 0x05, 0x82, 0x5c, 0x14, 0x00, 0x36, 0x28, 0x28, 0xb5, - 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x29, 0x86, 0x4b, 0x18, 0x45, 0xb4, 0xb8, 0x20, 0x3f, 0xaf, 0x38, - 0x55, 0xc8, 0x95, 0x8b, 0x0d, 0x62, 0xa1, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0xba, 0x1e, - 0x01, 0x0f, 0xe8, 0x41, 0x0c, 0x70, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0xd9, 0x68, - 0x31, 0x23, 0x17, 0x2b, 0xd8, 0x78, 0xa1, 0x99, 0x8c, 0x5c, 0x6c, 0x10, 0x25, 0x42, 0xc6, 0x04, - 0xcd, 0xc2, 0x74, 0xa7, 0x94, 0x09, 0x69, 0x9a, 0x20, 0xde, 0x50, 0x52, 0x69, 0xba, 0xfc, 0x64, - 0x32, 0x93, 0x9c, 0x90, 0x0c, 0xf6, 0x60, 0x85, 0xb8, 0xd2, 0x29, 0xe2, 0xc4, 0x23, 0x39, 0xc6, - 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, - 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xec, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, - 0x73, 0xf5, 0x5d, 0x21, 0xf6, 0xfb, 0xa5, 0x96, 0x94, 0xe7, 0x17, 0x65, 0xeb, 0xc3, 0xe2, 0xab, - 0x02, 0xbb, 0xd1, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0xa0, 0x37, 0x06, 0x04, 0x00, - 0x00, 0xff, 0xff, 0x29, 0x90, 0x68, 0x5f, 0x2c, 0x02, 0x00, 0x00, + // 427 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x41, 0x8b, 0xd3, 0x40, + 0x14, 0xce, 0xa8, 0xbb, 0xe0, 0xec, 0xc9, 0xb1, 0x88, 0x84, 0x75, 0x56, 0x82, 0xb0, 0x82, 0x92, + 0xa1, 0x5d, 0x3d, 0x89, 0x2b, 0x54, 0x8a, 0x37, 0xd1, 0xf6, 0x22, 0x22, 0xc8, 0x24, 0x0e, 0x69, + 0xd0, 0xce, 0x4b, 0x67, 0x26, 0xb5, 0x45, 0xbc, 0x78, 0xeb, 0x4d, 0xf0, 0xee, 0xef, 0xe9, 0xb1, + 0xe0, 0xc5, 0x53, 0x91, 0xd6, 0x1f, 0x22, 0x99, 0x49, 0x4b, 0xb5, 0x29, 0x51, 0x6f, 0x93, 0x79, + 0xdf, 0xfb, 0xbe, 0xef, 0x7d, 0x6f, 0x82, 0xef, 0x88, 0x31, 0xc4, 0xa0, 0x04, 0xe3, 0x59, 0x16, + 0xf7, 0x79, 0x2a, 0x59, 0x0c, 0xa0, 0xde, 0xa4, 0x92, 0x1b, 0x50, 0x6c, 0xd4, 0x64, 0xc3, 0x5c, + 0xa8, 0x49, 0x98, 0x29, 0x30, 0x40, 0x4e, 0x4a, 0x70, 0xb8, 0x06, 0x87, 0x5b, 0xe0, 0x70, 0xd4, + 0xf4, 0x4f, 0x2b, 0xd8, 0x06, 0x03, 0x90, 0x05, 0x91, 0x3b, 0x39, 0x26, 0xff, 0x6e, 0x9d, 0x6c, + 0xc6, 0x15, 0x1f, 0xe8, 0x12, 0x7d, 0x9c, 0x00, 0x24, 0xef, 0x0a, 0x70, 0xca, 0xb8, 0x94, 0x60, + 0xb8, 0x49, 0x41, 0xae, 0xab, 0x8d, 0x04, 0x12, 0xb0, 0x47, 0x56, 0x9c, 0xdc, 0x6d, 0xd0, 0xc0, + 0xe4, 0x79, 0x61, 0xfd, 0x99, 0x25, 0xea, 0x8a, 0x61, 0x2e, 0xb4, 0x09, 0x5e, 0xe1, 0xab, 0xbf, + 0xdd, 0xea, 0x0c, 0xa4, 0x16, 0xa4, 0x83, 0x0f, 0x9d, 0xe0, 0x75, 0x74, 0x13, 0xdd, 0x3e, 0x6a, + 0x9d, 0x86, 0x35, 0x93, 0x86, 0x8e, 0xa0, 0x7d, 0x69, 0xb6, 0x38, 0xf1, 0xba, 0x65, 0x73, 0x70, + 0x1f, 0xdf, 0xb0, 0xec, 0xbd, 0x3c, 0xd2, 0xb1, 0x4a, 0x23, 0xa1, 0x9e, 0x08, 0x29, 0x74, 0xba, + 0x96, 0x27, 0x0d, 0x7c, 0x60, 0xd9, 0xac, 0xcc, 0xe5, 0xae, 0xfb, 0x08, 0xa6, 0x08, 0xd3, 0x7d, + 0x7d, 0xa5, 0xc1, 0x04, 0x13, 0xbd, 0x29, 0xbe, 0x4e, 0x5c, 0xb5, 0x34, 0xdb, 0xaa, 0x32, 0x6b, + 0xb3, 0x1e, 0x35, 0xc3, 0x1d, 0xca, 0x9e, 0xe1, 0x46, 0x94, 0xbe, 0xaf, 0xe8, 0x3f, 0xab, 0xad, + 0xe9, 0x45, 0x7c, 0x60, 0xbd, 0x90, 0xaf, 0x08, 0x1f, 0x6d, 0x65, 0x45, 0xce, 0x6a, 0x33, 0xd9, + 0xcd, 0xdb, 0xbf, 0xf7, 0x6f, 0x4d, 0x6e, 0xda, 0xe0, 0xd6, 0xa7, 0x6f, 0x3f, 0xbf, 0x5c, 0xa0, + 0xe4, 0xb8, 0xfa, 0x79, 0xb8, 0xb4, 0xc9, 0x02, 0xe1, 0x6b, 0xd5, 0xb1, 0x91, 0xf3, 0xbf, 0x93, + 0xdd, 0xb7, 0x27, 0xff, 0xd1, 0x7f, 0xf7, 0x97, 0x13, 0x3c, 0xb6, 0x13, 0x3c, 0x24, 0x0f, 0x58, + 0xdd, 0x43, 0xdf, 0x5d, 0x2b, 0xfb, 0x60, 0x81, 0x1f, 0xdb, 0x2f, 0x66, 0x4b, 0x8a, 0xe6, 0x4b, + 0x8a, 0x7e, 0x2c, 0x29, 0xfa, 0xbc, 0xa2, 0xde, 0x7c, 0x45, 0xbd, 0xef, 0x2b, 0xea, 0xbd, 0x3c, + 0x4f, 0x52, 0xd3, 0xcf, 0xa3, 0x62, 0xcf, 0xac, 0xe3, 0x04, 0x9e, 0x0a, 0xf3, 0x1e, 0xd4, 0xdb, + 0x8d, 0xde, 0xb8, 0x5a, 0xd1, 0x4c, 0x32, 0xa1, 0xa3, 0x43, 0xfb, 0x8f, 0x9c, 0xfd, 0x0a, 0x00, + 0x00, 0xff, 0xff, 0xb0, 0x92, 0xd4, 0x9f, 0xfe, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -153,7 +259,10 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // QueryParams returns the appchain coordinator module parameters. + QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // QuerySubscriberGenesis returns the genesis state for a subscriber chain. + QuerySubscriberGenesis(ctx context.Context, in *QuerySubscriberGenesisRequest, opts ...grpc.CallOption) (*QuerySubscriberGenesisResponse, error) } type queryClient struct { @@ -164,9 +273,18 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { +func (c *queryClient) QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/exocore.appchain.coordinator.v1.Query/Params", in, out, opts...) + err := c.cc.Invoke(ctx, "/exocore.appchain.coordinator.v1.Query/QueryParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) QuerySubscriberGenesis(ctx context.Context, in *QuerySubscriberGenesisRequest, opts ...grpc.CallOption) (*QuerySubscriberGenesisResponse, error) { + out := new(QuerySubscriberGenesisResponse) + err := c.cc.Invoke(ctx, "/exocore.appchain.coordinator.v1.Query/QuerySubscriberGenesis", in, out, opts...) if err != nil { return nil, err } @@ -175,35 +293,59 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . // QueryServer is the server API for Query service. type QueryServer interface { - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // QueryParams returns the appchain coordinator module parameters. + QueryParams(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // QuerySubscriberGenesis returns the genesis state for a subscriber chain. + QuerySubscriberGenesis(context.Context, *QuerySubscriberGenesisRequest) (*QuerySubscriberGenesisResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. type UnimplementedQueryServer struct { } -func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +func (*UnimplementedQueryServer) QueryParams(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryParams not implemented") +} +func (*UnimplementedQueryServer) QuerySubscriberGenesis(ctx context.Context, req *QuerySubscriberGenesisRequest) (*QuerySubscriberGenesisResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QuerySubscriberGenesis not implemented") } func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } -func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Query_QueryParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryParamsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).Params(ctx, in) + return srv.(QueryServer).QueryParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/exocore.appchain.coordinator.v1.Query/QueryParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryParams(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_QuerySubscriberGenesis_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySubscriberGenesisRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QuerySubscriberGenesis(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/exocore.appchain.coordinator.v1.Query/Params", + FullMethod: "/exocore.appchain.coordinator.v1.Query/QuerySubscriberGenesis", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + return srv.(QueryServer).QuerySubscriberGenesis(ctx, req.(*QuerySubscriberGenesisRequest)) } return interceptor(ctx, in, info, handler) } @@ -213,8 +355,12 @@ var _Query_serviceDesc = grpc.ServiceDesc{ HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "Params", - Handler: _Query_Params_Handler, + MethodName: "QueryParams", + Handler: _Query_QueryParams_Handler, + }, + { + MethodName: "QuerySubscriberGenesis", + Handler: _Query_QuerySubscriberGenesis_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -277,6 +423,69 @@ func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QuerySubscriberGenesisRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySubscriberGenesisRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySubscriberGenesisRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Chain) > 0 { + i -= len(m.Chain) + copy(dAtA[i:], m.Chain) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Chain))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QuerySubscriberGenesisResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySubscriberGenesisResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySubscriberGenesisResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.SubscriberGenesis.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -308,6 +517,30 @@ func (m *QueryParamsResponse) Size() (n int) { return n } +func (m *QuerySubscriberGenesisRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Chain) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySubscriberGenesisResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.SubscriberGenesis.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -447,6 +680,171 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QuerySubscriberGenesisRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySubscriberGenesisRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySubscriberGenesisRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Chain", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Chain = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySubscriberGenesisResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySubscriberGenesisResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySubscriberGenesisResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubscriberGenesis", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SubscriberGenesis.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/appchain/coordinator/types/query.pb.gw.go b/x/appchain/coordinator/types/query.pb.gw.go index d113a2bb2..0d292bb66 100644 --- a/x/appchain/coordinator/types/query.pb.gw.go +++ b/x/appchain/coordinator/types/query.pb.gw.go @@ -33,20 +33,74 @@ var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage var _ = metadata.Join -func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { +func request_Query_QueryParams_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryParamsRequest var metadata runtime.ServerMetadata - msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.QueryParams(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { +func local_request_Query_QueryParams_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryParamsRequest var metadata runtime.ServerMetadata - msg, err := server.Params(ctx, &protoReq) + msg, err := server.QueryParams(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_QuerySubscriberGenesis_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySubscriberGenesisRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain") + } + + protoReq.Chain, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain", err) + } + + msg, err := client.QuerySubscriberGenesis(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QuerySubscriberGenesis_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySubscriberGenesisRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain") + } + + protoReq.Chain, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain", err) + } + + msg, err := server.QuerySubscriberGenesis(ctx, &protoReq) return msg, metadata, err } @@ -57,7 +111,7 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_QueryParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -68,7 +122,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_QueryParams_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -76,7 +130,30 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_QueryParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QuerySubscriberGenesis_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_QuerySubscriberGenesis_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QuerySubscriberGenesis_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -121,7 +198,27 @@ func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // "QueryClient" to call the correct interceptors. func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_QueryParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_QueryParams_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QuerySubscriberGenesis_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -130,14 +227,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_QuerySubscriberGenesis_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_QuerySubscriberGenesis_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -145,9 +242,13 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"appchain", "coordinator", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_QueryParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"appchain", "coordinator", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QuerySubscriberGenesis_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"exocore", "appchain", "coordinator", "v1", "subscriber_genesis", "chain"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( - forward_Query_Params_0 = runtime.ForwardResponseMessage + forward_Query_QueryParams_0 = runtime.ForwardResponseMessage + + forward_Query_QuerySubscriberGenesis_0 = runtime.ForwardResponseMessage ) diff --git a/x/appchain/coordinator/types/tx.pb.go b/x/appchain/coordinator/types/tx.pb.go index 9135b7536..61ea3e631 100644 --- a/x/appchain/coordinator/types/tx.pb.go +++ b/x/appchain/coordinator/types/tx.pb.go @@ -6,10 +6,19 @@ package types import ( context "context" fmt "fmt" + types "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. @@ -23,22 +32,198 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// RegisterSubscriberChainRequest is the request type for the RegisterSubscriberChain message. +type RegisterSubscriberChainRequest struct { + // from_address is the address of the transaction signer. any transactions + // originating from this address may be used to edit the chain. at some point + // in the future this will be offloaded to the governance module on the + // subscriber chain. (TODO) + FromAddress string `protobuf:"bytes,1,opt,name=from_address,json=fromAddress,proto3" json:"from_address,omitempty"` + // chain_id is the unique identifier for the chain, serving as the primary key. + ChainID string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // epoch_identifier specifies the unit of epoch (week, hour, day). It must be registered in the x/epochs module. + // This epoch is the identifier used by the coordinator to send validator set updates to the subscriber at the + // end of each epoch. The subscriber chain's genesis is made available at the end of the current epoch + // (marked by this identifier). + EpochIdentifier string `protobuf:"bytes,3,opt,name=epoch_identifier,json=epochIdentifier,proto3" json:"epoch_identifier,omitempty"` + // asset_ids lists the IDs of assets accepted by the subscriber chain. + AssetIDs []string `protobuf:"bytes,4,rep,name=asset_ids,json=assetIds,proto3" json:"asset_ids,omitempty"` + // min_self_delegation_usd is the minimum self-delegation in USD required to be a validator on the chain. + MinSelfDelegationUsd uint64 `protobuf:"varint,5,opt,name=min_self_delegation_usd,json=minSelfDelegationUsd,proto3" json:"min_self_delegation_usd,omitempty"` + // max_validators is the maximum number of validators allowed on the chain. + MaxValidators uint32 `protobuf:"varint,6,opt,name=max_validators,json=maxValidators,proto3" json:"max_validators,omitempty"` + // subscriber_params are the parameters used by the subscriber module + // on the subscriber chain. + SubscriberParams types.SubscriberParams `protobuf:"bytes,7,opt,name=subscriber_params,json=subscriberParams,proto3" json:"subscriber_params"` +} + +func (m *RegisterSubscriberChainRequest) Reset() { *m = RegisterSubscriberChainRequest{} } +func (m *RegisterSubscriberChainRequest) String() string { return proto.CompactTextString(m) } +func (*RegisterSubscriberChainRequest) ProtoMessage() {} +func (*RegisterSubscriberChainRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_23c4660f55e25cbc, []int{0} +} +func (m *RegisterSubscriberChainRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RegisterSubscriberChainRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RegisterSubscriberChainRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RegisterSubscriberChainRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RegisterSubscriberChainRequest.Merge(m, src) +} +func (m *RegisterSubscriberChainRequest) XXX_Size() int { + return m.Size() +} +func (m *RegisterSubscriberChainRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RegisterSubscriberChainRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_RegisterSubscriberChainRequest proto.InternalMessageInfo + +func (m *RegisterSubscriberChainRequest) GetFromAddress() string { + if m != nil { + return m.FromAddress + } + return "" +} + +func (m *RegisterSubscriberChainRequest) GetChainID() string { + if m != nil { + return m.ChainID + } + return "" +} + +func (m *RegisterSubscriberChainRequest) GetEpochIdentifier() string { + if m != nil { + return m.EpochIdentifier + } + return "" +} + +func (m *RegisterSubscriberChainRequest) GetAssetIDs() []string { + if m != nil { + return m.AssetIDs + } + return nil +} + +func (m *RegisterSubscriberChainRequest) GetMinSelfDelegationUsd() uint64 { + if m != nil { + return m.MinSelfDelegationUsd + } + return 0 +} + +func (m *RegisterSubscriberChainRequest) GetMaxValidators() uint32 { + if m != nil { + return m.MaxValidators + } + return 0 +} + +func (m *RegisterSubscriberChainRequest) GetSubscriberParams() types.SubscriberParams { + if m != nil { + return m.SubscriberParams + } + return types.SubscriberParams{} +} + +// RegisterSubscriberChainResponse defines the response structure for executing a +// RegisterSubscriberChain message. +type RegisterSubscriberChainResponse struct { +} + +func (m *RegisterSubscriberChainResponse) Reset() { *m = RegisterSubscriberChainResponse{} } +func (m *RegisterSubscriberChainResponse) String() string { return proto.CompactTextString(m) } +func (*RegisterSubscriberChainResponse) ProtoMessage() {} +func (*RegisterSubscriberChainResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_23c4660f55e25cbc, []int{1} +} +func (m *RegisterSubscriberChainResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RegisterSubscriberChainResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RegisterSubscriberChainResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RegisterSubscriberChainResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RegisterSubscriberChainResponse.Merge(m, src) +} +func (m *RegisterSubscriberChainResponse) XXX_Size() int { + return m.Size() +} +func (m *RegisterSubscriberChainResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RegisterSubscriberChainResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RegisterSubscriberChainResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*RegisterSubscriberChainRequest)(nil), "exocore.appchain.coordinator.v1.RegisterSubscriberChainRequest") + proto.RegisterType((*RegisterSubscriberChainResponse)(nil), "exocore.appchain.coordinator.v1.RegisterSubscriberChainResponse") +} + func init() { proto.RegisterFile("exocore/appchain/coordinator/v1/tx.proto", fileDescriptor_23c4660f55e25cbc) } var fileDescriptor_23c4660f55e25cbc = []byte{ - // 154 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x48, 0xad, 0xc8, 0x4f, - 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, - 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, - 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x87, 0xaa, 0xd4, 0x83, 0xa9, 0xd4, 0x43, 0x52, 0xa9, 0x57, - 0x66, 0x68, 0xc4, 0xca, 0xc5, 0xec, 0x5b, 0x9c, 0xee, 0x14, 0x71, 0xe2, 0x91, 0x1c, 0xe3, 0x85, - 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, - 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x76, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, - 0xfa, 0xae, 0x10, 0xc3, 0xfc, 0x52, 0x4b, 0xca, 0xf3, 0x8b, 0xb2, 0xf5, 0x61, 0xae, 0xa8, 0xc0, - 0xee, 0x8e, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x43, 0x8c, 0x01, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x5e, 0x8c, 0x36, 0x21, 0xb4, 0x00, 0x00, 0x00, + // 571 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcf, 0x6a, 0x13, 0x41, + 0x1c, 0xce, 0x36, 0x6d, 0x93, 0x4c, 0x5a, 0x8d, 0x4b, 0x20, 0x6b, 0x90, 0x4d, 0x0c, 0xa8, 0xdb, + 0xa2, 0xbb, 0xa4, 0xe2, 0xc5, 0xe2, 0x9f, 0xa6, 0x51, 0xc8, 0x41, 0x91, 0x0d, 0x8a, 0x78, 0x59, + 0x26, 0x3b, 0x93, 0xcd, 0x60, 0x76, 0x67, 0x9d, 0xdf, 0x24, 0xc6, 0x9b, 0xf4, 0x09, 0x04, 0x5f, + 0xc3, 0x43, 0x0f, 0x3e, 0x44, 0x8f, 0x45, 0x2f, 0x9e, 0x82, 0x26, 0x42, 0xaf, 0x3e, 0x82, 0xec, + 0x6e, 0x9a, 0x8a, 0x24, 0x16, 0xbc, 0xcd, 0x7c, 0x7f, 0xe6, 0xfb, 0xf1, 0xcd, 0x0c, 0x32, 0xe8, + 0x88, 0xbb, 0x5c, 0x50, 0x0b, 0x87, 0xa1, 0xdb, 0xc3, 0x2c, 0xb0, 0x5c, 0xce, 0x05, 0x61, 0x01, + 0x96, 0x5c, 0x58, 0xc3, 0xba, 0x25, 0x47, 0x66, 0x28, 0xb8, 0xe4, 0x6a, 0x65, 0xa6, 0x34, 0x4f, + 0x95, 0xe6, 0x1f, 0x4a, 0x73, 0x58, 0x2f, 0x97, 0x5c, 0x0e, 0x3e, 0x07, 0xcb, 0x07, 0x2f, 0x32, + 0xfa, 0xe0, 0x25, 0xce, 0xf2, 0xe5, 0x84, 0x70, 0xe2, 0x9d, 0x95, 0x6c, 0x66, 0x54, 0xd1, 0xe3, + 0x1e, 0x4f, 0xf0, 0x68, 0x35, 0x43, 0xaf, 0x78, 0x9c, 0x7b, 0xfd, 0x68, 0x26, 0x66, 0xe1, 0x20, + 0xe0, 0x12, 0x4b, 0xc6, 0x83, 0x53, 0xcf, 0x8d, 0x05, 0x23, 0xfb, 0x3e, 0x0f, 0xa2, 0xd0, 0x64, + 0x95, 0x08, 0x6b, 0x9f, 0xd2, 0x48, 0xb7, 0xa9, 0xc7, 0x40, 0x52, 0xd1, 0x1e, 0x74, 0xc0, 0x15, + 0xac, 0x43, 0xc5, 0x7e, 0x64, 0xb1, 0xe9, 0x9b, 0x01, 0x05, 0xa9, 0xee, 0xa2, 0x8d, 0xae, 0xe0, + 0xbe, 0x83, 0x09, 0x11, 0x14, 0x40, 0x53, 0xaa, 0x8a, 0x91, 0x6b, 0x68, 0x5f, 0x3e, 0xdf, 0x2a, + 0xce, 0xe6, 0xdc, 0x4b, 0x98, 0xb6, 0x14, 0x2c, 0xf0, 0xec, 0x7c, 0xa4, 0x9e, 0x41, 0xea, 0x75, + 0x94, 0x8d, 0xf3, 0x1d, 0x46, 0xb4, 0x95, 0xd8, 0x98, 0x9f, 0x8c, 0x2b, 0x99, 0x38, 0xa0, 0xd5, + 0xb4, 0x33, 0x31, 0xd9, 0x22, 0xea, 0x16, 0x2a, 0xd0, 0x90, 0xbb, 0x3d, 0x87, 0x11, 0x1a, 0x48, + 0xd6, 0x65, 0x54, 0x68, 0xe9, 0x48, 0x6f, 0x5f, 0x8c, 0xf1, 0xd6, 0x1c, 0x56, 0xb7, 0x50, 0x0e, + 0x03, 0x50, 0xe9, 0x30, 0x02, 0xda, 0x6a, 0x35, 0x6d, 0xe4, 0x1a, 0x1b, 0x93, 0x71, 0x25, 0xbb, + 0x17, 0x81, 0xad, 0x26, 0xd8, 0xd9, 0x98, 0x6e, 0x11, 0x50, 0xef, 0xa0, 0x92, 0xcf, 0x02, 0x07, + 0x68, 0xbf, 0xeb, 0x10, 0xda, 0xa7, 0x5e, 0x5c, 0x92, 0x33, 0x00, 0xa2, 0xad, 0x55, 0x15, 0x63, + 0xd5, 0x2e, 0xfa, 0x2c, 0x68, 0xd3, 0x7e, 0xb7, 0x39, 0x27, 0x9f, 0x03, 0x51, 0xaf, 0xa1, 0x0b, + 0x3e, 0x1e, 0x39, 0x43, 0xdc, 0x67, 0x24, 0xba, 0x39, 0xd0, 0xd6, 0xab, 0x8a, 0xb1, 0x69, 0x6f, + 0xfa, 0x78, 0xf4, 0x62, 0x0e, 0xaa, 0x0e, 0xba, 0x04, 0xf3, 0xca, 0x9c, 0x10, 0x0b, 0xec, 0x83, + 0x96, 0xa9, 0x2a, 0x46, 0x7e, 0xe7, 0xa6, 0xb9, 0xe0, 0x25, 0xc4, 0xb5, 0x0f, 0xeb, 0xe6, 0x59, + 0xcf, 0xcf, 0x62, 0x4f, 0x63, 0xf5, 0x68, 0x5c, 0x49, 0xd9, 0x05, 0xf8, 0x0b, 0xbf, 0x5b, 0x38, + 0x38, 0x39, 0xdc, 0xce, 0x3f, 0x3e, 0xab, 0xb3, 0x76, 0x15, 0x55, 0x96, 0xde, 0x16, 0x84, 0x3c, + 0x00, 0xba, 0xf3, 0x4b, 0x41, 0xe9, 0x27, 0xe0, 0xa9, 0x3f, 0x14, 0x54, 0x5a, 0xa2, 0x55, 0x1f, + 0x98, 0xe7, 0x3c, 0x54, 0xf3, 0xdf, 0x6f, 0xa2, 0xfc, 0xf0, 0xff, 0x0f, 0x48, 0xc6, 0xac, 0xed, + 0x1f, 0x7c, 0xfd, 0xf9, 0x71, 0xe5, 0x5e, 0x6d, 0xd7, 0x3a, 0xff, 0x77, 0x59, 0x4b, 0x0e, 0x2b, + 0xaf, 0xbd, 0x3f, 0x39, 0xdc, 0x56, 0x1a, 0x2f, 0x8f, 0x26, 0xba, 0x72, 0x3c, 0xd1, 0x95, 0xef, + 0x13, 0x5d, 0xf9, 0x30, 0xd5, 0x53, 0xc7, 0x53, 0x3d, 0xf5, 0x6d, 0xaa, 0xa7, 0x5e, 0xdd, 0xf7, + 0x98, 0xec, 0x0d, 0x3a, 0x51, 0xf9, 0xd6, 0xa3, 0x24, 0xe7, 0x29, 0x95, 0x6f, 0xb9, 0x78, 0x3d, + 0x8f, 0x1d, 0x2d, 0x0e, 0x96, 0xef, 0x42, 0x0a, 0x9d, 0xf5, 0xf8, 0x97, 0xdc, 0xfe, 0x1d, 0x00, + 0x00, 0xff, 0xff, 0x7e, 0x3b, 0xf2, 0xe0, 0x03, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -53,6 +238,8 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { + // RegisterSubscriberChain registers a subscriber chain with the coordinator. By default, it is activated at the next epoch. + RegisterSubscriberChain(ctx context.Context, in *RegisterSubscriberChainRequest, opts ...grpc.CallOption) (*RegisterSubscriberChainResponse, error) } type msgClient struct { @@ -63,22 +250,601 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { return &msgClient{cc} } +func (c *msgClient) RegisterSubscriberChain(ctx context.Context, in *RegisterSubscriberChainRequest, opts ...grpc.CallOption) (*RegisterSubscriberChainResponse, error) { + out := new(RegisterSubscriberChainResponse) + err := c.cc.Invoke(ctx, "/exocore.appchain.coordinator.v1.Msg/RegisterSubscriberChain", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { + // RegisterSubscriberChain registers a subscriber chain with the coordinator. By default, it is activated at the next epoch. + RegisterSubscriberChain(context.Context, *RegisterSubscriberChainRequest) (*RegisterSubscriberChainResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. type UnimplementedMsgServer struct { } +func (*UnimplementedMsgServer) RegisterSubscriberChain(ctx context.Context, req *RegisterSubscriberChainRequest) (*RegisterSubscriberChainResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterSubscriberChain not implemented") +} + func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) } +func _Msg_RegisterSubscriberChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterSubscriberChainRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RegisterSubscriberChain(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/exocore.appchain.coordinator.v1.Msg/RegisterSubscriberChain", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RegisterSubscriberChain(ctx, req.(*RegisterSubscriberChainRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "exocore.appchain.coordinator.v1.Msg", HandlerType: (*MsgServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{}, - Metadata: "exocore/appchain/coordinator/v1/tx.proto", + Methods: []grpc.MethodDesc{ + { + MethodName: "RegisterSubscriberChain", + Handler: _Msg_RegisterSubscriberChain_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "exocore/appchain/coordinator/v1/tx.proto", +} + +func (m *RegisterSubscriberChainRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RegisterSubscriberChainRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisterSubscriberChainRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.SubscriberParams.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + if m.MaxValidators != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.MaxValidators)) + i-- + dAtA[i] = 0x30 + } + if m.MinSelfDelegationUsd != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.MinSelfDelegationUsd)) + i-- + dAtA[i] = 0x28 + } + if len(m.AssetIDs) > 0 { + for iNdEx := len(m.AssetIDs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AssetIDs[iNdEx]) + copy(dAtA[i:], m.AssetIDs[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.AssetIDs[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if len(m.EpochIdentifier) > 0 { + i -= len(m.EpochIdentifier) + copy(dAtA[i:], m.EpochIdentifier) + i = encodeVarintTx(dAtA, i, uint64(len(m.EpochIdentifier))) + i-- + dAtA[i] = 0x1a + } + if len(m.ChainID) > 0 { + i -= len(m.ChainID) + copy(dAtA[i:], m.ChainID) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainID))) + i-- + dAtA[i] = 0x12 + } + if len(m.FromAddress) > 0 { + i -= len(m.FromAddress) + copy(dAtA[i:], m.FromAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.FromAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RegisterSubscriberChainResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RegisterSubscriberChainResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } + +func (m *RegisterSubscriberChainResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *RegisterSubscriberChainRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FromAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChainID) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.EpochIdentifier) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.AssetIDs) > 0 { + for _, s := range m.AssetIDs { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + if m.MinSelfDelegationUsd != 0 { + n += 1 + sovTx(uint64(m.MinSelfDelegationUsd)) + } + if m.MaxValidators != 0 { + n += 1 + sovTx(uint64(m.MaxValidators)) + } + l = m.SubscriberParams.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *RegisterSubscriberChainResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *RegisterSubscriberChainRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RegisterSubscriberChainRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RegisterSubscriberChainRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FromAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FromAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochIdentifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EpochIdentifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssetIDs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetIDs = append(m.AssetIDs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinSelfDelegationUsd", wireType) + } + m.MinSelfDelegationUsd = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinSelfDelegationUsd |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxValidators", wireType) + } + m.MaxValidators = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxValidators |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubscriberParams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SubscriberParams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RegisterSubscriberChainResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RegisterSubscriberChainResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RegisterSubscriberChainResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/coordinator/types/tx.pb.gw.go b/x/appchain/coordinator/types/tx.pb.gw.go new file mode 100644 index 000000000..805e54434 --- /dev/null +++ b/x/appchain/coordinator/types/tx.pb.gw.go @@ -0,0 +1,171 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: exocore/appchain/coordinator/v1/tx.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +var ( + filter_Msg_RegisterSubscriberChain_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Msg_RegisterSubscriberChain_0(ctx context.Context, marshaler runtime.Marshaler, client MsgClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RegisterSubscriberChainRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_RegisterSubscriberChain_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.RegisterSubscriberChain(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Msg_RegisterSubscriberChain_0(ctx context.Context, marshaler runtime.Marshaler, server MsgServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RegisterSubscriberChainRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_RegisterSubscriberChain_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.RegisterSubscriberChain(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterMsgHandlerServer registers the http handlers for service Msg to "mux". +// UnaryRPC :call MsgServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMsgHandlerFromEndpoint instead. +func RegisterMsgHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MsgServer) error { + + mux.Handle("POST", pattern_Msg_RegisterSubscriberChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Msg_RegisterSubscriberChain_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Msg_RegisterSubscriberChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterMsgHandlerFromEndpoint is same as RegisterMsgHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterMsgHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterMsgHandler(ctx, mux, conn) +} + +// RegisterMsgHandler registers the http handlers for service Msg to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterMsgHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterMsgHandlerClient(ctx, mux, NewMsgClient(conn)) +} + +// RegisterMsgHandlerClient registers the http handlers for service Msg +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MsgClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MsgClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "MsgClient" to call the correct interceptors. +func RegisterMsgHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MsgClient) error { + + mux.Handle("POST", pattern_Msg_RegisterSubscriberChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Msg_RegisterSubscriberChain_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Msg_RegisterSubscriberChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Msg_RegisterSubscriberChain_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"exocore", "appchain", "coordinator", "v1", "tx", "RegisterSubscriberChain"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Msg_RegisterSubscriberChain_0 = runtime.ForwardResponseMessage +) diff --git a/x/appchain/subscriber/client/cli/query.go b/x/appchain/subscriber/client/cli/query.go index f30834c68..aeb7d4386 100644 --- a/x/appchain/subscriber/client/cli/query.go +++ b/x/appchain/subscriber/client/cli/query.go @@ -11,7 +11,7 @@ import ( ) // GetQueryCmd returns the cli query commands for this module -func GetQueryCmd(queryRoute string) *cobra.Command { +func GetQueryCmd(string) *cobra.Command { // Group dogfood queries under a subcommand cmd := &cobra.Command{ Use: types.ModuleName, diff --git a/x/appchain/subscriber/keeper/grpc_query.go b/x/appchain/subscriber/keeper/grpc_query.go index 6f523fe13..70954845d 100644 --- a/x/appchain/subscriber/keeper/grpc_query.go +++ b/x/appchain/subscriber/keeper/grpc_query.go @@ -12,7 +12,7 @@ import ( var _ types.QueryServer = Keeper{} -func (k Keeper) Params( +func (k Keeper) QueryParams( goCtx context.Context, req *types.QueryParamsRequest, ) (*types.QueryParamsResponse, error) { diff --git a/x/appchain/subscriber/keeper/params.go b/x/appchain/subscriber/keeper/params.go index a16ced7aa..a94cb6cc3 100644 --- a/x/appchain/subscriber/keeper/params.go +++ b/x/appchain/subscriber/keeper/params.go @@ -1,25 +1,22 @@ package keeper import ( + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" sdk "github.com/cosmos/cosmos-sdk/types" ) // SetParams sets the appchain coordinator parameters. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { +func (k Keeper) SetParams(ctx sdk.Context, params commontypes.SubscriberParams) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(¶ms) store.Set(types.ParamsKey(), bz) } // GetParams gets the appchain coordinator parameters. -func (k Keeper) GetParams(ctx sdk.Context) types.Params { +func (k Keeper) GetParams(ctx sdk.Context) (res commontypes.SubscriberParams) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ParamsKey()) - if bz == nil { - return types.DefaultParams() - } - var params types.Params - k.cdc.MustUnmarshal(bz, ¶ms) - return params + k.cdc.MustUnmarshal(bz, &res) + return res } diff --git a/x/appchain/subscriber/types/codec.go b/x/appchain/subscriber/types/codec.go index 8883bdf68..a98707ec8 100644 --- a/x/appchain/subscriber/types/codec.go +++ b/x/appchain/subscriber/types/codec.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/msgservice" ) -func RegisterCodec(cdc *codec.LegacyAmino) { +func RegisterCodec(*codec.LegacyAmino) { // this line is used by starport scaffolding # 2 } diff --git a/x/appchain/subscriber/types/genesis.go b/x/appchain/subscriber/types/genesis.go index 255e60642..7d5e514e6 100644 --- a/x/appchain/subscriber/types/genesis.go +++ b/x/appchain/subscriber/types/genesis.go @@ -1,13 +1,17 @@ package types +import ( + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" +) + // DefaultGenesis returns the default genesis state. func DefaultGenesis() *GenesisState { - return NewGenesis(DefaultParams()) + return NewGenesis(commontypes.DefaultSubscriberParams()) } // NewGenesis creates a new genesis state with the provided parameters and // data. -func NewGenesis(params Params) *GenesisState { +func NewGenesis(params commontypes.SubscriberParams) *GenesisState { return &GenesisState{Params: params} } diff --git a/x/appchain/subscriber/types/genesis.pb.go b/x/appchain/subscriber/types/genesis.pb.go index 3acb96aaf..4d3f210f0 100644 --- a/x/appchain/subscriber/types/genesis.pb.go +++ b/x/appchain/subscriber/types/genesis.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + types "github.com/ExocoreNetwork/exocore/x/appchain/common/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -26,7 +27,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState is the genesis state for the appchain subscriber module. type GenesisState struct { // Params is the parameters for the appchain subscriber module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + Params types.SubscriberParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -62,11 +63,11 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo -func (m *GenesisState) GetParams() Params { +func (m *GenesisState) GetParams() types.SubscriberParams { if m != nil { return m.Params } - return Params{} + return types.SubscriberParams{} } func init() { @@ -78,21 +79,22 @@ func init() { } var fileDescriptor_f608de439fd2c5db = []byte{ - // 217 bytes of a gzipped FileDescriptorProto + // 232 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x49, 0xad, 0xc8, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x2e, 0x4d, 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0xaa, 0xd6, 0x83, 0xa9, 0xd6, - 0x43, 0xa8, 0xd6, 0x2b, 0x33, 0x94, 0xd2, 0x26, 0x60, 0x5a, 0x41, 0x62, 0x51, 0x62, 0x2e, 0xd4, - 0x30, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0x30, 0x53, 0x1f, 0xc4, 0x82, 0x88, 0x2a, 0x85, 0x70, - 0xf1, 0xb8, 0x43, 0xec, 0x0c, 0x2e, 0x49, 0x2c, 0x49, 0x15, 0x72, 0xe1, 0x62, 0x83, 0xe8, 0x92, - 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, 0x52, 0xd3, 0xc3, 0xef, 0x06, 0xbd, 0x00, 0xb0, 0x6a, 0x27, - 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0x7a, 0x9d, 0xc2, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, + 0x43, 0xa8, 0xd6, 0x2b, 0x33, 0x94, 0x52, 0xc7, 0x30, 0x2d, 0x39, 0x3f, 0x37, 0x37, 0x3f, 0x0f, + 0x64, 0x12, 0x84, 0x05, 0x31, 0x48, 0x4a, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xcc, 0xd4, 0x07, 0xb1, + 0x20, 0xa2, 0x4a, 0x51, 0x5c, 0x3c, 0xee, 0x10, 0xfb, 0x82, 0x4b, 0x12, 0x4b, 0x52, 0x85, 0xbc, + 0xb8, 0xd8, 0x0a, 0x12, 0x8b, 0x12, 0x73, 0x8b, 0x25, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0x74, + 0xf4, 0x30, 0xec, 0x87, 0x9a, 0x5a, 0x66, 0xa8, 0x17, 0x0c, 0x77, 0x49, 0x00, 0x58, 0x8f, 0x13, + 0xcb, 0x89, 0x7b, 0xf2, 0x0c, 0x41, 0x50, 0x13, 0x9c, 0xc2, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, - 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x36, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, - 0xdf, 0x15, 0x62, 0xb2, 0x5f, 0x6a, 0x49, 0x79, 0x7e, 0x51, 0xb6, 0x3e, 0xcc, 0x33, 0x15, 0x58, - 0xbd, 0x53, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x76, 0xb5, 0x31, 0x20, 0x00, 0x00, 0xff, - 0xff, 0xa2, 0xcb, 0xbe, 0x33, 0x48, 0x01, 0x00, 0x00, + 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x36, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x09, 0x64, 0x94, 0xbe, 0x2b, + 0xc4, 0x7c, 0xbf, 0xd4, 0x92, 0xf2, 0xfc, 0xa2, 0x6c, 0x7d, 0x98, 0x77, 0x2a, 0xb0, 0x06, 0x4f, + 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0xed, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x3c, 0xba, 0x2f, 0x3b, 0x4a, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/appchain/subscriber/types/params.go b/x/appchain/subscriber/types/params.go deleted file mode 100644 index 21722dc9b..000000000 --- a/x/appchain/subscriber/types/params.go +++ /dev/null @@ -1,16 +0,0 @@ -package types - -// DefaultParams returns the default parameters for the module. -func DefaultParams() Params { - return Params{} -} - -// NewParams creates a new Params object -func NewParams() Params { - return Params{} -} - -// Validate checks that the parameters have valid values. -func (p Params) Validate() error { - return nil -} diff --git a/x/appchain/subscriber/types/params.pb.go b/x/appchain/subscriber/types/params.pb.go deleted file mode 100644 index c2a6b3d10..000000000 --- a/x/appchain/subscriber/types/params.pb.go +++ /dev/null @@ -1,266 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: exocore/appchain/subscriber/v1/params.proto - -package types - -import ( - fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// Params is the parameters for the appchain subscriber module. -type Params struct { -} - -func (m *Params) Reset() { *m = Params{} } -func (m *Params) String() string { return proto.CompactTextString(m) } -func (*Params) ProtoMessage() {} -func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_f35e5b6a0b1989b5, []int{0} -} -func (m *Params) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Params.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Params) XXX_Merge(src proto.Message) { - xxx_messageInfo_Params.Merge(m, src) -} -func (m *Params) XXX_Size() int { - return m.Size() -} -func (m *Params) XXX_DiscardUnknown() { - xxx_messageInfo_Params.DiscardUnknown(m) -} - -var xxx_messageInfo_Params proto.InternalMessageInfo - -func init() { - proto.RegisterType((*Params)(nil), "exocore.appchain.subscriber.v1.Params") -} - -func init() { - proto.RegisterFile("exocore/appchain/subscriber/v1/params.proto", fileDescriptor_f35e5b6a0b1989b5) -} - -var fileDescriptor_f35e5b6a0b1989b5 = []byte{ - // 157 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0xad, 0xc8, 0x4f, - 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x2e, 0x4d, - 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, - 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0x2a, 0xd6, 0x83, 0x29, 0xd6, 0x43, - 0x28, 0xd6, 0x2b, 0x33, 0x54, 0xe2, 0xe0, 0x62, 0x0b, 0x00, 0xab, 0x77, 0x0a, 0x3f, 0xf1, 0x48, - 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, - 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xdb, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, - 0xe4, 0xfc, 0x5c, 0x7d, 0x57, 0x88, 0x71, 0x7e, 0xa9, 0x25, 0xe5, 0xf9, 0x45, 0xd9, 0xfa, 0x30, - 0xa7, 0x54, 0x60, 0x75, 0x4c, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x25, 0xc6, 0x80, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0xcc, 0xe3, 0x34, 0xb8, 0x00, 0x00, 0x00, -} - -func (m *Params) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Params) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func encodeVarintParams(dAtA []byte, offset int, v uint64) int { - offset -= sovParams(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *Params) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func sovParams(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozParams(x uint64) (n int) { - return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *Params) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Params: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipParams(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthParams - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipParams(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowParams - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowParams - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowParams - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthParams - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupParams - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthParams - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/appchain/subscriber/types/query.pb.go b/x/appchain/subscriber/types/query.pb.go index 57f15a01f..62cb6806b 100644 --- a/x/appchain/subscriber/types/query.pb.go +++ b/x/appchain/subscriber/types/query.pb.go @@ -6,6 +6,7 @@ package types import ( context "context" fmt "fmt" + types "github.com/ExocoreNetwork/exocore/x/appchain/common/types" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" @@ -29,6 +30,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// QueryParamsRequest is the request type for the Query.QueryParams RPC method. type QueryParamsRequest struct { } @@ -65,8 +67,10 @@ func (m *QueryParamsRequest) XXX_DiscardUnknown() { var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo +// QueryParamsResponse is the response type for the Query.QueryParams RPC method. type QueryParamsResponse struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // params is the parameters for the appchain subscriber module. + Params types.SubscriberParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` } func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } @@ -102,11 +106,11 @@ func (m *QueryParamsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo -func (m *QueryParamsResponse) GetParams() Params { +func (m *QueryParamsResponse) GetParams() types.SubscriberParams { if m != nil { return m.Params } - return Params{} + return types.SubscriberParams{} } func init() { @@ -119,26 +123,27 @@ func init() { } var fileDescriptor_351939062175e6f7 = []byte{ - // 298 bytes of a gzipped FileDescriptorProto + // 315 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4a, 0xad, 0xc8, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x2e, 0x4d, 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0xaa, 0xd5, 0x83, 0xa9, 0xd5, 0x43, 0xa8, - 0xd5, 0x2b, 0x33, 0x94, 0xd2, 0x26, 0x60, 0x56, 0x41, 0x62, 0x51, 0x62, 0x6e, 0x31, 0xc4, 0x30, - 0x29, 0x99, 0xf4, 0xfc, 0xfc, 0xf4, 0x1c, 0x90, 0xda, 0x4c, 0xfd, 0xc4, 0xbc, 0xbc, 0xfc, 0x92, - 0xc4, 0x92, 0xcc, 0xfc, 0x3c, 0x98, 0xac, 0x48, 0x7a, 0x7e, 0x7a, 0x3e, 0x98, 0xa9, 0x0f, 0x62, - 0x41, 0x44, 0x95, 0x44, 0xb8, 0x84, 0x02, 0x41, 0xee, 0x09, 0x00, 0x1b, 0x14, 0x94, 0x5a, 0x58, - 0x9a, 0x5a, 0x5c, 0xa2, 0x14, 0xcd, 0x25, 0x8c, 0x22, 0x5a, 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x2a, - 0xe4, 0xc2, 0xc5, 0x06, 0xb1, 0x50, 0x82, 0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x4d, 0x0f, 0xbf, - 0xf3, 0xf5, 0x20, 0xfa, 0x9d, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x82, 0xea, 0x35, 0x5a, 0xc0, - 0xc8, 0xc5, 0x0a, 0x36, 0x5d, 0x68, 0x1a, 0x23, 0x17, 0x1b, 0x44, 0x89, 0x90, 0x11, 0x21, 0xa3, - 0x30, 0x5d, 0x29, 0x65, 0x4c, 0x92, 0x1e, 0x88, 0x1f, 0x94, 0x94, 0x9b, 0x2e, 0x3f, 0x99, 0xcc, - 0x24, 0x2b, 0x24, 0x8d, 0x35, 0x48, 0x21, 0x4e, 0x74, 0x0a, 0x3f, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, - 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, - 0xc6, 0x63, 0x39, 0x86, 0x28, 0xdb, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, - 0x7d, 0x57, 0x88, 0xed, 0x7e, 0xa9, 0x25, 0xe5, 0xf9, 0x45, 0xd9, 0xfa, 0xb0, 0xa8, 0xaa, 0xc0, - 0x6a, 0x72, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0xd4, 0x8d, 0x01, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x7a, 0x5f, 0x4e, 0xf2, 0x24, 0x02, 0x00, 0x00, + 0xd5, 0x2b, 0x33, 0x94, 0x52, 0xc7, 0x30, 0x2b, 0x39, 0x3f, 0x37, 0x37, 0x3f, 0x0f, 0x64, 0x0e, + 0x84, 0x05, 0x31, 0x48, 0x4a, 0x26, 0x3d, 0x3f, 0x3f, 0x3d, 0x07, 0xa4, 0x2e, 0x53, 0x3f, 0x31, + 0x2f, 0x2f, 0xbf, 0x24, 0xb1, 0x24, 0x33, 0x3f, 0xaf, 0x18, 0x2a, 0x2b, 0x92, 0x9e, 0x9f, 0x9e, + 0x0f, 0x66, 0xea, 0x83, 0x58, 0x10, 0x51, 0x25, 0x11, 0x2e, 0xa1, 0x40, 0x90, 0x5b, 0x02, 0x12, + 0x8b, 0x12, 0x73, 0x8b, 0x83, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x94, 0x12, 0xb9, 0x84, 0x51, + 0x44, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0xbc, 0xb8, 0xd8, 0x0a, 0xc0, 0x22, 0x12, 0x8c, + 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x3a, 0x7a, 0x18, 0x4e, 0x87, 0x3a, 0xa8, 0xcc, 0x50, 0x2f, 0x18, + 0xee, 0x09, 0x88, 0x29, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x41, 0x4d, 0x30, 0x5a, 0xca, + 0xc8, 0xc5, 0x0a, 0xb6, 0x43, 0x68, 0x36, 0x23, 0x17, 0x37, 0x92, 0x6d, 0x42, 0x46, 0x7a, 0xf8, + 0x03, 0x44, 0x0f, 0xd3, 0xc1, 0x52, 0xc6, 0x24, 0xe9, 0x81, 0x78, 0x47, 0x49, 0xb9, 0xe9, 0xf2, + 0x93, 0xc9, 0x4c, 0xb2, 0x42, 0xd2, 0x58, 0x63, 0x09, 0xe2, 0x4e, 0xa7, 0xf0, 0x13, 0x8f, 0xe4, + 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, + 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0x02, 0x79, + 0x59, 0xdf, 0x15, 0x62, 0xbb, 0x5f, 0x6a, 0x49, 0x79, 0x7e, 0x51, 0xb6, 0x3e, 0x2c, 0xc6, 0x2a, + 0xb0, 0x9a, 0x5c, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x8e, 0x00, 0x63, 0x40, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x5e, 0x6d, 0x1a, 0xab, 0x2b, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -153,7 +158,8 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { - Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // QueryParams returns the appchain subscriber module parameters. + QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) } type queryClient struct { @@ -164,9 +170,9 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } -func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { +func (c *queryClient) QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/exocore.appchain.subscriber.v1.Query/Params", in, out, opts...) + err := c.cc.Invoke(ctx, "/exocore.appchain.subscriber.v1.Query/QueryParams", in, out, opts...) if err != nil { return nil, err } @@ -175,35 +181,36 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . // QueryServer is the server API for Query service. type QueryServer interface { - Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // QueryParams returns the appchain subscriber module parameters. + QueryParams(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. type UnimplementedQueryServer struct { } -func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +func (*UnimplementedQueryServer) QueryParams(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryParams not implemented") } func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } -func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Query_QueryParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryParamsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).Params(ctx, in) + return srv.(QueryServer).QueryParams(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/exocore.appchain.subscriber.v1.Query/Params", + FullMethod: "/exocore.appchain.subscriber.v1.Query/QueryParams", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + return srv.(QueryServer).QueryParams(ctx, req.(*QueryParamsRequest)) } return interceptor(ctx, in, info, handler) } @@ -213,8 +220,8 @@ var _Query_serviceDesc = grpc.ServiceDesc{ HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "Params", - Handler: _Query_Params_Handler, + MethodName: "QueryParams", + Handler: _Query_QueryParams_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/x/appchain/subscriber/types/query.pb.gw.go b/x/appchain/subscriber/types/query.pb.gw.go index 98be0e96a..d5dfc6f3b 100644 --- a/x/appchain/subscriber/types/query.pb.gw.go +++ b/x/appchain/subscriber/types/query.pb.gw.go @@ -33,20 +33,20 @@ var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage var _ = metadata.Join -func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { +func request_Query_QueryParams_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryParamsRequest var metadata runtime.ServerMetadata - msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.QueryParams(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { +func local_request_Query_QueryParams_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryParamsRequest var metadata runtime.ServerMetadata - msg, err := server.Params(ctx, &protoReq) + msg, err := server.QueryParams(ctx, &protoReq) return msg, metadata, err } @@ -57,7 +57,7 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_QueryParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -68,7 +68,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_QueryParams_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -76,7 +76,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_QueryParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -121,7 +121,7 @@ func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // "QueryClient" to call the correct interceptors. func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { - mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_QueryParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -130,14 +130,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_QueryParams_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_QueryParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -145,9 +145,9 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"appchain", "subscriber", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_QueryParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"appchain", "subscriber", "params"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( - forward_Query_Params_0 = runtime.ForwardResponseMessage + forward_Query_QueryParams_0 = runtime.ForwardResponseMessage ) From 4bd8948b21161257db2d00447d584f3ce302dcc8 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 15:39:54 +0000 Subject: [PATCH 12/52] chore(lint) --- x/appchain/common/types/events.go | 13 +----------- x/appchain/coordinator/keeper/identifiers.go | 12 +++++------ .../coordinator/keeper/impl_epochs_hooks.go | 13 ++++++++++-- x/appchain/coordinator/keeper/slash.go | 2 +- x/appchain/coordinator/types/keys.go | 20 +++++++++---------- 5 files changed, 29 insertions(+), 31 deletions(-) diff --git a/x/appchain/common/types/events.go b/x/appchain/common/types/events.go index cd5ceced1..5d8899972 100644 --- a/x/appchain/common/types/events.go +++ b/x/appchain/common/types/events.go @@ -1,16 +1,5 @@ package types const ( - // EventTypeTimeout = "timeout" - AttributeKeyAckSuccess = "success" - AttributeKeyAck = "acknowledgement" - AttributeKeyAckError = "error" - AttributeChainID = "chain_id" - AttributeValidatorAddress = "validator_address" - AttributeValSetUpdateId = "valset_update_id" - AttributeInfractionType = "infraction_type" - - EventTypeChannelEstablished = "channel_established" - EventTypePacket = "common_packet" - EventTypeTimeout = "common_timeout" + AttributeChainID = "chain_id" ) diff --git a/x/appchain/coordinator/keeper/identifiers.go b/x/appchain/coordinator/keeper/identifiers.go index daea84510..63b8b3353 100644 --- a/x/appchain/coordinator/keeper/identifiers.go +++ b/x/appchain/coordinator/keeper/identifiers.go @@ -7,18 +7,18 @@ import ( // SetClientForChain sets the ibc client id for a given chain id. func (k Keeper) SetClientForChain( - ctx sdk.Context, chainId string, clientId string, + ctx sdk.Context, chainID string, clientID string, ) { store := ctx.KVStore(k.storeKey) - store.Set(types.ClientForChainKey(chainId), []byte(clientId)) + store.Set(types.ClientForChainKey(chainID), []byte(clientID)) } // GetClientForChain gets the ibc client id for a given chain id. func (k Keeper) GetClientForChain( - ctx sdk.Context, chainId string, + ctx sdk.Context, chainID string, ) (string, bool) { store := ctx.KVStore(k.storeKey) - bytes := store.Get(types.ClientForChainKey(chainId)) + bytes := store.Get(types.ClientForChainKey(chainID)) if bytes == nil { return "", false } @@ -26,7 +26,7 @@ func (k Keeper) GetClientForChain( } // DeleteClientForChain deletes the ibc client id for a given chain id. -func (k Keeper) DeleteClientForChain(ctx sdk.Context, chainId string) { +func (k Keeper) DeleteClientForChain(ctx sdk.Context, chainID string) { store := ctx.KVStore(k.storeKey) - store.Delete(types.ClientForChainKey(chainId)) + store.Delete(types.ClientForChainKey(chainID)) } diff --git a/x/appchain/coordinator/keeper/impl_epochs_hooks.go b/x/appchain/coordinator/keeper/impl_epochs_hooks.go index 489a68a2d..bd313cc80 100644 --- a/x/appchain/coordinator/keeper/impl_epochs_hooks.go +++ b/x/appchain/coordinator/keeper/impl_epochs_hooks.go @@ -40,10 +40,19 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( "chainID", subscriber, "error", err, ) - // clear the registered AVS + // clear the registered AVS. remember that this module stores + // the chainID with the revision but the AVS module stores it without. chainID := avstypes.ChainIDWithoutRevision(subscriber.ChainID) + // always guaranteed to exist _, addr := wrapper.keeper.avsKeeper.IsAVSByChainID(ctx, chainID) - wrapper.keeper.avsKeeper.DeleteAVSInfo(ctx, addr) + if err := wrapper.keeper.avsKeeper.DeleteAVSInfo(ctx, addr); err != nil { + // should never happen + ctx.Logger().Error( + "subscriber AVS not deleted", + "chainID", subscriber, + "error", err, + ) + } continue } // copy over the events from the cached ctx diff --git a/x/appchain/coordinator/keeper/slash.go b/x/appchain/coordinator/keeper/slash.go index 7c7046e3a..5f4f6cb61 100644 --- a/x/appchain/coordinator/keeper/slash.go +++ b/x/appchain/coordinator/keeper/slash.go @@ -12,7 +12,7 @@ import ( // SetSubSlashFractionDowntime sets the sub slash fraction downtime for a chain func (k Keeper) SetSubSlashFractionDowntime(ctx sdk.Context, chainID string, fraction string) { store := ctx.KVStore(k.storeKey) - store.Set([]byte(types.SubSlashFractionDowntimeKey(chainID)), []byte(fraction)) + store.Set(types.SubSlashFractionDowntimeKey(chainID), []byte(fraction)) } // GetSubSlashFractionDowntime gets the sub slash fraction downtime for a chain diff --git a/x/appchain/coordinator/types/keys.go b/x/appchain/coordinator/types/keys.go index 907000965..16565e190 100644 --- a/x/appchain/coordinator/types/keys.go +++ b/x/appchain/coordinator/types/keys.go @@ -73,31 +73,31 @@ func PendingSubscriberChainKey(epochIdentifier string, epochNumber uint64) []byt } // ClientForChainKey returns the key under which the clientId for the given chainId is stored. -func ClientForChainKey(chainId string) []byte { - return append([]byte{ClientForChainBytePrefix}, []byte(chainId)...) +func ClientForChainKey(chainID string) []byte { + return append([]byte{ClientForChainBytePrefix}, []byte(chainID)...) } // SubSlashFractionDowntimeKey returns the key under which the slashing fraction for downtime // against a particular chain is stored. -func SubSlashFractionDowntimeKey(chainId string) []byte { - return append([]byte{SubSlashFractionDowntimeBytePrefix}, []byte(chainId)...) +func SubSlashFractionDowntimeKey(chainID string) []byte { + return append([]byte{SubSlashFractionDowntimeBytePrefix}, []byte(chainID)...) } // SubSlashFractionDoubleSignKey returns the key under which the slashing fraction for double sign // against a particular chain is stored. -func SubSlashFractionDoubleSignKey(chainId string) []byte { - return append([]byte{SubSlashFractionDoubleSignBytePrefix}, []byte(chainId)...) +func SubSlashFractionDoubleSignKey(chainID string) []byte { + return append([]byte{SubSlashFractionDoubleSignBytePrefix}, []byte(chainID)...) } // SubDowntimeJailDurationKey returns the key under which the downtime jail duration for a chain // is stored. -func SubDowntimeJailDurationKey(chainId string) []byte { - return append([]byte{SubDowntimeJailDurationBytePrefix}, []byte(chainId)...) +func SubDowntimeJailDurationKey(chainID string) []byte { + return append([]byte{SubDowntimeJailDurationBytePrefix}, []byte(chainID)...) } // SubscriberGenesisKey returns the key under which the genesis state for a subscriber chain is stored. -func SubscriberGenesisKey(chainId string) []byte { - return append([]byte{SubscriberGenesisBytePrefix}, []byte(chainId)...) +func SubscriberGenesisKey(chainID string) []byte { + return append([]byte{SubscriberGenesisBytePrefix}, []byte(chainID)...) } // InitTimeoutEpochKey returns the key under which the list of chains which will timeout (if not From 571c65e7e12c68bef43771d46dc3973e9967d77c Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:03:58 +0000 Subject: [PATCH 13/52] fix(test): make avs test pass The AVS module now validates the assetIDs passed to it --- precompiles/avs/avs_test.go | 6 +++--- testutil/utils.go | 2 ++ x/avs/keeper/avs_test.go | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/precompiles/avs/avs_test.go b/precompiles/avs/avs_test.go index 1171d328e..639af4818 100644 --- a/precompiles/avs/avs_test.go +++ b/precompiles/avs/avs_test.go @@ -80,7 +80,7 @@ func (suite *AVSManagerPrecompileSuite) TestRegisterAVS() { sdk.AccAddress(utiltx.GenerateAddress().Bytes()).String(), sdk.AccAddress(utiltx.GenerateAddress().Bytes()).String(), } - assetID := []string{"11", "22", "33"} + assetID := suite.AssetIDs minStakeAmount, taskAddr := uint64(3), "0xDF907c29719154eb9872f021d21CAE6E5025d7aB" avsUnbondingPeriod, minSelfDelegation := uint64(3), uint64(3) epochIdentifier := epochstypes.DayEpochID @@ -312,7 +312,7 @@ func (suite *AVSManagerPrecompileSuite) TestUpdateAVS() { sdk.AccAddress(utiltx.GenerateAddress().Bytes()).String(), sdk.AccAddress(utiltx.GenerateAddress().Bytes()).String(), } - assetID := []string{"11", "22", "33"} + assetID := suite.AssetIDs minStakeAmount, taskAddr := uint64(3), "0xDF907c29719154eb9872f021d21CAE6E5025d7aB" avsUnbondingPeriod, minSelfDelegation := uint64(3), uint64(3) epochIdentifier := epochstypes.DayEpochID @@ -657,7 +657,7 @@ func (suite *AVSManagerPrecompileSuite) TestRunRegTaskInfo() { "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkjr", "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkj2", } - assetID := []string{"11", "22", "33"} + assetID := suite.AssetIDs avsInfo := &types.AVSInfo{ Name: avsName, AvsAddress: utiltx.GenerateAddress().String(), diff --git a/testutil/utils.go b/testutil/utils.go index eb44fe1cf..0d99b2edb 100644 --- a/testutil/utils.go +++ b/testutil/utils.go @@ -55,6 +55,7 @@ type BaseTestSuite struct { // x/assets ClientChains []assetstypes.ClientChainInfo Assets []assetstypes.AssetInfo + AssetIDs []string // for tracking validator across blocks ValSet *tmtypes.ValidatorSet Operators []sdk.AccAddress @@ -99,6 +100,7 @@ func (suite *BaseTestSuite) SetupWithGenesisValSet(genAccs []authtypes.GenesisAc suite.ClientChains[0].LayerZeroChainID, "", suite.Assets[0].Address, ) + suite.AssetIDs = append(suite.AssetIDs, assetID) // x/assets initialization - deposits (client chains and tokens are from caller) power := int64(101) power2 := int64(100) diff --git a/x/avs/keeper/avs_test.go b/x/avs/keeper/avs_test.go index 857313152..4c52ea2a3 100644 --- a/x/avs/keeper/avs_test.go +++ b/x/avs/keeper/avs_test.go @@ -16,7 +16,7 @@ func (suite *AVSTestSuite) TestAVS() { avsName := "avsTest" avsAddress := suite.avsAddress avsOwnerAddress := []string{"exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkjr", "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkj1", "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkj2"} - assetID := []string{"0xdac17f958d2ee523a2206206994597c13d831ec7_0x65"} + assetID := suite.AssetIDs avs := &types.AVSInfo{ Name: avsName, AvsAddress: avsAddress.String(), @@ -62,7 +62,7 @@ func (suite *AVSTestSuite) TestAVS() { func (suite *AVSTestSuite) TestAVSInfoUpdate_Register() { avsName, avsAddres, slashAddress, rewardAddress := "avsTest", "exo18cggcpvwspnd5c6ny8wrqxpffj5zmhklprtnph", "0xDF907c29719154eb9872f021d21CAE6E5025d7aB", "0xDF907c29719154eb9872f021d21CAE6E5025d7aB" avsOwnerAddress := []string{"exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkjr", "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkj1", "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkj2"} - assetID := []string{"11", "22", "33"} + assetID := suite.AssetIDs avsParams := &types.AVSRegisterOrDeregisterParams{ AvsName: avsName, @@ -94,7 +94,7 @@ func (suite *AVSTestSuite) TestAVSInfoUpdate_DeRegister() { // Test case setup avsName, avsAddres, slashAddress := "avsTest", suite.avsAddress.String(), "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutash" avsOwnerAddress := []string{"exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkjr", "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkj1", "exo13h6xg79g82e2g2vhjwg7j4r2z2hlncelwutkj2"} - assetID := []string{"11", "22", "33", "44", "55"} // Multiple assets + assetID := suite.AssetIDs avsParams := &types.AVSRegisterOrDeregisterParams{ AvsName: avsName, From 6f4cfa041624d9622792dbd6fd577e16ee69d56b Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:04:19 +0000 Subject: [PATCH 14/52] fix(appchain): remove superfluous test --- x/appchain/coordinator/types/params_test.go | 33 --------------------- 1 file changed, 33 deletions(-) diff --git a/x/appchain/coordinator/types/params_test.go b/x/appchain/coordinator/types/params_test.go index 526600d05..ad44610ee 100644 --- a/x/appchain/coordinator/types/params_test.go +++ b/x/appchain/coordinator/types/params_test.go @@ -7,7 +7,6 @@ import ( "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" - "github.com/stretchr/testify/require" ) func TestValidate(t *testing.T) { @@ -108,35 +107,3 @@ func TestValidate(t *testing.T) { }) } } - -func TestInvalidParams(t *testing.T) { - // Example of an invalid Init Timeout Period (0 epochs) - params := types.Params{ - InitTimeoutPeriod: epochstypes.NewEpoch(0, "week"), - } - err := params.Validate() - require.Error(t, err, "Params with 0 epoch InitTimeoutPeriod should return an error") - - // Invalid Trusting Period Fraction (>1) - params = types.Params{ - TrustingPeriodFraction: "1.5", - } - err = params.Validate() - require.Error(t, err, "Params with TrustingPeriodFraction > 1 should return an error") -} - -func TestEdgeCaseParams(t *testing.T) { - // Edge case with a very large number of epochs - params := types.Params{ - InitTimeoutPeriod: epochstypes.NewEpoch(1<<62, "week"), - } - err := params.Validate() - require.NoError(t, err, "Params with a very large number of epochs should still be valid") - - // Trusting Period Fraction equal to 1 - params = types.Params{ - TrustingPeriodFraction: "1.0", - } - err = params.Validate() - require.NoError(t, err, "Params with TrustingPeriodFraction equal to 1 should be valid") -} From 19ce74a1da2c6286c1787bd6c41129c76907dfb4 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:04:34 +0000 Subject: [PATCH 15/52] fix(epochs): update expected test message negative duration is also not supported --- x/epochs/types/genesis_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/epochs/types/genesis_test.go b/x/epochs/types/genesis_test.go index 563e56608..12398108f 100644 --- a/x/epochs/types/genesis_test.go +++ b/x/epochs/types/genesis_test.go @@ -73,7 +73,7 @@ func (suite *GenesisTestSuite) TestValidateGenesis() { }, ), expPass: false, - expError: "epoch duration should NOT be 0", + expError: "epoch duration should NOT be non-positive", }, { name: "negative current epoch number", From 0a0688c0b4d72e172f75aba5fce0557b97abaea7 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:10:20 +0000 Subject: [PATCH 16/52] chore(lint) --- precompiles/testutil/logs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/precompiles/testutil/logs.go b/precompiles/testutil/logs.go index 1f587f80a..4be7a0031 100644 --- a/precompiles/testutil/logs.go +++ b/precompiles/testutil/logs.go @@ -37,7 +37,7 @@ func CheckLogs(logArgs LogCheckArgs) error { int64(float64(logArgs.Res.GasUsed)/float64(logArgs.Res.GasWanted)*100), ) } - // nolint + if err := CheckVMError(logArgs.Res, logArgs.ErrContains); err != nil { return err } From 6cb92fc16b889a0cb87a2be10ffa90381d0caa35 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:18:38 +0000 Subject: [PATCH 17/52] chore(lint): proto lint --- proto/exocore/appchain/common/v1/common.proto | 121 +++++++++--------- .../appchain/coordinator/v1/coordinator.proto | 10 +- .../appchain/coordinator/v1/genesis.proto | 4 +- .../appchain/coordinator/v1/params.proto | 37 +++--- .../appchain/coordinator/v1/query.proto | 39 +++--- .../exocore/appchain/coordinator/v1/tx.proto | 65 +++++----- .../appchain/subscriber/v1/genesis.proto | 4 +- .../appchain/subscriber/v1/query.proto | 18 +-- proto/exocore/epochs/v1/epochs.proto | 8 +- 9 files changed, 164 insertions(+), 142 deletions(-) diff --git a/proto/exocore/appchain/common/v1/common.proto b/proto/exocore/appchain/common/v1/common.proto index 2ac4270f8..1285640e8 100644 --- a/proto/exocore/appchain/common/v1/common.proto +++ b/proto/exocore/appchain/common/v1/common.proto @@ -2,12 +2,12 @@ syntax = "proto3"; package exocore.appchain.common.v1; +import "amino/amino.proto"; import "gogoproto/gogo.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; import "tendermint/abci/types.proto"; -import "amino/amino.proto"; option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/common/types"; @@ -19,68 +19,70 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/common/types"; // for edits via governance on the subscriber chain to prevent the subcriber participants // from unilaterally alterting parameters (like reward %) for their own benefit. message SubscriberParams { - // Reward related params + // Reward related params - // coordinator_fee_pool_addr_str is the address of the fee pool on the coordinator. - string coordinator_fee_pool_addr_str = 1; - // distribution_transmission_channel is the channel name used to transmit - // the rewards from the subscriber to the coordinator. It is used in the event - // that a channel between coordinator and subscriber exists prior to the - // provision of security from Exocore to the appchain. Until a changeover - // process is implemented, it is currently unused. (TODO) - string distribution_transmission_channel = 2; - // blocks_per_distribution_transmission is the number of blocks after which the minted - // reward is sent to the coordinator. - int64 blocks_per_distribution_transmission = 3; - // subscriber_redistribution_fraction is the %age of the rewards that the subscriber - // should send out. For example, "0.75" means 75% of the rewards are sent out. - string subscriber_redistribution_fraction = 4; - // reward_denom is the denomination of the reward. For now, this is not - // distributed but rather simply tracked. - string reward_denom = 5; + // coordinator_fee_pool_addr_str is the address of the fee pool on the coordinator. + string coordinator_fee_pool_addr_str = 1; + // distribution_transmission_channel is the channel name used to transmit + // the rewards from the subscriber to the coordinator. It is used in the event + // that a channel between coordinator and subscriber exists prior to the + // provision of security from Exocore to the appchain. Until a changeover + // process is implemented, it is currently unused. (TODO) + string distribution_transmission_channel = 2; + // blocks_per_distribution_transmission is the number of blocks after which the minted + // reward is sent to the coordinator. + int64 blocks_per_distribution_transmission = 3; + // subscriber_redistribution_fraction is the %age of the rewards that the subscriber + // should send out. For example, "0.75" means 75% of the rewards are sent out. + string subscriber_redistribution_fraction = 4; + // reward_denom is the denomination of the reward. For now, this is not + // distributed but rather simply tracked. + string reward_denom = 5; - // IBC related params + // IBC related params - // ibc_timeout_period is the timeout period used for IBC packets (excluding transfers) - // Such a timeout is enforced by IBC itself and not by either of the chains. - google.protobuf.Duration ibc_timeout_period = 6 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, - (gogoproto.customname) = "IBCTimeoutPeriod" ]; - // transfer_timeout_period is the timeout period used for IBC transfers. - google.protobuf.Duration transfer_timeout_period = 7 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // ibc_timeout_period is the timeout period used for IBC packets (excluding transfers) + // Such a timeout is enforced by IBC itself and not by either of the chains. + google.protobuf.Duration ibc_timeout_period = 6 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, + (gogoproto.customname) = "IBCTimeoutPeriod" ]; + // transfer_timeout_period is the timeout period used for IBC transfers. + google.protobuf.Duration transfer_timeout_period = 7 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - // Params relevant to chain operation - // unbonding_duration is the subscriber chain's unbonding duration. it should be less - // than the coordinator chain's unbonding duration. - // for now, we don't support the subscriber chain using x/epochs as a unit of time; however, - // when we do, this duration should be the best approximation of that mechanism, with - // 1 epoch added to account for the current epoch. (TODO) - google.protobuf.Duration unbonding_period = 8 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - // HistoricalEntries is the number of historical entries to persist in the - // historical stats module. It is the same as that defined in the staking module, - // however, we use the signed version so that negative values can be caught. - int64 historical_entries = 9; + // Params relevant to chain operation + // unbonding_duration is the subscriber chain's unbonding duration. it should be less + // than the coordinator chain's unbonding duration. + // for now, we don't support the subscriber chain using x/epochs as a unit of time; however, + // when we do, this duration should be the best approximation of that mechanism, with + // 1 epoch added to account for the current epoch. (TODO) + google.protobuf.Duration unbonding_period = 8 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // HistoricalEntries is the number of historical entries to persist in the + // historical stats module. It is the same as that defined in the staking module, + // however, we use the signed version so that negative values can be caught. + int64 historical_entries = 9; - // These are params related to the slashing module. Requests are received - // from the subscriber and slashed according to these params. Since signing - // can only be tracked by the subscriber chain, we do not have any parameters - // here that can be used to configure the signing window and the number of - // blocks that should be signed in it. Conversely, the subscriber chain - // does not do anything with these parameters (even though they are shared) - // since slashing is done by the coordinator chain. - // Operators should refer to the genesis file of the subscriber chain to - // check their comfort with these values before onboarding the chain. + // These are params related to the slashing module. Requests are received + // from the subscriber and slashed according to these params. Since signing + // can only be tracked by the subscriber chain, we do not have any parameters + // here that can be used to configure the signing window and the number of + // blocks that should be signed in it. Conversely, the subscriber chain + // does not do anything with these parameters (even though they are shared) + // since slashing is done by the coordinator chain. + // Operators should refer to the genesis file of the subscriber chain to + // check their comfort with these values before onboarding the chain. - // slash_fraction_downtime is the fraction of the stake that is slashed when a validator is found to be offline. - string slash_fraction_downtime = 15; - // downtime_jail_duration is the duration of the jail period for a validator - // after they have been found to be offline for too long. - google.protobuf.Duration downtime_jail_duration = 16 - [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdduration) = true]; - // slash_fraction_double_sign is the fraction of the stake that is slashed when a validator is found to have double signed. - string slash_fraction_double_sign = 17; + // slash_fraction_downtime is the fraction of the stake that is slashed when a + // validator is found to be offline. + string slash_fraction_downtime = 15; + // downtime_jail_duration is the duration of the jail period for a validator + // after they have been found to be offline for too long. + google.protobuf.Duration downtime_jail_duration = 16 + [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdduration) = true]; + // slash_fraction_double_sign is the fraction of the stake that is slashed + // when a validator is found to have double signed. + string slash_fraction_double_sign = 17; } // SubscriberGenesisState is the genesis state of a subscriber at the time of @@ -92,7 +94,8 @@ message SubscriberGenesisState { CoordinatorInfo coordinator = 2 [ (gogoproto.nullable) = false ]; } -// CoordinatorInfo is the information about the coordinator chain that is stored within the subscriber chain's subscriber module. +// CoordinatorInfo is the information about the coordinator chain that is +// stored within the subscriber chain's subscriber module. message CoordinatorInfo { // client_state is the client state of the coordinator chain. ibc.lightclients.tendermint.v1.ClientState client_state = 1; @@ -100,5 +103,5 @@ message CoordinatorInfo { ibc.lightclients.tendermint.v1.ConsensusState consensus_state = 2; // initial_val_set is the initial validator set of the coordinator chain. repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; } \ No newline at end of file diff --git a/proto/exocore/appchain/coordinator/v1/coordinator.proto b/proto/exocore/appchain/coordinator/v1/coordinator.proto index e948adbd9..feff10b5f 100644 --- a/proto/exocore/appchain/coordinator/v1/coordinator.proto +++ b/proto/exocore/appchain/coordinator/v1/coordinator.proto @@ -10,14 +10,14 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/ty // PendingSubscriberChainRequests is a helper structure to store a list of // subscriber chain requests that are pending activation. message PendingSubscriberChainRequests { - // list is the list of subscriber chain requests that are pending activation. - repeated .exocore.appchain.coordinator.v1.RegisterSubscriberChainRequest list = 1 - [(gogoproto.nullable) = false]; + // list is the list of subscriber chain requests that are pending activation. + repeated .exocore.appchain.coordinator.v1.RegisterSubscriberChainRequest list = 1 + [(gogoproto.nullable) = false]; } // ChainIDs is a helper structure to store a list of chain IDs. message ChainIDs { - // list is the list of chain IDs. - repeated string list = 1; + // list is the list of chain IDs. + repeated string list = 1; } diff --git a/proto/exocore/appchain/coordinator/v1/genesis.proto b/proto/exocore/appchain/coordinator/v1/genesis.proto index 15f5743be..f183568bd 100644 --- a/proto/exocore/appchain/coordinator/v1/genesis.proto +++ b/proto/exocore/appchain/coordinator/v1/genesis.proto @@ -9,6 +9,6 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/ty // GenesisState is the genesis state for the appchain coordinator module. message GenesisState { - // Params is the parameters for the appchain coordinator module. - Params params = 1 [(gogoproto.nullable) = false]; + // Params is the parameters for the appchain coordinator module. + Params params = 1 [(gogoproto.nullable) = false]; } diff --git a/proto/exocore/appchain/coordinator/v1/params.proto b/proto/exocore/appchain/coordinator/v1/params.proto index ba68f5373..cd6773ab8 100644 --- a/proto/exocore/appchain/coordinator/v1/params.proto +++ b/proto/exocore/appchain/coordinator/v1/params.proto @@ -2,27 +2,34 @@ syntax = "proto3"; package exocore.appchain.coordinator.v1; +import "exocore/epochs/v1/epochs.proto"; import "gogoproto/gogo.proto"; import "google/protobuf/duration.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; -import "exocore/epochs/v1/epochs.proto"; option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; // Params is the parameters for the appchain coordinator module. message Params { - // template_client is the IBC template client. - ibc.lightclients.tendermint.v1.ClientState template_client = 1; - // trusting_period_fraction is the multiplier applied on the subscriber's unbonding duration to determine the IBC trusting period. - string trusting_period_fraction = 2; - // ibc_timeout_period is the timeout period for IBC packets. While our system is largely created with epochs as a unit of time (and not standard durations), this is an exception since it is used directly by the IBC codebase. - google.protobuf.Duration ibc_timeout_period = 3 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.customname) = "IBCTimeoutPeriod" ]; - // init_timeout_period is the period within which the subscriber chain must make a connection with the coordinator, after being spawned. - exocore.epochs.v1.Epoch init_timeout_period = 4 - [ (gogoproto.nullable) = false ]; - // vsc_timeout_period is the period within which the subscriber chain must respond to a VSC request, after it is sent. - exocore.epochs.v1.Epoch vsc_timeout_period = 5 - [ (gogoproto.nullable) = false, (gogoproto.customname) = "VSCTimeoutPeriod" ]; - // TODO: slashing and reward related parameters + // template_client is the IBC template client. + ibc.lightclients.tendermint.v1.ClientState template_client = 1; + // trusting_period_fraction is the multiplier applied on the subscriber's + // unbonding duration to determine the IBC trusting period. + string trusting_period_fraction = 2; + // ibc_timeout_period is the timeout period for IBC packets. While our + // system is largely created with epochs as a unit of time (and not + // standard durations), this is an exception since it is used directly + // by the IBC codebase. + google.protobuf.Duration ibc_timeout_period = 3 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, + (gogoproto.customname) = "IBCTimeoutPeriod" ]; + // init_timeout_period is the period within which the subscriber chain + // must make a connection with the coordinator, after being spawned. + exocore.epochs.v1.Epoch init_timeout_period = 4 + [ (gogoproto.nullable) = false ]; + // vsc_timeout_period is the period within which the subscriber chain + // must respond to a VSC request, after it is sent. + exocore.epochs.v1.Epoch vsc_timeout_period = 5 + [ (gogoproto.nullable) = false, (gogoproto.customname) = "VSCTimeoutPeriod" ]; + // TODO: slashing and reward related parameters } diff --git a/proto/exocore/appchain/coordinator/v1/query.proto b/proto/exocore/appchain/coordinator/v1/query.proto index 06e565719..c4e29cf8d 100644 --- a/proto/exocore/appchain/coordinator/v1/query.proto +++ b/proto/exocore/appchain/coordinator/v1/query.proto @@ -4,25 +4,25 @@ package exocore.appchain.coordinator.v1; import "exocore/appchain/common/v1/common.proto"; import "exocore/appchain/coordinator/v1/params.proto"; -import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; // Query defines the gRPC querier service. service Query { - // QueryParams returns the appchain coordinator module parameters. - rpc QueryParams(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http) = { - get: "/appchain/coordinator/params" - }; - } - // QuerySubscriberGenesis returns the genesis state for a subscriber chain. - rpc QuerySubscriberGenesis(QuerySubscriberGenesisRequest) returns (QuerySubscriberGenesisResponse) { - option (google.api.http) = { - get: "/exocore/appchain/coordinator/v1/subscriber_genesis/{chain}" - }; - } + // QueryParams returns the appchain coordinator module parameters. + rpc QueryParams(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http) = { + get: "/appchain/coordinator/params" + }; + } + // QuerySubscriberGenesis returns the genesis state for a subscriber chain. + rpc QuerySubscriberGenesis(QuerySubscriberGenesisRequest) returns (QuerySubscriberGenesisResponse) { + option (google.api.http) = { + get: "/exocore/appchain/coordinator/v1/subscriber_genesis/{chain}" + }; + } } // QueryParamsRequest is the request type for the Query.QueryParams RPC method. @@ -30,19 +30,20 @@ message QueryParamsRequest {} // QueryParamsResponse is the response type for the Query.QueryParams RPC method. message QueryParamsResponse { - // params is the parameters for the appchain coordinator module. - Params params = 1 [(gogoproto.nullable) = false]; + // params is the parameters for the appchain coordinator module. + Params params = 1 [(gogoproto.nullable) = false]; } // QuerySubscriberGenesisRequest is the request type for the Query.QuerySubscriberGenesis RPC method. message QuerySubscriberGenesisRequest { - // chain is the chain ID of the subscriber chain. we intentionally don't use ChainID so that - // the query can work (it does not support custom names). - string chain = 1; + // chain is the chain ID of the subscriber chain. we intentionally don't use ChainID so that + // the query can work (it does not support custom names). + string chain = 1; } // QuerySubscriberGenesisResponse is the response type for the Query.QuerySubscriberGenesis RPC method. message QuerySubscriberGenesisResponse { + // subscriber_genesis is the genesis state for the subscriber chain. exocore.appchain.common.v1.SubscriberGenesisState subscriber_genesis = 1 - [ (gogoproto.nullable) = false ]; + [ (gogoproto.nullable) = false ]; } \ No newline at end of file diff --git a/proto/exocore/appchain/coordinator/v1/tx.proto b/proto/exocore/appchain/coordinator/v1/tx.proto index b36e0851c..b051758e2 100644 --- a/proto/exocore/appchain/coordinator/v1/tx.proto +++ b/proto/exocore/appchain/coordinator/v1/tx.proto @@ -4,45 +4,52 @@ package exocore.appchain.coordinator.v1; import "cosmos/msg/v1/msg.proto"; import "cosmos_proto/cosmos.proto"; +import "exocore/appchain/common/v1/common.proto"; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; -import "exocore/appchain/common/v1/common.proto"; option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; // Msg defines the Msg service. service Msg { - option (cosmos.msg.v1.service) = true; - // RegisterSubscriberChain registers a subscriber chain with the coordinator. By default, it is activated at the next epoch. - rpc RegisterSubscriberChain(RegisterSubscriberChainRequest) returns (RegisterSubscriberChainResponse) { - option (google.api.http).post = "/exocore/appchain/coordinator/v1/tx/RegisterSubscriberChain"; - } + option (cosmos.msg.v1.service) = true; + // RegisterSubscriberChain registers a subscriber chain with the coordinator. + // By default, it is activated at the next epoch. + rpc RegisterSubscriberChain( + RegisterSubscriberChainRequest + ) returns (RegisterSubscriberChainResponse) { + option (google.api.http).post = "/exocore/appchain/coordinator/v1/tx/RegisterSubscriberChain"; + } } -// RegisterSubscriberChainRequest is the request type for the RegisterSubscriberChain message. +// RegisterSubscriberChainRequest is the request type for the +// RegisterSubscriberChain message. message RegisterSubscriberChainRequest { - option (cosmos.msg.v1.signer) = "FromAddress"; - // from_address is the address of the transaction signer. any transactions - // originating from this address may be used to edit the chain. at some point - // in the future this will be offloaded to the governance module on the - // subscriber chain. (TODO) - string from_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - // chain_id is the unique identifier for the chain, serving as the primary key. - string chain_id = 2 [(gogoproto.customname) = "ChainID"]; - // epoch_identifier specifies the unit of epoch (week, hour, day). It must be registered in the x/epochs module. - // This epoch is the identifier used by the coordinator to send validator set updates to the subscriber at the - // end of each epoch. The subscriber chain's genesis is made available at the end of the current epoch - // (marked by this identifier). - string epoch_identifier = 3; - // asset_ids lists the IDs of assets accepted by the subscriber chain. - repeated string asset_ids = 4 [(gogoproto.customname) = "AssetIDs"]; - // min_self_delegation_usd is the minimum self-delegation in USD required to be a validator on the chain. - uint64 min_self_delegation_usd = 5; - // max_validators is the maximum number of validators allowed on the chain. - uint32 max_validators = 6; - // subscriber_params are the parameters used by the subscriber module - // on the subscriber chain. - exocore.appchain.common.v1.SubscriberParams subscriber_params = 7 [(gogoproto.nullable) = false]; + option (cosmos.msg.v1.signer) = "FromAddress"; + // from_address is the address of the transaction signer. any transactions + // originating from this address may be used to edit the chain. at some point + // in the future this will be offloaded to the governance module on the + // subscriber chain. (TODO) + string from_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // chain_id is the unique identifier for the chain, serving as the primary key. + string chain_id = 2 [(gogoproto.customname) = "ChainID"]; + // epoch_identifier specifies the unit of epoch (week, hour, day). It must be + // registered in the x/epochs module. + // This epoch is the identifier used by the coordinator to send validator set + // updates to the subscriber at the end of each epoch. The subscriber chain's + // genesis is made available at the end of the current epoch + // (marked by this identifier). + string epoch_identifier = 3; + // asset_ids lists the IDs of assets accepted by the subscriber chain. + repeated string asset_ids = 4 [(gogoproto.customname) = "AssetIDs"]; + // min_self_delegation_usd is the minimum self-delegation in USD required to + // be a validator on the chain. + uint64 min_self_delegation_usd = 5; + // max_validators is the maximum number of validators allowed on the chain. + uint32 max_validators = 6; + // subscriber_params are the parameters used by the subscriber module + // on the subscriber chain. + exocore.appchain.common.v1.SubscriberParams subscriber_params = 7 [(gogoproto.nullable) = false]; } // RegisterSubscriberChainResponse defines the response structure for executing a diff --git a/proto/exocore/appchain/subscriber/v1/genesis.proto b/proto/exocore/appchain/subscriber/v1/genesis.proto index 222813eb4..2df7a1654 100644 --- a/proto/exocore/appchain/subscriber/v1/genesis.proto +++ b/proto/exocore/appchain/subscriber/v1/genesis.proto @@ -9,6 +9,6 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/typ // GenesisState is the genesis state for the appchain subscriber module. message GenesisState { - // Params is the parameters for the appchain subscriber module. - exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false]; + // Params is the parameters for the appchain subscriber module. + exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false]; } diff --git a/proto/exocore/appchain/subscriber/v1/query.proto b/proto/exocore/appchain/subscriber/v1/query.proto index 8082f8e7a..6efda0e3e 100644 --- a/proto/exocore/appchain/subscriber/v1/query.proto +++ b/proto/exocore/appchain/subscriber/v1/query.proto @@ -3,19 +3,19 @@ syntax = "proto3"; package exocore.appchain.subscriber.v1; import "exocore/appchain/common/v1/common.proto"; -import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; // Query defines the gRPC querier service. service Query { - // QueryParams returns the appchain subscriber module parameters. - rpc QueryParams(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http) = { - get: "/appchain/subscriber/params" - }; - } + // QueryParams returns the appchain subscriber module parameters. + rpc QueryParams(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http) = { + get: "/appchain/subscriber/params" + }; + } } // QueryParamsRequest is the request type for the Query.QueryParams RPC method. @@ -23,6 +23,6 @@ message QueryParamsRequest {} // QueryParamsResponse is the response type for the Query.QueryParams RPC method. message QueryParamsResponse { - // params is the parameters for the appchain subscriber module. - exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false]; + // params is the parameters for the appchain subscriber module. + exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false]; } \ No newline at end of file diff --git a/proto/exocore/epochs/v1/epochs.proto b/proto/exocore/epochs/v1/epochs.proto index 5598e699a..afdc69da4 100644 --- a/proto/exocore/epochs/v1/epochs.proto +++ b/proto/exocore/epochs/v1/epochs.proto @@ -4,10 +4,14 @@ package exocore.epochs.v1; option go_package = "github.com/ExocoreNetwork/exocore/x/epochs/types"; -// Epoch represents a specific epoch with its number and associated identifier. It is not used within this module; rather, it is designed by other modules to replace a time.Duration object. Modules are free to choose whether such a structure represents the beginning or the end of an epoch. +// Epoch represents a specific epoch with its number and associated identifier. +// It is not used within this module; rather, it is designed by other modules +// to replace a time.Duration object. Modules are free to choose whether such +// a structure represents the beginning or the end of an epoch. message Epoch { // epoch_number is the sequential number of the epoch. uint64 epoch_number = 1; - // epoch_identifier is a descriptive or unique identifier for the epoch (e.g., 'week', 'day', 'hour'). + // epoch_identifier is a descriptive or unique identifier for the epoch + // (e.g., 'week', 'day', 'hour'). string epoch_identifier = 2; } \ No newline at end of file From ca8b2ee3e5209229aa6de31a8131abf11feb79c1 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:20:33 +0000 Subject: [PATCH 18/52] chore: run proto gen --- x/appchain/common/types/common.pb.go | 113 +++++++++++----------- x/appchain/coordinator/types/params.pb.go | 72 +++++++------- x/appchain/coordinator/types/query.pb.go | 55 +++++------ x/appchain/coordinator/types/tx.pb.go | 94 +++++++++--------- x/appchain/subscriber/types/query.pb.go | 8 +- x/epochs/types/epochs.pb.go | 8 +- 6 files changed, 185 insertions(+), 165 deletions(-) diff --git a/x/appchain/common/types/common.pb.go b/x/appchain/common/types/common.pb.go index c56d81bf3..7236d149e 100644 --- a/x/appchain/common/types/common.pb.go +++ b/x/appchain/common/types/common.pb.go @@ -68,12 +68,14 @@ type SubscriberParams struct { // historical stats module. It is the same as that defined in the staking module, // however, we use the signed version so that negative values can be caught. HistoricalEntries int64 `protobuf:"varint,9,opt,name=historical_entries,json=historicalEntries,proto3" json:"historical_entries,omitempty"` - // slash_fraction_downtime is the fraction of the stake that is slashed when a validator is found to be offline. + // slash_fraction_downtime is the fraction of the stake that is slashed when a + // validator is found to be offline. SlashFractionDowntime string `protobuf:"bytes,15,opt,name=slash_fraction_downtime,json=slashFractionDowntime,proto3" json:"slash_fraction_downtime,omitempty"` // downtime_jail_duration is the duration of the jail period for a validator // after they have been found to be offline for too long. DowntimeJailDuration time.Duration `protobuf:"bytes,16,opt,name=downtime_jail_duration,json=downtimeJailDuration,proto3,stdduration" json:"downtime_jail_duration"` - // slash_fraction_double_sign is the fraction of the stake that is slashed when a validator is found to have double signed. + // slash_fraction_double_sign is the fraction of the stake that is slashed + // when a validator is found to have double signed. SlashFractionDoubleSign string `protobuf:"bytes,17,opt,name=slash_fraction_double_sign,json=slashFractionDoubleSign,proto3" json:"slash_fraction_double_sign,omitempty"` } @@ -250,7 +252,8 @@ func (m *SubscriberGenesisState) GetCoordinator() CoordinatorInfo { return CoordinatorInfo{} } -// CoordinatorInfo is the information about the coordinator chain that is stored within the subscriber chain's subscriber module. +// CoordinatorInfo is the information about the coordinator chain that is +// stored within the subscriber chain's subscriber module. type CoordinatorInfo struct { // client_state is the client state of the coordinator chain. ClientState *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty"` @@ -326,58 +329,58 @@ func init() { var fileDescriptor_71cb7b22d050d7a3 = []byte{ // 829 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x95, 0x41, 0x6f, 0x1c, 0x35, - 0x14, 0xc7, 0x33, 0x4d, 0x09, 0xad, 0xb7, 0x65, 0x37, 0x56, 0xdb, 0x4c, 0x17, 0xd8, 0xdd, 0x44, - 0x48, 0x44, 0x14, 0x66, 0xd4, 0x20, 0x21, 0x21, 0x2e, 0x90, 0xa4, 0x45, 0x8d, 0x50, 0x88, 0x76, - 0x4b, 0x91, 0x40, 0xc2, 0xf2, 0x78, 0xbc, 0xb3, 0x8f, 0xce, 0xd8, 0x23, 0xdb, 0x93, 0x94, 0xaf, - 0xc0, 0x89, 0x23, 0x1f, 0x81, 0x23, 0x57, 0xbe, 0x41, 0x8f, 0x3d, 0x72, 0x2a, 0x28, 0x39, 0xf0, - 0x1d, 0x38, 0x21, 0x7b, 0x3c, 0xd9, 0xd9, 0xad, 0x42, 0x7a, 0x19, 0xd9, 0x7e, 0xff, 0xf7, 0xf3, - 0x7b, 0xb6, 0xdf, 0x1b, 0xf4, 0x3e, 0x7f, 0x26, 0x99, 0x54, 0x3c, 0xa6, 0x65, 0xc9, 0x66, 0x14, - 0x44, 0xcc, 0x64, 0x51, 0x48, 0x11, 0x1f, 0xdf, 0xf7, 0xa3, 0xa8, 0x54, 0xd2, 0x48, 0xdc, 0xf7, - 0xc2, 0xa8, 0x11, 0x46, 0xde, 0x7c, 0x7c, 0xbf, 0x7f, 0x2b, 0x93, 0x99, 0x74, 0xb2, 0xd8, 0x8e, - 0x6a, 0x8f, 0xfe, 0x20, 0x93, 0x32, 0xcb, 0x79, 0xec, 0x66, 0x49, 0x35, 0x8d, 0xd3, 0x4a, 0x51, - 0x03, 0x0d, 0xb1, 0x3f, 0x5c, 0xb6, 0x1b, 0x28, 0xb8, 0x36, 0xb4, 0x28, 0xbd, 0x20, 0x86, 0x84, - 0xc5, 0x39, 0x64, 0x33, 0xc3, 0x72, 0xe0, 0xc2, 0xe8, 0xd8, 0x70, 0x91, 0x72, 0x55, 0x80, 0x30, - 0x36, 0xbe, 0xf9, 0xcc, 0x3b, 0xbc, 0xdd, 0xb2, 0xd3, 0x84, 0x41, 0x6c, 0x7e, 0x2a, 0xb9, 0xf6, - 0xc6, 0x75, 0x5a, 0x80, 0x90, 0xb1, 0xfb, 0xd6, 0x4b, 0x5b, 0xff, 0xae, 0xa1, 0xde, 0xa4, 0x4a, - 0x34, 0x53, 0x90, 0x70, 0x75, 0x44, 0x15, 0x2d, 0x34, 0xfe, 0x1c, 0xbd, 0xcb, 0xa4, 0x54, 0x29, - 0x08, 0x6a, 0xa4, 0x22, 0x53, 0xce, 0x49, 0x29, 0x65, 0x4e, 0x68, 0x9a, 0x2a, 0xa2, 0x8d, 0x0a, - 0x83, 0x51, 0xb0, 0x7d, 0x7d, 0x7c, 0xb7, 0x25, 0x7a, 0xc8, 0xf9, 0x91, 0x94, 0xf9, 0x17, 0x69, - 0xaa, 0x26, 0x46, 0xe1, 0x03, 0xb4, 0x99, 0x82, 0x36, 0x0a, 0x92, 0xca, 0xa6, 0x4b, 0x8c, 0xa2, - 0x42, 0x17, 0xa0, 0xb5, 0x9d, 0xb0, 0x19, 0x15, 0x82, 0xe7, 0xe1, 0x15, 0x47, 0x19, 0xb6, 0x85, - 0x8f, 0x5b, 0xba, 0xbd, 0x5a, 0x86, 0xbf, 0x46, 0xef, 0x25, 0xb9, 0x64, 0x4f, 0x35, 0x29, 0xb9, - 0x22, 0x17, 0x62, 0xc3, 0xd5, 0x51, 0xb0, 0xbd, 0x3a, 0xde, 0xac, 0xb5, 0x47, 0x5c, 0xed, 0x5f, - 0xc0, 0xc5, 0x5f, 0xa1, 0x2d, 0x7d, 0x9e, 0x32, 0x51, 0x7c, 0x01, 0x39, 0x55, 0x94, 0xd9, 0x41, - 0x78, 0xd5, 0x45, 0x37, 0x9a, 0x2b, 0xc7, 0x0b, 0xc2, 0x87, 0x5e, 0x87, 0x37, 0xd1, 0x0d, 0xc5, - 0x4f, 0xa8, 0x4a, 0x49, 0xca, 0x85, 0x2c, 0xc2, 0x37, 0x9c, 0x5f, 0xa7, 0x5e, 0xdb, 0xb7, 0x4b, - 0x98, 0x23, 0x0c, 0x09, 0x23, 0xf6, 0x72, 0x65, 0x65, 0x6c, 0x1a, 0x20, 0xd3, 0x70, 0x6d, 0x14, - 0x6c, 0x77, 0x76, 0xee, 0x46, 0xf5, 0x1b, 0x88, 0x9a, 0x37, 0x10, 0xed, 0xfb, 0x37, 0xb2, 0xfb, - 0xce, 0xf3, 0x97, 0xc3, 0x95, 0xd3, 0x97, 0xc3, 0xde, 0xa3, 0xdd, 0xbd, 0xc7, 0xb5, 0xef, 0x91, - 0x73, 0xfd, 0xf5, 0xaf, 0x61, 0x30, 0xee, 0x41, 0xc2, 0x16, 0x56, 0xf1, 0xf7, 0x68, 0xc3, 0x1d, - 0xc8, 0x94, 0xab, 0xe5, 0xbd, 0xde, 0xbc, 0x6c, 0xaf, 0x6b, 0x76, 0x2f, 0xc7, 0xbd, 0xdd, 0x30, - 0x16, 0xe1, 0x87, 0xa8, 0x57, 0x89, 0x44, 0x8a, 0x14, 0x44, 0xd6, 0x50, 0xaf, 0xbd, 0x3e, 0xb5, - 0x7b, 0xee, 0xec, 0x79, 0x1f, 0x21, 0x3c, 0x03, 0x6d, 0xa4, 0x02, 0x46, 0x73, 0xc2, 0x85, 0x51, - 0xc0, 0x75, 0x78, 0xdd, 0xdd, 0xe1, 0xfa, 0xdc, 0xf2, 0xa0, 0x36, 0xe0, 0x4f, 0xd0, 0x86, 0xce, - 0xa9, 0x9e, 0x9d, 0xdf, 0x0f, 0x49, 0xe5, 0x89, 0xb0, 0x59, 0x86, 0x5d, 0x77, 0xe0, 0xb7, 0x9d, - 0xb9, 0xb9, 0x95, 0x7d, 0x6f, 0xc4, 0x3f, 0xa0, 0x3b, 0x8d, 0x90, 0xfc, 0x48, 0x21, 0x27, 0x4d, - 0x05, 0x86, 0xbd, 0xcb, 0x82, 0xbf, 0xd9, 0x04, 0xff, 0xdb, 0x3f, 0xbf, 0x7f, 0x10, 0x8c, 0x6f, - 0x35, 0x9c, 0x03, 0x0a, 0x79, 0x23, 0xc2, 0x9f, 0xa1, 0xfe, 0x2b, 0x71, 0x55, 0x49, 0xce, 0x89, - 0x86, 0x4c, 0x84, 0xeb, 0x2e, 0xb4, 0x8d, 0xa5, 0xd0, 0xac, 0x7d, 0x02, 0x99, 0xd8, 0xfa, 0x23, - 0x40, 0x77, 0xe6, 0xc5, 0xf7, 0x25, 0x17, 0x5c, 0x83, 0x9e, 0x18, 0x6a, 0x38, 0x3e, 0x40, 0x6b, - 0xa5, 0x2b, 0x46, 0x57, 0x6b, 0x9d, 0x9d, 0x0f, 0xa3, 0x8b, 0x9b, 0x4f, 0xb4, 0x5c, 0xc0, 0xbb, - 0x57, 0x6d, 0xe8, 0x63, 0x4f, 0xc0, 0x13, 0xd4, 0x69, 0x55, 0xaa, 0x2b, 0xbb, 0xce, 0xce, 0xbd, - 0xff, 0x03, 0xee, 0xcd, 0xe5, 0x8f, 0xc4, 0x54, 0x7a, 0x5e, 0x9b, 0xb2, 0xf5, 0xf3, 0x15, 0xd4, - 0x5d, 0x92, 0xe1, 0x43, 0x74, 0xa3, 0x6e, 0x53, 0x44, 0xdb, 0x24, 0x7c, 0xe8, 0xf7, 0x22, 0x48, - 0x58, 0xd4, 0x6e, 0x62, 0x51, 0xab, 0x6d, 0xd9, 0xdd, 0xdc, 0xaa, 0xcb, 0x7b, 0xdc, 0x61, 0xf3, - 0x09, 0xfe, 0x16, 0x75, 0x99, 0x14, 0x9a, 0x0b, 0x5d, 0x69, 0x8f, 0xac, 0x83, 0x8f, 0x2e, 0x45, - 0x36, 0x6e, 0x35, 0xf5, 0x2d, 0xb6, 0x30, 0xc7, 0x87, 0xa8, 0x0b, 0x02, 0x0c, 0xd0, 0x9c, 0x1c, - 0xd3, 0x9c, 0x68, 0x6e, 0xc2, 0xd5, 0xd1, 0xea, 0x76, 0x67, 0x67, 0xd4, 0xe6, 0xd8, 0xfe, 0x19, - 0x3d, 0xa1, 0x39, 0xa4, 0x36, 0xc3, 0x6f, 0xca, 0x94, 0x1a, 0xee, 0x8f, 0xe2, 0xa6, 0x77, 0x7f, - 0x42, 0xf3, 0x09, 0x37, 0xbb, 0x93, 0xe7, 0xa7, 0x83, 0xe0, 0xc5, 0xe9, 0x20, 0xf8, 0xfb, 0x74, - 0x10, 0xfc, 0x72, 0x36, 0x58, 0x79, 0x71, 0x36, 0x58, 0xf9, 0xf3, 0x6c, 0xb0, 0xf2, 0xdd, 0xa7, - 0x19, 0x98, 0x59, 0x95, 0xd8, 0xb3, 0x8d, 0x1f, 0xd4, 0x07, 0x7e, 0xc8, 0xcd, 0x89, 0x54, 0x4f, - 0xe3, 0xe6, 0xb7, 0xf3, 0xec, 0x95, 0x1f, 0x8f, 0xeb, 0xd9, 0xc9, 0x9a, 0x7b, 0x92, 0x1f, 0xff, - 0x17, 0x00, 0x00, 0xff, 0xff, 0x31, 0x97, 0x3c, 0x0f, 0xa0, 0x06, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x41, 0x6f, 0x1c, 0x35, + 0x14, 0xce, 0x34, 0x25, 0xb4, 0xde, 0x96, 0xdd, 0x58, 0x6d, 0x33, 0x5d, 0x60, 0x77, 0x13, 0x21, + 0x11, 0x51, 0x98, 0x51, 0x83, 0x84, 0x84, 0xb8, 0x40, 0x92, 0x16, 0x35, 0x42, 0x21, 0xda, 0x2d, + 0x45, 0x02, 0x09, 0xcb, 0xe3, 0xf1, 0xce, 0x3e, 0x3a, 0x63, 0x8f, 0x6c, 0x4f, 0x52, 0xfe, 0x02, + 0x27, 0x8e, 0xfc, 0x04, 0x8e, 0x5c, 0xf9, 0x07, 0x3d, 0xf6, 0xc8, 0xa9, 0xa0, 0xe4, 0xc0, 0x7f, + 0xe0, 0x84, 0xec, 0xf1, 0x64, 0x67, 0xb7, 0x0a, 0xe9, 0x65, 0x65, 0xfb, 0x7d, 0xef, 0x7b, 0xdf, + 0x7b, 0x6f, 0xdf, 0x1b, 0xf4, 0x3e, 0x7f, 0x26, 0x99, 0x54, 0x3c, 0xa6, 0x65, 0xc9, 0x66, 0x14, + 0x44, 0xcc, 0x64, 0x51, 0x48, 0x11, 0x1f, 0xdf, 0xf7, 0xa7, 0xa8, 0x54, 0xd2, 0x48, 0xdc, 0xf7, + 0xc0, 0xa8, 0x01, 0x46, 0xde, 0x7c, 0x7c, 0xbf, 0xbf, 0x4e, 0x0b, 0x10, 0x32, 0x76, 0xbf, 0x35, + 0xbc, 0x7f, 0x2b, 0x93, 0x99, 0x74, 0xc7, 0xd8, 0x9e, 0xfc, 0xeb, 0x20, 0x93, 0x32, 0xcb, 0x79, + 0xec, 0x6e, 0x49, 0x35, 0x8d, 0xd3, 0x4a, 0x51, 0x03, 0x4d, 0x90, 0xfe, 0x70, 0xd9, 0x6e, 0xa0, + 0xe0, 0xda, 0xd0, 0xa2, 0xf4, 0x80, 0x18, 0x12, 0x16, 0xe7, 0x90, 0xcd, 0x0c, 0xcb, 0x81, 0x0b, + 0xa3, 0x63, 0xc3, 0x45, 0xca, 0x55, 0x01, 0xc2, 0x58, 0xc9, 0xf3, 0x9b, 0x77, 0x78, 0xbb, 0x65, + 0xa7, 0x09, 0x83, 0xd8, 0xfc, 0x54, 0x72, 0x5d, 0x1b, 0xb7, 0xfe, 0x5d, 0x43, 0xbd, 0x49, 0x95, + 0x68, 0xa6, 0x20, 0xe1, 0xea, 0x88, 0x2a, 0x5a, 0x68, 0xfc, 0x39, 0x7a, 0x97, 0x49, 0xa9, 0x52, + 0x10, 0xd4, 0x48, 0x45, 0xa6, 0x9c, 0x93, 0x52, 0xca, 0x9c, 0xd0, 0x34, 0x55, 0x44, 0x1b, 0x15, + 0x06, 0xa3, 0x60, 0xfb, 0xfa, 0xf8, 0x6e, 0x0b, 0xf4, 0x90, 0xf3, 0x23, 0x29, 0xf3, 0x2f, 0xd2, + 0x54, 0x4d, 0x8c, 0xc2, 0x07, 0x68, 0x33, 0x05, 0x6d, 0x14, 0x24, 0x95, 0xcd, 0x8d, 0x18, 0x45, + 0x85, 0x2e, 0x40, 0x6b, 0x7b, 0x61, 0x33, 0x2a, 0x04, 0xcf, 0xc3, 0x2b, 0x8e, 0x65, 0xd8, 0x06, + 0x3e, 0x6e, 0xe1, 0xf6, 0x6a, 0x18, 0xfe, 0x1a, 0xbd, 0x97, 0xe4, 0x92, 0x3d, 0xd5, 0xa4, 0xe4, + 0x8a, 0x5c, 0x48, 0x1b, 0xae, 0x8e, 0x82, 0xed, 0xd5, 0xf1, 0x66, 0x8d, 0x3d, 0xe2, 0x6a, 0xff, + 0x02, 0x5e, 0xfc, 0x15, 0xda, 0xd2, 0xe7, 0x29, 0x13, 0xc5, 0x17, 0x28, 0xa7, 0x8a, 0x32, 0x7b, + 0x08, 0xaf, 0x3a, 0x75, 0xa3, 0x39, 0x72, 0xbc, 0x00, 0x7c, 0xe8, 0x71, 0x78, 0x13, 0xdd, 0x50, + 0xfc, 0x84, 0xaa, 0x94, 0xa4, 0x5c, 0xc8, 0x22, 0x7c, 0xc3, 0xf9, 0x75, 0xea, 0xb7, 0x7d, 0xfb, + 0x84, 0x39, 0xc2, 0x90, 0x30, 0x62, 0x3b, 0x29, 0x2b, 0x63, 0xd3, 0x00, 0x99, 0x86, 0x6b, 0xa3, + 0x60, 0xbb, 0xb3, 0x73, 0x37, 0xaa, 0x1b, 0x1e, 0x35, 0x0d, 0x8f, 0xf6, 0xfd, 0x1f, 0x62, 0xf7, + 0x9d, 0xe7, 0x2f, 0x87, 0x2b, 0xa7, 0x2f, 0x87, 0xbd, 0x47, 0xbb, 0x7b, 0x8f, 0x6b, 0xdf, 0x23, + 0xe7, 0xfa, 0xeb, 0x5f, 0xc3, 0x60, 0xdc, 0x83, 0x84, 0x2d, 0xbc, 0xe2, 0xef, 0xd1, 0x86, 0x2b, + 0xc8, 0x94, 0xab, 0xe5, 0x58, 0x6f, 0x5e, 0x16, 0xeb, 0x9a, 0x8d, 0xe5, 0x78, 0x6f, 0x37, 0x1c, + 0x8b, 0xe4, 0x87, 0xa8, 0x57, 0x89, 0x44, 0x8a, 0x14, 0x44, 0xd6, 0xb0, 0x5e, 0x7b, 0x7d, 0xd6, + 0xee, 0xb9, 0xb3, 0xe7, 0xfb, 0x08, 0xe1, 0x19, 0x68, 0x23, 0x15, 0x30, 0x9a, 0x13, 0x2e, 0x8c, + 0x02, 0xae, 0xc3, 0xeb, 0xae, 0x87, 0xeb, 0x73, 0xcb, 0x83, 0xda, 0x80, 0x3f, 0x41, 0x1b, 0x3a, + 0xa7, 0x7a, 0x76, 0xde, 0x1f, 0x92, 0xca, 0x13, 0x61, 0xb3, 0x0c, 0xbb, 0xae, 0xe0, 0xb7, 0x9d, + 0xb9, 0xe9, 0xca, 0xbe, 0x37, 0xe2, 0x1f, 0xd0, 0x9d, 0x06, 0x48, 0x7e, 0xa4, 0x90, 0x93, 0x66, + 0xdc, 0xc2, 0xde, 0x65, 0xe2, 0x6f, 0x36, 0xe2, 0x7f, 0xfb, 0xe7, 0xf7, 0x0f, 0x82, 0xf1, 0xad, + 0x86, 0xe7, 0x80, 0x42, 0xde, 0x80, 0xf0, 0x67, 0xa8, 0xff, 0x8a, 0xae, 0x2a, 0xc9, 0x39, 0xd1, + 0x90, 0x89, 0x70, 0xdd, 0x49, 0xdb, 0x58, 0x92, 0x66, 0xed, 0x13, 0xc8, 0xc4, 0xd6, 0x1f, 0x01, + 0xba, 0x33, 0x1f, 0xbe, 0x2f, 0xb9, 0xe0, 0x1a, 0xf4, 0xc4, 0x50, 0xc3, 0xf1, 0x01, 0x5a, 0x2b, + 0xdd, 0x30, 0xba, 0x59, 0xeb, 0xec, 0x7c, 0x18, 0x5d, 0xbc, 0x7c, 0xa2, 0xe5, 0x01, 0xde, 0xbd, + 0x6a, 0xa5, 0x8f, 0x3d, 0x03, 0x9e, 0xa0, 0x4e, 0x6b, 0x52, 0xdd, 0xd8, 0x75, 0x76, 0xee, 0xfd, + 0x1f, 0xe1, 0xde, 0x1c, 0xfe, 0x48, 0x4c, 0xa5, 0xe7, 0x6b, 0xb3, 0x6c, 0xfd, 0x7c, 0x05, 0x75, + 0x97, 0x60, 0xf8, 0x10, 0xdd, 0xa8, 0x77, 0x12, 0xd1, 0x36, 0x09, 0x2f, 0xfd, 0x5e, 0x04, 0x09, + 0x8b, 0xda, 0x1b, 0x2b, 0x6a, 0xed, 0x28, 0x1b, 0xcd, 0xbd, 0xba, 0xbc, 0xc7, 0x1d, 0x36, 0xbf, + 0xe0, 0x6f, 0x51, 0x97, 0x49, 0xa1, 0xb9, 0xd0, 0x95, 0xf6, 0x94, 0xb5, 0xf8, 0xe8, 0x52, 0xca, + 0xc6, 0xad, 0x66, 0x7d, 0x8b, 0x2d, 0xdc, 0xf1, 0x21, 0xea, 0x82, 0x00, 0x03, 0x34, 0x27, 0xc7, + 0x34, 0x27, 0x9a, 0x9b, 0x70, 0x75, 0xb4, 0xba, 0xdd, 0xd9, 0x19, 0xb5, 0x79, 0xec, 0xb2, 0x8c, + 0x9e, 0xd0, 0x1c, 0x52, 0x9b, 0xe1, 0x37, 0x65, 0x4a, 0x0d, 0xf7, 0xa5, 0xb8, 0xe9, 0xdd, 0x9f, + 0xd0, 0x7c, 0xc2, 0xcd, 0xee, 0xe4, 0xf9, 0xe9, 0x20, 0x78, 0x71, 0x3a, 0x08, 0xfe, 0x3e, 0x1d, + 0x04, 0xbf, 0x9c, 0x0d, 0x56, 0x5e, 0x9c, 0x0d, 0x56, 0xfe, 0x3c, 0x1b, 0xac, 0x7c, 0xf7, 0x69, + 0x06, 0x66, 0x56, 0x25, 0xb6, 0xb6, 0xf1, 0x83, 0xba, 0xe0, 0x87, 0xdc, 0x9c, 0x48, 0xf5, 0x34, + 0x6e, 0x3e, 0x3b, 0xcf, 0x5e, 0xf9, 0xf0, 0xb8, 0x05, 0x9d, 0xac, 0xb9, 0xbf, 0xe4, 0xc7, 0xff, + 0x05, 0x00, 0x00, 0xff, 0xff, 0x26, 0xae, 0x3d, 0xf1, 0xa0, 0x06, 0x00, 0x00, } func (m *SubscriberParams) Marshal() (dAtA []byte, err error) { diff --git a/x/appchain/coordinator/types/params.pb.go b/x/appchain/coordinator/types/params.pb.go index 6f64ea43e..4eb64897d 100644 --- a/x/appchain/coordinator/types/params.pb.go +++ b/x/appchain/coordinator/types/params.pb.go @@ -33,13 +33,19 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Params struct { // template_client is the IBC template client. TemplateClient *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=template_client,json=templateClient,proto3" json:"template_client,omitempty"` - // trusting_period_fraction is the multiplier applied on the subscriber's unbonding duration to determine the IBC trusting period. + // trusting_period_fraction is the multiplier applied on the subscriber's + // unbonding duration to determine the IBC trusting period. TrustingPeriodFraction string `protobuf:"bytes,2,opt,name=trusting_period_fraction,json=trustingPeriodFraction,proto3" json:"trusting_period_fraction,omitempty"` - // ibc_timeout_period is the timeout period for IBC packets. While our system is largely created with epochs as a unit of time (and not standard durations), this is an exception since it is used directly by the IBC codebase. + // ibc_timeout_period is the timeout period for IBC packets. While our + // system is largely created with epochs as a unit of time (and not + // standard durations), this is an exception since it is used directly + // by the IBC codebase. IBCTimeoutPeriod time.Duration `protobuf:"bytes,3,opt,name=ibc_timeout_period,json=ibcTimeoutPeriod,proto3,stdduration" json:"ibc_timeout_period"` - // init_timeout_period is the period within which the subscriber chain must make a connection with the coordinator, after being spawned. + // init_timeout_period is the period within which the subscriber chain + // must make a connection with the coordinator, after being spawned. InitTimeoutPeriod types.Epoch `protobuf:"bytes,4,opt,name=init_timeout_period,json=initTimeoutPeriod,proto3" json:"init_timeout_period"` - // vsc_timeout_period is the period within which the subscriber chain must respond to a VSC request, after it is sent. + // vsc_timeout_period is the period within which the subscriber chain + // must respond to a VSC request, after it is sent. VSCTimeoutPeriod types.Epoch `protobuf:"bytes,5,opt,name=vsc_timeout_period,json=vscTimeoutPeriod,proto3" json:"vsc_timeout_period"` } @@ -120,35 +126,35 @@ func init() { } var fileDescriptor_153952e3bb2d49c4 = []byte{ - // 438 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0xc1, 0x6e, 0xd4, 0x30, - 0x14, 0xdc, 0xd0, 0x52, 0x89, 0x20, 0xc1, 0x12, 0x10, 0x0a, 0x15, 0xca, 0x56, 0x9c, 0x2a, 0x81, - 0x6c, 0x2d, 0x5c, 0x38, 0x71, 0xd8, 0x52, 0x24, 0x2e, 0x55, 0x95, 0x56, 0x08, 0x71, 0x59, 0x1c, - 0xaf, 0x9b, 0x7d, 0x62, 0xe3, 0x67, 0x39, 0x2f, 0xa1, 0xfc, 0x05, 0x47, 0x7e, 0x83, 0xbf, 0xe8, - 0xb1, 0x47, 0x4e, 0x05, 0xed, 0xfe, 0x08, 0x8a, 0x1d, 0x8b, 0x5d, 0x40, 0xea, 0xcd, 0x7e, 0x33, - 0x6f, 0x66, 0x32, 0x71, 0xfc, 0x4c, 0x9d, 0xa3, 0x44, 0xab, 0xb8, 0x30, 0x46, 0xce, 0x05, 0x68, - 0x2e, 0x11, 0xed, 0x0c, 0xb4, 0x20, 0xb4, 0xbc, 0x1d, 0x73, 0x23, 0xac, 0xa8, 0x6a, 0x66, 0x2c, - 0x12, 0x26, 0xa3, 0x9e, 0xcd, 0x02, 0x9b, 0xad, 0xb1, 0x59, 0x3b, 0xde, 0x7d, 0x50, 0x62, 0x89, - 0x8e, 0xcb, 0xbb, 0x93, 0x5f, 0xdb, 0xcd, 0x4a, 0xc4, 0x72, 0xa1, 0xb8, 0xbb, 0x15, 0xcd, 0x19, - 0x9f, 0x35, 0x56, 0x10, 0xa0, 0xee, 0x71, 0x0e, 0x85, 0xe4, 0x0b, 0x28, 0xe7, 0x24, 0x17, 0xa0, - 0x34, 0xd5, 0x9c, 0x94, 0x9e, 0x29, 0x5b, 0x81, 0xa6, 0x2e, 0xc3, 0x9f, 0x5b, 0x10, 0x0c, 0xa9, - 0x95, 0x41, 0x39, 0xaf, 0x3b, 0x8e, 0x3f, 0x79, 0xfc, 0xc9, 0xf7, 0xad, 0x78, 0xe7, 0xd8, 0x05, - 0x4f, 0x4e, 0xe3, 0xbb, 0xa4, 0x2a, 0xb3, 0x10, 0xa4, 0xa6, 0x5e, 0x3d, 0x8d, 0xf6, 0xa2, 0xfd, - 0xdb, 0xcf, 0x9f, 0x32, 0x28, 0x24, 0x5b, 0x77, 0x65, 0x6b, 0x3e, 0xed, 0x98, 0x1d, 0xb8, 0xe9, - 0x09, 0x09, 0x52, 0xf9, 0x9d, 0xa0, 0xe1, 0x87, 0xc9, 0xcb, 0x38, 0x25, 0xdb, 0xd4, 0x04, 0xba, - 0x9c, 0x1a, 0x65, 0x01, 0x67, 0xd3, 0x33, 0x2b, 0x64, 0xf7, 0x4d, 0xe9, 0x8d, 0xbd, 0x68, 0xff, - 0x56, 0xfe, 0x30, 0xe0, 0xc7, 0x0e, 0x7e, 0xd3, 0xa3, 0x89, 0x8a, 0x13, 0x28, 0xe4, 0x94, 0xa0, - 0x52, 0xd8, 0x50, 0xbf, 0x9c, 0x6e, 0xb9, 0x48, 0x8f, 0x98, 0x2f, 0x8a, 0x85, 0xa2, 0xd8, 0xeb, - 0xbe, 0xa8, 0xc9, 0xe3, 0x8b, 0xab, 0xd1, 0x60, 0x79, 0x35, 0x1a, 0xbe, 0x9d, 0x1c, 0x9c, 0xfa, - 0x5d, 0x2f, 0xfc, 0xed, 0xe7, 0x28, 0xca, 0x87, 0x50, 0xc8, 0x8d, 0x69, 0x72, 0x14, 0xdf, 0x07, - 0x0d, 0xf4, 0xb7, 0xcf, 0xb6, 0xf3, 0x49, 0x59, 0xf8, 0x8f, 0x7d, 0x6b, 0xed, 0x98, 0x1d, 0x76, - 0xa7, 0xc9, 0x76, 0x67, 0x93, 0xdf, 0xeb, 0x56, 0x37, 0xf5, 0x3e, 0xc6, 0x49, 0x5b, 0xff, 0x13, - 0xfb, 0xe6, 0x35, 0x72, 0x69, 0x48, 0xfd, 0xee, 0x64, 0x33, 0x75, 0x3e, 0x6c, 0xeb, 0xcd, 0xc4, - 0x93, 0xf7, 0x17, 0xcb, 0x2c, 0xba, 0x5c, 0x66, 0xd1, 0xaf, 0x65, 0x16, 0x7d, 0x5d, 0x65, 0x83, - 0xcb, 0x55, 0x36, 0xf8, 0xb1, 0xca, 0x06, 0x1f, 0x5e, 0x95, 0x40, 0xf3, 0xa6, 0x60, 0x12, 0x2b, - 0x7e, 0xe8, 0x9d, 0x8e, 0x14, 0x7d, 0x46, 0xfb, 0x89, 0x87, 0x77, 0x70, 0xfe, 0xff, 0xf7, 0x4b, - 0x5f, 0x8c, 0xaa, 0x8b, 0x1d, 0x57, 0xe7, 0x8b, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb0, 0xa3, - 0x9c, 0xaa, 0xec, 0x02, 0x00, 0x00, + // 439 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xc1, 0x6e, 0xd4, 0x30, + 0x10, 0x86, 0x37, 0xb4, 0x54, 0x22, 0x48, 0xb0, 0x04, 0x84, 0x42, 0x85, 0xb2, 0x15, 0xa7, 0x4a, + 0x20, 0x5b, 0x0b, 0x17, 0x4e, 0x1c, 0xb6, 0x14, 0x89, 0x4b, 0x55, 0xa5, 0x15, 0x42, 0x5c, 0x16, + 0xc7, 0xeb, 0x66, 0x47, 0x6c, 0x3c, 0x96, 0x33, 0x09, 0xe5, 0x2d, 0x38, 0xf2, 0x1a, 0xbc, 0x45, + 0x8f, 0x3d, 0x72, 0x2a, 0x68, 0xf7, 0x45, 0x50, 0xec, 0x58, 0xec, 0x02, 0x52, 0x6f, 0xe3, 0x19, + 0xff, 0xdf, 0xff, 0x6b, 0xec, 0xf8, 0x99, 0x3a, 0x47, 0x89, 0x56, 0x71, 0x61, 0x8c, 0x9c, 0x0b, + 0xd0, 0x5c, 0x22, 0xda, 0x19, 0x68, 0x41, 0x68, 0x79, 0x3b, 0xe6, 0x46, 0x58, 0x51, 0xd5, 0xcc, + 0x58, 0x24, 0x4c, 0x46, 0xfd, 0x6d, 0x16, 0x6e, 0xb3, 0xb5, 0xdb, 0xac, 0x1d, 0xef, 0x66, 0x01, + 0xa7, 0x0c, 0xca, 0x79, 0xdd, 0x01, 0x7c, 0xe5, 0x01, 0xbb, 0x0f, 0x4a, 0x2c, 0xd1, 0x95, 0xbc, + 0xab, 0xfa, 0x6e, 0x56, 0x22, 0x96, 0x0b, 0xc5, 0xdd, 0xa9, 0x68, 0xce, 0xf8, 0xac, 0xb1, 0x82, + 0x00, 0x75, 0x3f, 0xe7, 0x50, 0x48, 0xbe, 0x80, 0x72, 0x4e, 0x72, 0x01, 0x4a, 0x53, 0xcd, 0x49, + 0xe9, 0x99, 0xb2, 0x15, 0x68, 0xea, 0x2c, 0xfe, 0x9c, 0xbc, 0xe0, 0xc9, 0xf7, 0xad, 0x78, 0xe7, + 0xd8, 0x05, 0x4f, 0x4e, 0xe3, 0xbb, 0xa4, 0x2a, 0xb3, 0x10, 0xa4, 0xa6, 0x5e, 0x9d, 0x46, 0x7b, + 0xd1, 0xfe, 0xed, 0xe7, 0x4f, 0x19, 0x14, 0x92, 0xad, 0x53, 0xd9, 0x1a, 0xa7, 0x1d, 0xb3, 0x03, + 0xd7, 0x3d, 0x21, 0x41, 0x2a, 0xbf, 0x13, 0x18, 0xbe, 0x99, 0xbc, 0x8c, 0x53, 0xb2, 0x4d, 0x4d, + 0xa0, 0xcb, 0xa9, 0x51, 0x16, 0x70, 0x36, 0x3d, 0xb3, 0x42, 0x76, 0x99, 0xd3, 0x1b, 0x7b, 0xd1, + 0xfe, 0xad, 0xfc, 0x61, 0x98, 0x1f, 0xbb, 0xf1, 0x9b, 0x7e, 0x9a, 0xa8, 0x38, 0x81, 0x42, 0x4e, + 0x09, 0x2a, 0x85, 0x0d, 0xf5, 0xe2, 0x74, 0xcb, 0x45, 0x7a, 0xc4, 0xfc, 0x22, 0x58, 0x58, 0x04, + 0x7b, 0xdd, 0x2f, 0x62, 0xf2, 0xf8, 0xe2, 0x6a, 0x34, 0x58, 0x5e, 0x8d, 0x86, 0x6f, 0x27, 0x07, + 0xa7, 0x5e, 0xeb, 0xc1, 0xdf, 0x7e, 0x8e, 0xa2, 0x7c, 0x08, 0x85, 0xdc, 0xe8, 0x26, 0x47, 0xf1, + 0x7d, 0xd0, 0x40, 0x7f, 0xfb, 0x6c, 0x3b, 0x9f, 0x94, 0x85, 0x77, 0xec, 0x1f, 0xa7, 0x1d, 0xb3, + 0xc3, 0xae, 0x9a, 0x6c, 0x77, 0x36, 0xf9, 0xbd, 0x4e, 0xba, 0xc9, 0xfb, 0x18, 0x27, 0x6d, 0xfd, + 0x4f, 0xec, 0x9b, 0xd7, 0xe0, 0xd2, 0x90, 0xfa, 0xdd, 0xc9, 0x66, 0xea, 0x7c, 0xd8, 0xd6, 0x9b, + 0x89, 0x27, 0xef, 0x2f, 0x96, 0x59, 0x74, 0xb9, 0xcc, 0xa2, 0x5f, 0xcb, 0x2c, 0xfa, 0xba, 0xca, + 0x06, 0x97, 0xab, 0x6c, 0xf0, 0x63, 0x95, 0x0d, 0x3e, 0xbc, 0x2a, 0x81, 0xe6, 0x4d, 0xc1, 0x24, + 0x56, 0xfc, 0xd0, 0x3b, 0x1d, 0x29, 0xfa, 0x8c, 0xf6, 0x13, 0x0f, 0xdf, 0xed, 0xfc, 0xff, 0xff, + 0x97, 0xbe, 0x18, 0x55, 0x17, 0x3b, 0x6e, 0x9d, 0x2f, 0x7e, 0x07, 0x00, 0x00, 0xff, 0xff, 0x5d, + 0xbe, 0xf3, 0x4d, 0xec, 0x02, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { diff --git a/x/appchain/coordinator/types/query.pb.go b/x/appchain/coordinator/types/query.pb.go index 34e8bba1d..898ff6177 100644 --- a/x/appchain/coordinator/types/query.pb.go +++ b/x/appchain/coordinator/types/query.pb.go @@ -162,6 +162,7 @@ func (m *QuerySubscriberGenesisRequest) GetChain() string { // QuerySubscriberGenesisResponse is the response type for the Query.QuerySubscriberGenesis RPC method. type QuerySubscriberGenesisResponse struct { + // subscriber_genesis is the genesis state for the subscriber chain. SubscriberGenesis types.SubscriberGenesisState `protobuf:"bytes,1,opt,name=subscriber_genesis,json=subscriberGenesis,proto3" json:"subscriber_genesis"` } @@ -218,33 +219,33 @@ func init() { var fileDescriptor_c71eb5ef95876a4b = []byte{ // 427 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x41, 0x8b, 0xd3, 0x40, - 0x14, 0xce, 0xa8, 0xbb, 0xe0, 0xec, 0xc9, 0xb1, 0x88, 0x84, 0x75, 0x56, 0x82, 0xb0, 0x82, 0x92, - 0xa1, 0x5d, 0x3d, 0x89, 0x2b, 0x54, 0x8a, 0x37, 0xd1, 0xf6, 0x22, 0x22, 0xc8, 0x24, 0x0e, 0x69, - 0xd0, 0xce, 0x4b, 0x67, 0x26, 0xb5, 0x45, 0xbc, 0x78, 0xeb, 0x4d, 0xf0, 0xee, 0xef, 0xe9, 0xb1, - 0xe0, 0xc5, 0x53, 0x91, 0xd6, 0x1f, 0x22, 0x99, 0x49, 0x4b, 0xb5, 0x29, 0x51, 0x6f, 0x93, 0x79, - 0xdf, 0xfb, 0xbe, 0xef, 0x7d, 0x6f, 0x82, 0xef, 0x88, 0x31, 0xc4, 0xa0, 0x04, 0xe3, 0x59, 0x16, - 0xf7, 0x79, 0x2a, 0x59, 0x0c, 0xa0, 0xde, 0xa4, 0x92, 0x1b, 0x50, 0x6c, 0xd4, 0x64, 0xc3, 0x5c, - 0xa8, 0x49, 0x98, 0x29, 0x30, 0x40, 0x4e, 0x4a, 0x70, 0xb8, 0x06, 0x87, 0x5b, 0xe0, 0x70, 0xd4, - 0xf4, 0x4f, 0x2b, 0xd8, 0x06, 0x03, 0x90, 0x05, 0x91, 0x3b, 0x39, 0x26, 0xff, 0x6e, 0x9d, 0x6c, - 0xc6, 0x15, 0x1f, 0xe8, 0x12, 0x7d, 0x9c, 0x00, 0x24, 0xef, 0x0a, 0x70, 0xca, 0xb8, 0x94, 0x60, - 0xb8, 0x49, 0x41, 0xae, 0xab, 0x8d, 0x04, 0x12, 0xb0, 0x47, 0x56, 0x9c, 0xdc, 0x6d, 0xd0, 0xc0, - 0xe4, 0x79, 0x61, 0xfd, 0x99, 0x25, 0xea, 0x8a, 0x61, 0x2e, 0xb4, 0x09, 0x5e, 0xe1, 0xab, 0xbf, - 0xdd, 0xea, 0x0c, 0xa4, 0x16, 0xa4, 0x83, 0x0f, 0x9d, 0xe0, 0x75, 0x74, 0x13, 0xdd, 0x3e, 0x6a, - 0x9d, 0x86, 0x35, 0x93, 0x86, 0x8e, 0xa0, 0x7d, 0x69, 0xb6, 0x38, 0xf1, 0xba, 0x65, 0x73, 0x70, - 0x1f, 0xdf, 0xb0, 0xec, 0xbd, 0x3c, 0xd2, 0xb1, 0x4a, 0x23, 0xa1, 0x9e, 0x08, 0x29, 0x74, 0xba, - 0x96, 0x27, 0x0d, 0x7c, 0x60, 0xd9, 0xac, 0xcc, 0xe5, 0xae, 0xfb, 0x08, 0xa6, 0x08, 0xd3, 0x7d, - 0x7d, 0xa5, 0xc1, 0x04, 0x13, 0xbd, 0x29, 0xbe, 0x4e, 0x5c, 0xb5, 0x34, 0xdb, 0xaa, 0x32, 0x6b, - 0xb3, 0x1e, 0x35, 0xc3, 0x1d, 0xca, 0x9e, 0xe1, 0x46, 0x94, 0xbe, 0xaf, 0xe8, 0x3f, 0xab, 0xad, - 0xe9, 0x45, 0x7c, 0x60, 0xbd, 0x90, 0xaf, 0x08, 0x1f, 0x6d, 0x65, 0x45, 0xce, 0x6a, 0x33, 0xd9, - 0xcd, 0xdb, 0xbf, 0xf7, 0x6f, 0x4d, 0x6e, 0xda, 0xe0, 0xd6, 0xa7, 0x6f, 0x3f, 0xbf, 0x5c, 0xa0, - 0xe4, 0xb8, 0xfa, 0x79, 0xb8, 0xb4, 0xc9, 0x02, 0xe1, 0x6b, 0xd5, 0xb1, 0x91, 0xf3, 0xbf, 0x93, - 0xdd, 0xb7, 0x27, 0xff, 0xd1, 0x7f, 0xf7, 0x97, 0x13, 0x3c, 0xb6, 0x13, 0x3c, 0x24, 0x0f, 0x58, - 0xdd, 0x43, 0xdf, 0x5d, 0x2b, 0xfb, 0x60, 0x81, 0x1f, 0xdb, 0x2f, 0x66, 0x4b, 0x8a, 0xe6, 0x4b, - 0x8a, 0x7e, 0x2c, 0x29, 0xfa, 0xbc, 0xa2, 0xde, 0x7c, 0x45, 0xbd, 0xef, 0x2b, 0xea, 0xbd, 0x3c, - 0x4f, 0x52, 0xd3, 0xcf, 0xa3, 0x62, 0xcf, 0xac, 0xe3, 0x04, 0x9e, 0x0a, 0xf3, 0x1e, 0xd4, 0xdb, - 0x8d, 0xde, 0xb8, 0x5a, 0xd1, 0x4c, 0x32, 0xa1, 0xa3, 0x43, 0xfb, 0x8f, 0x9c, 0xfd, 0x0a, 0x00, - 0x00, 0xff, 0xff, 0xb0, 0x92, 0xd4, 0x9f, 0xfe, 0x03, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x4f, 0x8b, 0x13, 0x31, + 0x14, 0x9f, 0xa8, 0xbb, 0x60, 0xf6, 0x64, 0x2c, 0x22, 0xc3, 0x9a, 0x95, 0x41, 0x58, 0x41, 0x99, + 0xd0, 0xae, 0x9e, 0xc4, 0x15, 0x56, 0x16, 0x6f, 0xa2, 0xdd, 0x8b, 0x88, 0x20, 0x99, 0x31, 0xcc, + 0x0e, 0xda, 0xbc, 0x69, 0x92, 0xa9, 0x2d, 0xe2, 0xc5, 0x5b, 0x6f, 0x82, 0x77, 0x3f, 0x4f, 0x8f, + 0x05, 0x2f, 0x9e, 0x8a, 0xb4, 0x7e, 0x10, 0x99, 0x24, 0x2d, 0xd5, 0x4e, 0x19, 0xf5, 0x96, 0xc9, + 0x7b, 0xbf, 0x3f, 0xef, 0xf7, 0x32, 0xf8, 0x8e, 0x18, 0x42, 0x0a, 0x4a, 0x30, 0x5e, 0x14, 0xe9, + 0x39, 0xcf, 0x25, 0x4b, 0x01, 0xd4, 0x9b, 0x5c, 0x72, 0x03, 0x8a, 0x0d, 0xda, 0xac, 0x5f, 0x0a, + 0x35, 0x8a, 0x0b, 0x05, 0x06, 0xc8, 0x81, 0x6f, 0x8e, 0x97, 0xcd, 0xf1, 0x5a, 0x73, 0x3c, 0x68, + 0x87, 0x87, 0x35, 0x6c, 0xbd, 0x1e, 0xc8, 0x8a, 0xc8, 0x9d, 0x1c, 0x53, 0x78, 0xb7, 0x49, 0xb6, + 0xe0, 0x8a, 0xf7, 0xb4, 0xef, 0x6e, 0x65, 0x90, 0x81, 0x3d, 0xb2, 0xea, 0xe4, 0x6f, 0xf7, 0x33, + 0x80, 0xec, 0x5d, 0x45, 0x91, 0x33, 0x2e, 0x25, 0x18, 0x6e, 0x72, 0x90, 0x1e, 0x13, 0xb5, 0x30, + 0x79, 0x5e, 0x59, 0x7f, 0x66, 0x89, 0xba, 0xa2, 0x5f, 0x0a, 0x6d, 0xa2, 0x57, 0xf8, 0xea, 0x6f, + 0xb7, 0xba, 0x00, 0xa9, 0x05, 0x39, 0xc5, 0xbb, 0x4e, 0xf0, 0x3a, 0xba, 0x89, 0x6e, 0xef, 0x75, + 0x0e, 0xe3, 0x86, 0x49, 0x63, 0x47, 0x70, 0x72, 0x69, 0x32, 0x3b, 0x08, 0xba, 0x1e, 0x1c, 0xdd, + 0xc7, 0x37, 0x2c, 0xfb, 0x59, 0x99, 0xe8, 0x54, 0xe5, 0x89, 0x50, 0x4f, 0x84, 0x14, 0x3a, 0x5f, + 0xca, 0x93, 0x16, 0xde, 0xb1, 0x6c, 0x56, 0xe6, 0x72, 0xd7, 0x7d, 0x44, 0x63, 0x84, 0xe9, 0x36, + 0x9c, 0x37, 0x98, 0x61, 0xa2, 0x57, 0xc5, 0xd7, 0x99, 0xab, 0x7a, 0xb3, 0x9d, 0x3a, 0xb3, 0x36, + 0xeb, 0x41, 0x3b, 0xde, 0xa0, 0x3c, 0x33, 0xdc, 0x08, 0xef, 0xfb, 0x8a, 0xfe, 0xb3, 0xda, 0x19, + 0x5f, 0xc4, 0x3b, 0xd6, 0x0b, 0xf9, 0x8a, 0xf0, 0xde, 0x5a, 0x56, 0xe4, 0xa8, 0x31, 0x93, 0xcd, + 0xbc, 0xc3, 0x7b, 0xff, 0x06, 0x72, 0xd3, 0x46, 0xb7, 0x3e, 0x7d, 0xfb, 0xf9, 0xe5, 0x02, 0x25, + 0xfb, 0xf5, 0xcf, 0xc3, 0xa5, 0x4d, 0x66, 0x08, 0x5f, 0xab, 0x8f, 0x8d, 0x1c, 0xff, 0x9d, 0xec, + 0xb6, 0x3d, 0x85, 0x8f, 0xfe, 0x1b, 0xef, 0x27, 0x78, 0x6c, 0x27, 0x78, 0x48, 0x1e, 0xb0, 0xa6, + 0x87, 0xbe, 0xb9, 0x56, 0xf6, 0xc1, 0x36, 0x7e, 0x3c, 0x79, 0x31, 0x99, 0x53, 0x34, 0x9d, 0x53, + 0xf4, 0x63, 0x4e, 0xd1, 0xe7, 0x05, 0x0d, 0xa6, 0x0b, 0x1a, 0x7c, 0x5f, 0xd0, 0xe0, 0xe5, 0x71, + 0x96, 0x9b, 0xf3, 0x32, 0xa9, 0xf6, 0xcc, 0x4e, 0x9d, 0xc0, 0x53, 0x61, 0xde, 0x83, 0x7a, 0xbb, + 0xd2, 0x1b, 0xd6, 0x2b, 0x9a, 0x51, 0x21, 0x74, 0xb2, 0x6b, 0xff, 0x91, 0xa3, 0x5f, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x8e, 0x5d, 0x4a, 0xc3, 0xfe, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/appchain/coordinator/types/tx.pb.go b/x/appchain/coordinator/types/tx.pb.go index 61ea3e631..997c99436 100644 --- a/x/appchain/coordinator/types/tx.pb.go +++ b/x/appchain/coordinator/types/tx.pb.go @@ -32,7 +32,8 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// RegisterSubscriberChainRequest is the request type for the RegisterSubscriberChain message. +// RegisterSubscriberChainRequest is the request type for the +// RegisterSubscriberChain message. type RegisterSubscriberChainRequest struct { // from_address is the address of the transaction signer. any transactions // originating from this address may be used to edit the chain. at some point @@ -41,14 +42,17 @@ type RegisterSubscriberChainRequest struct { FromAddress string `protobuf:"bytes,1,opt,name=from_address,json=fromAddress,proto3" json:"from_address,omitempty"` // chain_id is the unique identifier for the chain, serving as the primary key. ChainID string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - // epoch_identifier specifies the unit of epoch (week, hour, day). It must be registered in the x/epochs module. - // This epoch is the identifier used by the coordinator to send validator set updates to the subscriber at the - // end of each epoch. The subscriber chain's genesis is made available at the end of the current epoch + // epoch_identifier specifies the unit of epoch (week, hour, day). It must be + // registered in the x/epochs module. + // This epoch is the identifier used by the coordinator to send validator set + // updates to the subscriber at the end of each epoch. The subscriber chain's + // genesis is made available at the end of the current epoch // (marked by this identifier). EpochIdentifier string `protobuf:"bytes,3,opt,name=epoch_identifier,json=epochIdentifier,proto3" json:"epoch_identifier,omitempty"` // asset_ids lists the IDs of assets accepted by the subscriber chain. AssetIDs []string `protobuf:"bytes,4,rep,name=asset_ids,json=assetIds,proto3" json:"asset_ids,omitempty"` - // min_self_delegation_usd is the minimum self-delegation in USD required to be a validator on the chain. + // min_self_delegation_usd is the minimum self-delegation in USD required to + // be a validator on the chain. MinSelfDelegationUsd uint64 `protobuf:"varint,5,opt,name=min_self_delegation_usd,json=minSelfDelegationUsd,proto3" json:"min_self_delegation_usd,omitempty"` // max_validators is the maximum number of validators allowed on the chain. MaxValidators uint32 `protobuf:"varint,6,opt,name=max_validators,json=maxValidators,proto3" json:"max_validators,omitempty"` @@ -187,43 +191,43 @@ func init() { } var fileDescriptor_23c4660f55e25cbc = []byte{ - // 571 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcf, 0x6a, 0x13, 0x41, - 0x1c, 0xce, 0x36, 0x6d, 0x93, 0x4c, 0x5a, 0x8d, 0x4b, 0x20, 0x6b, 0x90, 0x4d, 0x0c, 0xa8, 0xdb, - 0xa2, 0xbb, 0xa4, 0xe2, 0xc5, 0xe2, 0x9f, 0xa6, 0x51, 0xc8, 0x41, 0x91, 0x0d, 0x8a, 0x78, 0x59, - 0x26, 0x3b, 0x93, 0xcd, 0x60, 0x76, 0x67, 0x9d, 0xdf, 0x24, 0xc6, 0x9b, 0xf4, 0x09, 0x04, 0x5f, - 0xc3, 0x43, 0x0f, 0x3e, 0x44, 0x8f, 0x45, 0x2f, 0x9e, 0x82, 0x26, 0x42, 0xaf, 0x3e, 0x82, 0xec, - 0x6e, 0x9a, 0x8a, 0x24, 0x16, 0xbc, 0xcd, 0x7c, 0x7f, 0xe6, 0xfb, 0xf1, 0xcd, 0x0c, 0x32, 0xe8, - 0x88, 0xbb, 0x5c, 0x50, 0x0b, 0x87, 0xa1, 0xdb, 0xc3, 0x2c, 0xb0, 0x5c, 0xce, 0x05, 0x61, 0x01, - 0x96, 0x5c, 0x58, 0xc3, 0xba, 0x25, 0x47, 0x66, 0x28, 0xb8, 0xe4, 0x6a, 0x65, 0xa6, 0x34, 0x4f, - 0x95, 0xe6, 0x1f, 0x4a, 0x73, 0x58, 0x2f, 0x97, 0x5c, 0x0e, 0x3e, 0x07, 0xcb, 0x07, 0x2f, 0x32, - 0xfa, 0xe0, 0x25, 0xce, 0xf2, 0xe5, 0x84, 0x70, 0xe2, 0x9d, 0x95, 0x6c, 0x66, 0x54, 0xd1, 0xe3, - 0x1e, 0x4f, 0xf0, 0x68, 0x35, 0x43, 0xaf, 0x78, 0x9c, 0x7b, 0xfd, 0x68, 0x26, 0x66, 0xe1, 0x20, - 0xe0, 0x12, 0x4b, 0xc6, 0x83, 0x53, 0xcf, 0x8d, 0x05, 0x23, 0xfb, 0x3e, 0x0f, 0xa2, 0xd0, 0x64, - 0x95, 0x08, 0x6b, 0x9f, 0xd2, 0x48, 0xb7, 0xa9, 0xc7, 0x40, 0x52, 0xd1, 0x1e, 0x74, 0xc0, 0x15, - 0xac, 0x43, 0xc5, 0x7e, 0x64, 0xb1, 0xe9, 0x9b, 0x01, 0x05, 0xa9, 0xee, 0xa2, 0x8d, 0xae, 0xe0, - 0xbe, 0x83, 0x09, 0x11, 0x14, 0x40, 0x53, 0xaa, 0x8a, 0x91, 0x6b, 0x68, 0x5f, 0x3e, 0xdf, 0x2a, - 0xce, 0xe6, 0xdc, 0x4b, 0x98, 0xb6, 0x14, 0x2c, 0xf0, 0xec, 0x7c, 0xa4, 0x9e, 0x41, 0xea, 0x75, - 0x94, 0x8d, 0xf3, 0x1d, 0x46, 0xb4, 0x95, 0xd8, 0x98, 0x9f, 0x8c, 0x2b, 0x99, 0x38, 0xa0, 0xd5, - 0xb4, 0x33, 0x31, 0xd9, 0x22, 0xea, 0x16, 0x2a, 0xd0, 0x90, 0xbb, 0x3d, 0x87, 0x11, 0x1a, 0x48, - 0xd6, 0x65, 0x54, 0x68, 0xe9, 0x48, 0x6f, 0x5f, 0x8c, 0xf1, 0xd6, 0x1c, 0x56, 0xb7, 0x50, 0x0e, - 0x03, 0x50, 0xe9, 0x30, 0x02, 0xda, 0x6a, 0x35, 0x6d, 0xe4, 0x1a, 0x1b, 0x93, 0x71, 0x25, 0xbb, - 0x17, 0x81, 0xad, 0x26, 0xd8, 0xd9, 0x98, 0x6e, 0x11, 0x50, 0xef, 0xa0, 0x92, 0xcf, 0x02, 0x07, - 0x68, 0xbf, 0xeb, 0x10, 0xda, 0xa7, 0x5e, 0x5c, 0x92, 0x33, 0x00, 0xa2, 0xad, 0x55, 0x15, 0x63, - 0xd5, 0x2e, 0xfa, 0x2c, 0x68, 0xd3, 0x7e, 0xb7, 0x39, 0x27, 0x9f, 0x03, 0x51, 0xaf, 0xa1, 0x0b, - 0x3e, 0x1e, 0x39, 0x43, 0xdc, 0x67, 0x24, 0xba, 0x39, 0xd0, 0xd6, 0xab, 0x8a, 0xb1, 0x69, 0x6f, - 0xfa, 0x78, 0xf4, 0x62, 0x0e, 0xaa, 0x0e, 0xba, 0x04, 0xf3, 0xca, 0x9c, 0x10, 0x0b, 0xec, 0x83, - 0x96, 0xa9, 0x2a, 0x46, 0x7e, 0xe7, 0xa6, 0xb9, 0xe0, 0x25, 0xc4, 0xb5, 0x0f, 0xeb, 0xe6, 0x59, - 0xcf, 0xcf, 0x62, 0x4f, 0x63, 0xf5, 0x68, 0x5c, 0x49, 0xd9, 0x05, 0xf8, 0x0b, 0xbf, 0x5b, 0x38, - 0x38, 0x39, 0xdc, 0xce, 0x3f, 0x3e, 0xab, 0xb3, 0x76, 0x15, 0x55, 0x96, 0xde, 0x16, 0x84, 0x3c, - 0x00, 0xba, 0xf3, 0x4b, 0x41, 0xe9, 0x27, 0xe0, 0xa9, 0x3f, 0x14, 0x54, 0x5a, 0xa2, 0x55, 0x1f, - 0x98, 0xe7, 0x3c, 0x54, 0xf3, 0xdf, 0x6f, 0xa2, 0xfc, 0xf0, 0xff, 0x0f, 0x48, 0xc6, 0xac, 0xed, - 0x1f, 0x7c, 0xfd, 0xf9, 0x71, 0xe5, 0x5e, 0x6d, 0xd7, 0x3a, 0xff, 0x77, 0x59, 0x4b, 0x0e, 0x2b, - 0xaf, 0xbd, 0x3f, 0x39, 0xdc, 0x56, 0x1a, 0x2f, 0x8f, 0x26, 0xba, 0x72, 0x3c, 0xd1, 0x95, 0xef, - 0x13, 0x5d, 0xf9, 0x30, 0xd5, 0x53, 0xc7, 0x53, 0x3d, 0xf5, 0x6d, 0xaa, 0xa7, 0x5e, 0xdd, 0xf7, - 0x98, 0xec, 0x0d, 0x3a, 0x51, 0xf9, 0xd6, 0xa3, 0x24, 0xe7, 0x29, 0x95, 0x6f, 0xb9, 0x78, 0x3d, - 0x8f, 0x1d, 0x2d, 0x0e, 0x96, 0xef, 0x42, 0x0a, 0x9d, 0xf5, 0xf8, 0x97, 0xdc, 0xfe, 0x1d, 0x00, - 0x00, 0xff, 0xff, 0x7e, 0x3b, 0xf2, 0xe0, 0x03, 0x04, 0x00, 0x00, + // 575 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcd, 0x8a, 0x13, 0x4d, + 0x14, 0x4d, 0x4f, 0xe6, 0x27, 0xa9, 0xcc, 0x7c, 0x5f, 0x6c, 0x02, 0x69, 0x83, 0x74, 0x62, 0x40, + 0xed, 0x19, 0xb4, 0x9b, 0x8c, 0xb8, 0x71, 0xf0, 0x67, 0x32, 0x51, 0xc8, 0x42, 0x91, 0x0e, 0x8a, + 0xb8, 0x69, 0x2a, 0x5d, 0x95, 0x4e, 0x61, 0xba, 0xab, 0xad, 0x5b, 0x89, 0x71, 0x27, 0xf3, 0x04, + 0x82, 0xaf, 0xe1, 0x62, 0x16, 0x3e, 0xc4, 0x2c, 0x07, 0xdd, 0xb8, 0x0a, 0x9a, 0x08, 0xb3, 0xf5, + 0x11, 0xa4, 0x7f, 0xcc, 0x88, 0x24, 0x0e, 0xb8, 0xab, 0x3a, 0xe7, 0xdc, 0x7b, 0x6e, 0xdd, 0x7b, + 0x0b, 0x19, 0x74, 0xcc, 0x5d, 0x2e, 0xa8, 0x85, 0xc3, 0xd0, 0xed, 0x63, 0x16, 0x58, 0x2e, 0xe7, + 0x82, 0xb0, 0x00, 0x4b, 0x2e, 0xac, 0x51, 0xc3, 0x92, 0x63, 0x33, 0x14, 0x5c, 0x72, 0xb5, 0x9a, + 0x2a, 0xcd, 0x5f, 0x4a, 0xf3, 0x37, 0xa5, 0x39, 0x6a, 0x54, 0xca, 0x2e, 0x07, 0x9f, 0x83, 0xe5, + 0x83, 0x17, 0x05, 0xfa, 0xe0, 0x25, 0x91, 0x95, 0x8b, 0x09, 0xe1, 0xc4, 0x37, 0x2b, 0xb9, 0xa4, + 0xd4, 0xb5, 0x05, 0xf6, 0xbe, 0xcf, 0x83, 0x28, 0x41, 0x72, 0x4a, 0x85, 0x25, 0x8f, 0x7b, 0x3c, + 0x49, 0x10, 0x9d, 0x52, 0xf4, 0x92, 0xc7, 0xb9, 0x37, 0x88, 0xa2, 0x99, 0x85, 0x83, 0x80, 0x4b, + 0x2c, 0x19, 0x0f, 0xd2, 0xe4, 0xf5, 0x0f, 0x59, 0xa4, 0xdb, 0xd4, 0x63, 0x20, 0xa9, 0xe8, 0x0c, + 0xbb, 0xe0, 0x0a, 0xd6, 0xa5, 0xe2, 0x20, 0xb2, 0xb1, 0xe9, 0xab, 0x21, 0x05, 0xa9, 0xee, 0xa1, + 0xcd, 0x9e, 0xe0, 0xbe, 0x83, 0x09, 0x11, 0x14, 0x40, 0x53, 0x6a, 0x8a, 0x91, 0x6f, 0x6a, 0x9f, + 0x3e, 0xde, 0x28, 0xa5, 0x75, 0xee, 0x27, 0x4c, 0x47, 0x0a, 0x16, 0x78, 0x76, 0x21, 0x52, 0xa7, + 0x90, 0x7a, 0x15, 0xe5, 0xe2, 0x9a, 0x1d, 0x46, 0xb4, 0x95, 0x38, 0xb0, 0x30, 0x9d, 0x54, 0x37, + 0x62, 0x83, 0x76, 0xcb, 0xde, 0x88, 0xc9, 0x36, 0x51, 0xb7, 0x51, 0x91, 0x86, 0xdc, 0xed, 0x3b, + 0x8c, 0xd0, 0x40, 0xb2, 0x1e, 0xa3, 0x42, 0xcb, 0x46, 0x7a, 0xfb, 0xff, 0x18, 0x6f, 0xcf, 0x61, + 0x75, 0x1b, 0xe5, 0x31, 0x00, 0x95, 0x0e, 0x23, 0xa0, 0xad, 0xd6, 0xb2, 0x46, 0xbe, 0xb9, 0x39, + 0x9d, 0x54, 0x73, 0xfb, 0x11, 0xd8, 0x6e, 0x81, 0x9d, 0x8b, 0xe9, 0x36, 0x01, 0xf5, 0x16, 0x2a, + 0xfb, 0x2c, 0x70, 0x80, 0x0e, 0x7a, 0x0e, 0xa1, 0x03, 0xea, 0xc5, 0x6f, 0x77, 0x86, 0x40, 0xb4, + 0xb5, 0x9a, 0x62, 0xac, 0xda, 0x25, 0x9f, 0x05, 0x1d, 0x3a, 0xe8, 0xb5, 0xe6, 0xe4, 0x53, 0x20, + 0xea, 0x15, 0xf4, 0x9f, 0x8f, 0xc7, 0xce, 0x08, 0x0f, 0x18, 0x89, 0x26, 0x07, 0xda, 0x7a, 0x4d, + 0x31, 0xb6, 0xec, 0x2d, 0x1f, 0x8f, 0x9f, 0xcd, 0x41, 0xd5, 0x41, 0x17, 0x60, 0xde, 0x32, 0x27, + 0xc4, 0x02, 0xfb, 0xa0, 0x6d, 0xd4, 0x14, 0xa3, 0xb0, 0x7b, 0xdd, 0x5c, 0xb0, 0x09, 0xf1, 0xa8, + 0x46, 0x0d, 0xf3, 0xac, 0xcf, 0x4f, 0xe2, 0x98, 0xe6, 0xea, 0xf1, 0xa4, 0x9a, 0xb1, 0x8b, 0xf0, + 0x07, 0x7e, 0xbb, 0x78, 0x78, 0x7a, 0xb4, 0x53, 0x78, 0x78, 0xd6, 0xce, 0xfa, 0x65, 0x54, 0x5d, + 0x3a, 0x2d, 0x08, 0x79, 0x00, 0x74, 0xf7, 0x87, 0x82, 0xb2, 0x8f, 0xc0, 0x53, 0xbf, 0x29, 0xa8, + 0xbc, 0x44, 0xab, 0xde, 0x33, 0xcf, 0x59, 0x54, 0xf3, 0xef, 0x3b, 0x51, 0xb9, 0xff, 0xef, 0x09, + 0x92, 0x32, 0xeb, 0x07, 0x87, 0x9f, 0xbf, 0xbf, 0x5f, 0xb9, 0x53, 0xdf, 0xb3, 0xce, 0xff, 0x5d, + 0xd6, 0x92, 0x64, 0x95, 0xb5, 0xb7, 0xa7, 0x47, 0x3b, 0x4a, 0xf3, 0xf9, 0xf1, 0x54, 0x57, 0x4e, + 0xa6, 0xba, 0xf2, 0x75, 0xaa, 0x2b, 0xef, 0x66, 0x7a, 0xe6, 0x64, 0xa6, 0x67, 0xbe, 0xcc, 0xf4, + 0xcc, 0x8b, 0xbb, 0x1e, 0x93, 0xfd, 0x61, 0x37, 0x6a, 0xbe, 0xf5, 0x20, 0xf1, 0x79, 0x4c, 0xe5, + 0x6b, 0x2e, 0x5e, 0xce, 0x6d, 0xc7, 0x8b, 0x8d, 0xe5, 0x9b, 0x90, 0x42, 0x77, 0x3d, 0xfe, 0x25, + 0x37, 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x1f, 0x1f, 0x1a, 0x03, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -238,7 +242,8 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { - // RegisterSubscriberChain registers a subscriber chain with the coordinator. By default, it is activated at the next epoch. + // RegisterSubscriberChain registers a subscriber chain with the coordinator. + // By default, it is activated at the next epoch. RegisterSubscriberChain(ctx context.Context, in *RegisterSubscriberChainRequest, opts ...grpc.CallOption) (*RegisterSubscriberChainResponse, error) } @@ -261,7 +266,8 @@ func (c *msgClient) RegisterSubscriberChain(ctx context.Context, in *RegisterSub // MsgServer is the server API for Msg service. type MsgServer interface { - // RegisterSubscriberChain registers a subscriber chain with the coordinator. By default, it is activated at the next epoch. + // RegisterSubscriberChain registers a subscriber chain with the coordinator. + // By default, it is activated at the next epoch. RegisterSubscriberChain(context.Context, *RegisterSubscriberChainRequest) (*RegisterSubscriberChainResponse, error) } diff --git a/x/appchain/subscriber/types/query.pb.go b/x/appchain/subscriber/types/query.pb.go index 62cb6806b..b38388654 100644 --- a/x/appchain/subscriber/types/query.pb.go +++ b/x/appchain/subscriber/types/query.pb.go @@ -129,9 +129,9 @@ var fileDescriptor_351939062175e6f7 = []byte{ 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0xaa, 0xd5, 0x83, 0xa9, 0xd5, 0x43, 0xa8, 0xd5, 0x2b, 0x33, 0x94, 0x52, 0xc7, 0x30, 0x2b, 0x39, 0x3f, 0x37, 0x37, 0x3f, 0x0f, 0x64, 0x0e, - 0x84, 0x05, 0x31, 0x48, 0x4a, 0x26, 0x3d, 0x3f, 0x3f, 0x3d, 0x07, 0xa4, 0x2e, 0x53, 0x3f, 0x31, - 0x2f, 0x2f, 0xbf, 0x24, 0xb1, 0x24, 0x33, 0x3f, 0xaf, 0x18, 0x2a, 0x2b, 0x92, 0x9e, 0x9f, 0x9e, - 0x0f, 0x66, 0xea, 0x83, 0x58, 0x10, 0x51, 0x25, 0x11, 0x2e, 0xa1, 0x40, 0x90, 0x5b, 0x02, 0x12, + 0x84, 0x05, 0x31, 0x48, 0x4a, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xcc, 0xd4, 0x07, 0xb1, 0xa0, 0xa2, + 0x32, 0xe9, 0xf9, 0xf9, 0xe9, 0x39, 0x20, 0xdd, 0x99, 0xfa, 0x89, 0x79, 0x79, 0xf9, 0x25, 0x89, + 0x25, 0x99, 0xf9, 0x79, 0xc5, 0x10, 0x59, 0x25, 0x11, 0x2e, 0xa1, 0x40, 0x90, 0x5b, 0x02, 0x12, 0x8b, 0x12, 0x73, 0x8b, 0x83, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x94, 0x12, 0xb9, 0x84, 0x51, 0x44, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0xbc, 0xb8, 0xd8, 0x0a, 0xc0, 0x22, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x3a, 0x7a, 0x18, 0x4e, 0x87, 0x3a, 0xa8, 0xcc, 0x50, 0x2f, 0x18, @@ -143,7 +143,7 @@ var fileDescriptor_351939062175e6f7 = []byte{ 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0x02, 0x79, 0x59, 0xdf, 0x15, 0x62, 0xbb, 0x5f, 0x6a, 0x49, 0x79, 0x7e, 0x51, 0xb6, 0x3e, 0x2c, 0xc6, 0x2a, 0xb0, 0x9a, 0x5c, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x8e, 0x00, 0x63, 0x40, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x5e, 0x6d, 0x1a, 0xab, 0x2b, 0x02, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xd6, 0x6c, 0x26, 0x7e, 0x2b, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/epochs/types/epochs.pb.go b/x/epochs/types/epochs.pb.go index a65267937..ad34016c6 100644 --- a/x/epochs/types/epochs.pb.go +++ b/x/epochs/types/epochs.pb.go @@ -22,11 +22,15 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// Epoch represents a specific epoch with its number and associated identifier. It is not used within this module; rather, it is designed by other modules to replace a time.Duration object. Modules are free to choose whether such a structure represents the beginning or the end of an epoch. +// Epoch represents a specific epoch with its number and associated identifier. +// It is not used within this module; rather, it is designed by other modules +// to replace a time.Duration object. Modules are free to choose whether such +// a structure represents the beginning or the end of an epoch. type Epoch struct { // epoch_number is the sequential number of the epoch. EpochNumber uint64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"` - // epoch_identifier is a descriptive or unique identifier for the epoch (e.g., 'week', 'day', 'hour'). + // epoch_identifier is a descriptive or unique identifier for the epoch + // (e.g., 'week', 'day', 'hour'). EpochIdentifier string `protobuf:"bytes,2,opt,name=epoch_identifier,json=epochIdentifier,proto3" json:"epoch_identifier,omitempty"` } From cfba037cd6e9804fa72bd72283c5f7088601ac8b Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:23:20 +0000 Subject: [PATCH 19/52] fix(appchain): remove floating point arithmetic --- x/appchain/coordinator/keeper/register.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x/appchain/coordinator/keeper/register.go b/x/appchain/coordinator/keeper/register.go index 8a48f896b..1cab3bb7a 100644 --- a/x/appchain/coordinator/keeper/register.go +++ b/x/appchain/coordinator/keeper/register.go @@ -1,8 +1,6 @@ package keeper import ( - "math" - "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -34,7 +32,7 @@ func (k Keeper) AddSubscriberChain( } // this value is required by the AVS module when making edits or deleting the AVS. as always, we round it up for the // current epoch. it can never be 0, because both the durations are positive. - unbondingEpochs := math.Ceil(float64(req.SubscriberParams.UnbondingPeriod) / float64(epochInfo.Duration)) + unbondingEpochs := 1 + req.SubscriberParams.UnbondingPeriod/epochInfo.Duration if _, err := k.avsKeeper.RegisterAVSWithChainID(ctx, &avstypes.AVSRegisterOrDeregisterParams{ AvsName: req.ChainID, AssetID: req.AssetIDs, From 013f9381ff00c12c0753f645163f6edca74de7c6 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:23:35 +0000 Subject: [PATCH 20/52] fix(appchain): remove wrong comment --- proto/exocore/appchain/coordinator/v1/params.proto | 1 - 1 file changed, 1 deletion(-) diff --git a/proto/exocore/appchain/coordinator/v1/params.proto b/proto/exocore/appchain/coordinator/v1/params.proto index cd6773ab8..7172d8d29 100644 --- a/proto/exocore/appchain/coordinator/v1/params.proto +++ b/proto/exocore/appchain/coordinator/v1/params.proto @@ -31,5 +31,4 @@ message Params { // must respond to a VSC request, after it is sent. exocore.epochs.v1.Epoch vsc_timeout_period = 5 [ (gogoproto.nullable) = false, (gogoproto.customname) = "VSCTimeoutPeriod" ]; - // TODO: slashing and reward related parameters } From dc7915dedc0b6ad98084fab2f29925a8ff56dfc1 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:26:56 +0000 Subject: [PATCH 21/52] doc(appchain): add comment about params expect --- x/appchain/coordinator/keeper/params.go | 1 + x/appchain/subscriber/keeper/params.go | 1 + 2 files changed, 2 insertions(+) diff --git a/x/appchain/coordinator/keeper/params.go b/x/appchain/coordinator/keeper/params.go index 13c1c3e9c..1f959ad7b 100644 --- a/x/appchain/coordinator/keeper/params.go +++ b/x/appchain/coordinator/keeper/params.go @@ -6,6 +6,7 @@ import ( ) // SetParams sets the appchain coordinator parameters. +// The caller must ensure that the params are valid. func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(¶ms) diff --git a/x/appchain/subscriber/keeper/params.go b/x/appchain/subscriber/keeper/params.go index a94cb6cc3..9ccc5c5b7 100644 --- a/x/appchain/subscriber/keeper/params.go +++ b/x/appchain/subscriber/keeper/params.go @@ -7,6 +7,7 @@ import ( ) // SetParams sets the appchain coordinator parameters. +// The caller must ensure that the params are valid. func (k Keeper) SetParams(ctx sdk.Context, params commontypes.SubscriberParams) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(¶ms) From 607e12e3623bd0573c867c614aa079eaee35afec Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:27:54 +0000 Subject: [PATCH 22/52] fix(appchain): remove superfluous fmt --- x/appchain/coordinator/keeper/msg_server.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/appchain/coordinator/keeper/msg_server.go b/x/appchain/coordinator/keeper/msg_server.go index 1fa0c3501..1b34b5cd9 100644 --- a/x/appchain/coordinator/keeper/msg_server.go +++ b/x/appchain/coordinator/keeper/msg_server.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "fmt" errorsmod "cosmossdk.io/errors" @@ -29,7 +28,7 @@ func (m msgServer) RegisterSubscriberChain( ) (res *types.RegisterSubscriberChainResponse, err error) { ctx := sdk.UnwrapSDKContext(goCtx) if res, err = m.Keeper.AddSubscriberChain(ctx, req); err != nil { - return nil, errorsmod.Wrapf(err, fmt.Sprintf("RegisterSubscriberChain: key is %s", req.ChainID)) + return nil, errorsmod.Wrapf(err, "RegisterSubscriberChain: key is %s", req.ChainID) } return res, nil } From 4a275d35583c780272884e44b6fbc41adcc391a5 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:28:47 +0000 Subject: [PATCH 23/52] feat(appchain): report invalid json --- x/appchain/coordinator/client/cli/tx.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x/appchain/coordinator/client/cli/tx.go b/x/appchain/coordinator/client/cli/tx.go index 60df0eb27..3f6082bf8 100644 --- a/x/appchain/coordinator/client/cli/tx.go +++ b/x/appchain/coordinator/client/cli/tx.go @@ -1,6 +1,7 @@ package cli import ( + "encoding/json" "fmt" "github.com/spf13/cobra" @@ -42,6 +43,10 @@ func CmdRegisterSubscriberChain() *cobra.Command { return err } + if !json.Valid([]byte(args[0])) { + return fmt.Errorf("invalid JSON argument: %s", args[0]) + } + msg := types.NewRegisterSubscriberChainRequest(clientCtx.GetFromAddress().String(), args[0]) return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) From e9d8fc00cc2d585582242c04ed5080aa7062ad22 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:31:32 +0000 Subject: [PATCH 24/52] fix(utils): remove SliceStable and use Slice --- utils/utils.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/utils.go b/utils/utils.go index 3ddfcc289..6f026fb95 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -133,7 +133,8 @@ func SortByPower( } // Sort the indices slice based on the powers slice - sort.SliceStable(indices, func(i, j int) bool { + // Since the operator address is unique, SliceStable is not needed + sort.Slice(indices, func(i, j int) bool { if powers[indices[i]] == powers[indices[j]] { // ascending order of operator address as tiebreaker return bytes.Compare(operatorAddrs[indices[i]], operatorAddrs[indices[j]]) < 0 From 3be688218f8d624edcb08bb5d473e5bdf67be5f1 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:33:07 +0000 Subject: [PATCH 25/52] doc(appchain): add more logging --- x/appchain/coordinator/keeper/ibc_client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/appchain/coordinator/keeper/ibc_client.go b/x/appchain/coordinator/keeper/ibc_client.go index 9026bf9da..b4009e045 100644 --- a/x/appchain/coordinator/keeper/ibc_client.go +++ b/x/appchain/coordinator/keeper/ibc_client.go @@ -33,6 +33,7 @@ func (k Keeper) CreateClientForSubscriber( req types.RegisterSubscriberChainRequest, ) error { chainID := req.ChainID + k.Logger(ctx).Info("Creating client for subscriber chain", "chainID", chainID) subscriberParams := req.SubscriberParams // we always deploy a new client for the subscriber chain for our module // technically, the below can never happen but it is guarded in ICS-20 and therefore, here. @@ -129,6 +130,7 @@ func (k Keeper) MakeSubscriberGenesis( ) (*commontypes.SubscriberGenesisState, []byte, error) { params := k.GetParams(ctx) chainID := req.ChainID + k.Logger(ctx).Info("Creating genesis state for subscriber chain", "chainID", chainID) chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(chainID) coordinatorUnbondingPeriod := k.stakingKeeper.UnbondingTime(ctx) // client state From 4401e3fe1543623caae26f80d7f03ade96d00a4b Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 16:36:02 +0000 Subject: [PATCH 26/52] chore(lint) --- precompiles/testutil/logs.go | 1 - 1 file changed, 1 deletion(-) diff --git a/precompiles/testutil/logs.go b/precompiles/testutil/logs.go index 4be7a0031..d31de57cf 100644 --- a/precompiles/testutil/logs.go +++ b/precompiles/testutil/logs.go @@ -37,7 +37,6 @@ func CheckLogs(logArgs LogCheckArgs) error { int64(float64(logArgs.Res.GasUsed)/float64(logArgs.Res.GasWanted)*100), ) } - if err := CheckVMError(logArgs.Res, logArgs.ErrContains); err != nil { return err } From 47714fc8fd1a81d682de979a60f3be2cbb090af9 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 17:38:30 +0000 Subject: [PATCH 27/52] fix(ci): pin the golang lint version --- .github/workflows/lint.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index bea3bcb01..a13601988 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -37,8 +37,7 @@ jobs: # Now, the actual golangci-lint configuration - uses: golangci/golangci-lint-action@v4 with: - # Required parameter - version: latest + version: "v1.59.1" args: --timeout 10m github-token: ${{ secrets.github_token }} # Check only if there are differences in the source code From 2904a40c8c818b9387685f7797aff40274e65c5c Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 31 Aug 2024 17:40:19 +0000 Subject: [PATCH 28/52] chore(lint): remove unused timestamp proto --- proto/exocore/appchain/common/v1/common.proto | 1 - x/appchain/common/types/common.pb.go | 107 +++++++++--------- 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/proto/exocore/appchain/common/v1/common.proto b/proto/exocore/appchain/common/v1/common.proto index 1285640e8..138148319 100644 --- a/proto/exocore/appchain/common/v1/common.proto +++ b/proto/exocore/appchain/common/v1/common.proto @@ -5,7 +5,6 @@ package exocore.appchain.common.v1; import "amino/amino.proto"; import "gogoproto/gogo.proto"; import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; import "tendermint/abci/types.proto"; diff --git a/x/appchain/common/types/common.pb.go b/x/appchain/common/types/common.pb.go index 7236d149e..c2341e051 100644 --- a/x/appchain/common/types/common.pb.go +++ b/x/appchain/common/types/common.pb.go @@ -12,7 +12,6 @@ import ( github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" _ "google.golang.org/protobuf/types/known/durationpb" - _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" @@ -328,59 +327,59 @@ func init() { } var fileDescriptor_71cb7b22d050d7a3 = []byte{ - // 829 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x41, 0x6f, 0x1c, 0x35, - 0x14, 0xce, 0x34, 0x25, 0xb4, 0xde, 0x96, 0xdd, 0x58, 0x6d, 0x33, 0x5d, 0x60, 0x77, 0x13, 0x21, - 0x11, 0x51, 0x98, 0x51, 0x83, 0x84, 0x84, 0xb8, 0x40, 0x92, 0x16, 0x35, 0x42, 0x21, 0xda, 0x2d, - 0x45, 0x02, 0x09, 0xcb, 0xe3, 0xf1, 0xce, 0x3e, 0x3a, 0x63, 0x8f, 0x6c, 0x4f, 0x52, 0xfe, 0x02, - 0x27, 0x8e, 0xfc, 0x04, 0x8e, 0x5c, 0xf9, 0x07, 0x3d, 0xf6, 0xc8, 0xa9, 0xa0, 0xe4, 0xc0, 0x7f, - 0xe0, 0x84, 0xec, 0xf1, 0x64, 0x67, 0xb7, 0x0a, 0xe9, 0x65, 0x65, 0xfb, 0x7d, 0xef, 0x7b, 0xdf, - 0x7b, 0x6f, 0xdf, 0x1b, 0xf4, 0x3e, 0x7f, 0x26, 0x99, 0x54, 0x3c, 0xa6, 0x65, 0xc9, 0x66, 0x14, - 0x44, 0xcc, 0x64, 0x51, 0x48, 0x11, 0x1f, 0xdf, 0xf7, 0xa7, 0xa8, 0x54, 0xd2, 0x48, 0xdc, 0xf7, - 0xc0, 0xa8, 0x01, 0x46, 0xde, 0x7c, 0x7c, 0xbf, 0xbf, 0x4e, 0x0b, 0x10, 0x32, 0x76, 0xbf, 0x35, - 0xbc, 0x7f, 0x2b, 0x93, 0x99, 0x74, 0xc7, 0xd8, 0x9e, 0xfc, 0xeb, 0x20, 0x93, 0x32, 0xcb, 0x79, - 0xec, 0x6e, 0x49, 0x35, 0x8d, 0xd3, 0x4a, 0x51, 0x03, 0x4d, 0x90, 0xfe, 0x70, 0xd9, 0x6e, 0xa0, - 0xe0, 0xda, 0xd0, 0xa2, 0xf4, 0x80, 0x18, 0x12, 0x16, 0xe7, 0x90, 0xcd, 0x0c, 0xcb, 0x81, 0x0b, - 0xa3, 0x63, 0xc3, 0x45, 0xca, 0x55, 0x01, 0xc2, 0x58, 0xc9, 0xf3, 0x9b, 0x77, 0x78, 0xbb, 0x65, - 0xa7, 0x09, 0x83, 0xd8, 0xfc, 0x54, 0x72, 0x5d, 0x1b, 0xb7, 0xfe, 0x5d, 0x43, 0xbd, 0x49, 0x95, - 0x68, 0xa6, 0x20, 0xe1, 0xea, 0x88, 0x2a, 0x5a, 0x68, 0xfc, 0x39, 0x7a, 0x97, 0x49, 0xa9, 0x52, - 0x10, 0xd4, 0x48, 0x45, 0xa6, 0x9c, 0x93, 0x52, 0xca, 0x9c, 0xd0, 0x34, 0x55, 0x44, 0x1b, 0x15, - 0x06, 0xa3, 0x60, 0xfb, 0xfa, 0xf8, 0x6e, 0x0b, 0xf4, 0x90, 0xf3, 0x23, 0x29, 0xf3, 0x2f, 0xd2, - 0x54, 0x4d, 0x8c, 0xc2, 0x07, 0x68, 0x33, 0x05, 0x6d, 0x14, 0x24, 0x95, 0xcd, 0x8d, 0x18, 0x45, - 0x85, 0x2e, 0x40, 0x6b, 0x7b, 0x61, 0x33, 0x2a, 0x04, 0xcf, 0xc3, 0x2b, 0x8e, 0x65, 0xd8, 0x06, - 0x3e, 0x6e, 0xe1, 0xf6, 0x6a, 0x18, 0xfe, 0x1a, 0xbd, 0x97, 0xe4, 0x92, 0x3d, 0xd5, 0xa4, 0xe4, - 0x8a, 0x5c, 0x48, 0x1b, 0xae, 0x8e, 0x82, 0xed, 0xd5, 0xf1, 0x66, 0x8d, 0x3d, 0xe2, 0x6a, 0xff, - 0x02, 0x5e, 0xfc, 0x15, 0xda, 0xd2, 0xe7, 0x29, 0x13, 0xc5, 0x17, 0x28, 0xa7, 0x8a, 0x32, 0x7b, - 0x08, 0xaf, 0x3a, 0x75, 0xa3, 0x39, 0x72, 0xbc, 0x00, 0x7c, 0xe8, 0x71, 0x78, 0x13, 0xdd, 0x50, - 0xfc, 0x84, 0xaa, 0x94, 0xa4, 0x5c, 0xc8, 0x22, 0x7c, 0xc3, 0xf9, 0x75, 0xea, 0xb7, 0x7d, 0xfb, - 0x84, 0x39, 0xc2, 0x90, 0x30, 0x62, 0x3b, 0x29, 0x2b, 0x63, 0xd3, 0x00, 0x99, 0x86, 0x6b, 0xa3, - 0x60, 0xbb, 0xb3, 0x73, 0x37, 0xaa, 0x1b, 0x1e, 0x35, 0x0d, 0x8f, 0xf6, 0xfd, 0x1f, 0x62, 0xf7, - 0x9d, 0xe7, 0x2f, 0x87, 0x2b, 0xa7, 0x2f, 0x87, 0xbd, 0x47, 0xbb, 0x7b, 0x8f, 0x6b, 0xdf, 0x23, - 0xe7, 0xfa, 0xeb, 0x5f, 0xc3, 0x60, 0xdc, 0x83, 0x84, 0x2d, 0xbc, 0xe2, 0xef, 0xd1, 0x86, 0x2b, - 0xc8, 0x94, 0xab, 0xe5, 0x58, 0x6f, 0x5e, 0x16, 0xeb, 0x9a, 0x8d, 0xe5, 0x78, 0x6f, 0x37, 0x1c, - 0x8b, 0xe4, 0x87, 0xa8, 0x57, 0x89, 0x44, 0x8a, 0x14, 0x44, 0xd6, 0xb0, 0x5e, 0x7b, 0x7d, 0xd6, - 0xee, 0xb9, 0xb3, 0xe7, 0xfb, 0x08, 0xe1, 0x19, 0x68, 0x23, 0x15, 0x30, 0x9a, 0x13, 0x2e, 0x8c, - 0x02, 0xae, 0xc3, 0xeb, 0xae, 0x87, 0xeb, 0x73, 0xcb, 0x83, 0xda, 0x80, 0x3f, 0x41, 0x1b, 0x3a, - 0xa7, 0x7a, 0x76, 0xde, 0x1f, 0x92, 0xca, 0x13, 0x61, 0xb3, 0x0c, 0xbb, 0xae, 0xe0, 0xb7, 0x9d, - 0xb9, 0xe9, 0xca, 0xbe, 0x37, 0xe2, 0x1f, 0xd0, 0x9d, 0x06, 0x48, 0x7e, 0xa4, 0x90, 0x93, 0x66, - 0xdc, 0xc2, 0xde, 0x65, 0xe2, 0x6f, 0x36, 0xe2, 0x7f, 0xfb, 0xe7, 0xf7, 0x0f, 0x82, 0xf1, 0xad, - 0x86, 0xe7, 0x80, 0x42, 0xde, 0x80, 0xf0, 0x67, 0xa8, 0xff, 0x8a, 0xae, 0x2a, 0xc9, 0x39, 0xd1, - 0x90, 0x89, 0x70, 0xdd, 0x49, 0xdb, 0x58, 0x92, 0x66, 0xed, 0x13, 0xc8, 0xc4, 0xd6, 0x1f, 0x01, - 0xba, 0x33, 0x1f, 0xbe, 0x2f, 0xb9, 0xe0, 0x1a, 0xf4, 0xc4, 0x50, 0xc3, 0xf1, 0x01, 0x5a, 0x2b, - 0xdd, 0x30, 0xba, 0x59, 0xeb, 0xec, 0x7c, 0x18, 0x5d, 0xbc, 0x7c, 0xa2, 0xe5, 0x01, 0xde, 0xbd, - 0x6a, 0xa5, 0x8f, 0x3d, 0x03, 0x9e, 0xa0, 0x4e, 0x6b, 0x52, 0xdd, 0xd8, 0x75, 0x76, 0xee, 0xfd, - 0x1f, 0xe1, 0xde, 0x1c, 0xfe, 0x48, 0x4c, 0xa5, 0xe7, 0x6b, 0xb3, 0x6c, 0xfd, 0x7c, 0x05, 0x75, - 0x97, 0x60, 0xf8, 0x10, 0xdd, 0xa8, 0x77, 0x12, 0xd1, 0x36, 0x09, 0x2f, 0xfd, 0x5e, 0x04, 0x09, - 0x8b, 0xda, 0x1b, 0x2b, 0x6a, 0xed, 0x28, 0x1b, 0xcd, 0xbd, 0xba, 0xbc, 0xc7, 0x1d, 0x36, 0xbf, - 0xe0, 0x6f, 0x51, 0x97, 0x49, 0xa1, 0xb9, 0xd0, 0x95, 0xf6, 0x94, 0xb5, 0xf8, 0xe8, 0x52, 0xca, - 0xc6, 0xad, 0x66, 0x7d, 0x8b, 0x2d, 0xdc, 0xf1, 0x21, 0xea, 0x82, 0x00, 0x03, 0x34, 0x27, 0xc7, - 0x34, 0x27, 0x9a, 0x9b, 0x70, 0x75, 0xb4, 0xba, 0xdd, 0xd9, 0x19, 0xb5, 0x79, 0xec, 0xb2, 0x8c, - 0x9e, 0xd0, 0x1c, 0x52, 0x9b, 0xe1, 0x37, 0x65, 0x4a, 0x0d, 0xf7, 0xa5, 0xb8, 0xe9, 0xdd, 0x9f, - 0xd0, 0x7c, 0xc2, 0xcd, 0xee, 0xe4, 0xf9, 0xe9, 0x20, 0x78, 0x71, 0x3a, 0x08, 0xfe, 0x3e, 0x1d, - 0x04, 0xbf, 0x9c, 0x0d, 0x56, 0x5e, 0x9c, 0x0d, 0x56, 0xfe, 0x3c, 0x1b, 0xac, 0x7c, 0xf7, 0x69, - 0x06, 0x66, 0x56, 0x25, 0xb6, 0xb6, 0xf1, 0x83, 0xba, 0xe0, 0x87, 0xdc, 0x9c, 0x48, 0xf5, 0x34, - 0x6e, 0x3e, 0x3b, 0xcf, 0x5e, 0xf9, 0xf0, 0xb8, 0x05, 0x9d, 0xac, 0xb9, 0xbf, 0xe4, 0xc7, 0xff, - 0x05, 0x00, 0x00, 0xff, 0xff, 0x26, 0xae, 0x3d, 0xf1, 0xa0, 0x06, 0x00, 0x00, + // 819 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xc1, 0x6e, 0x1c, 0x45, + 0x10, 0xf5, 0xc4, 0xc1, 0x24, 0xbd, 0x09, 0xbb, 0x6e, 0x25, 0xf1, 0x64, 0x81, 0xf5, 0xda, 0x42, + 0xc2, 0x22, 0x30, 0xa3, 0x18, 0x09, 0x09, 0x71, 0x01, 0xdb, 0x09, 0x8a, 0x85, 0x8c, 0xb5, 0x1b, + 0x82, 0x04, 0x12, 0xad, 0x9e, 0x9e, 0xda, 0xd9, 0x22, 0xb3, 0xdd, 0xa3, 0xee, 0x1e, 0x3b, 0xfc, + 0x02, 0x27, 0x8e, 0x7c, 0x02, 0x47, 0xae, 0xfc, 0x41, 0x8e, 0x39, 0x72, 0x0a, 0xc8, 0x3e, 0xf0, + 0x0f, 0x9c, 0x50, 0xf7, 0xcc, 0x78, 0x67, 0x1d, 0x19, 0xe7, 0xb2, 0xea, 0xee, 0x7a, 0xf5, 0xea, + 0x55, 0xd5, 0x56, 0x0d, 0x79, 0x1f, 0x9e, 0x29, 0xa1, 0x34, 0xc4, 0xbc, 0x28, 0xc4, 0x94, 0xa3, + 0x8c, 0x85, 0x9a, 0xcd, 0x94, 0x8c, 0x8f, 0xee, 0xd7, 0xa7, 0xa8, 0xd0, 0xca, 0x2a, 0xda, 0xaf, + 0x81, 0x51, 0x03, 0x8c, 0x6a, 0xf3, 0xd1, 0xfd, 0xfe, 0x2a, 0x9f, 0xa1, 0x54, 0xb1, 0xff, 0xad, + 0xe0, 0xfd, 0x5b, 0x99, 0xca, 0x94, 0x3f, 0xc6, 0xee, 0x54, 0xbf, 0x0e, 0x32, 0xa5, 0xb2, 0x1c, + 0x62, 0x7f, 0x4b, 0xca, 0x49, 0x9c, 0x96, 0x9a, 0x5b, 0x6c, 0x82, 0xf4, 0x63, 0x4c, 0x44, 0x9c, + 0x63, 0x36, 0xb5, 0x22, 0x47, 0x90, 0xd6, 0xc4, 0x16, 0x64, 0x0a, 0x7a, 0x86, 0xd2, 0x3a, 0x45, + 0xf3, 0x5b, 0xed, 0xf0, 0x76, 0xcb, 0xce, 0x13, 0x81, 0xb1, 0xfd, 0xa9, 0x00, 0x53, 0x19, 0x37, + 0xff, 0x5d, 0x21, 0xbd, 0x71, 0x99, 0x18, 0xa1, 0x31, 0x01, 0x7d, 0xc8, 0x35, 0x9f, 0x19, 0xfa, + 0x39, 0x79, 0x57, 0x28, 0xa5, 0x53, 0x94, 0xdc, 0x2a, 0xcd, 0x26, 0x00, 0xac, 0x50, 0x2a, 0x67, + 0x3c, 0x4d, 0x35, 0x33, 0x56, 0x87, 0xc1, 0x30, 0xd8, 0xba, 0x3e, 0xba, 0xdb, 0x02, 0x3d, 0x04, + 0x38, 0x54, 0x2a, 0xff, 0x22, 0x4d, 0xf5, 0xd8, 0x6a, 0xba, 0x4f, 0x36, 0x52, 0x34, 0x56, 0x63, + 0x52, 0x3a, 0xe9, 0xcc, 0x6a, 0x2e, 0xcd, 0x0c, 0x8d, 0x71, 0x17, 0x31, 0xe5, 0x52, 0x42, 0x1e, + 0x5e, 0xf1, 0x2c, 0xeb, 0x6d, 0xe0, 0xe3, 0x16, 0x6e, 0xb7, 0x82, 0xd1, 0xaf, 0xc9, 0x7b, 0x49, + 0xae, 0xc4, 0x53, 0xc3, 0x0a, 0xd0, 0xec, 0x42, 0xda, 0x70, 0x79, 0x18, 0x6c, 0x2d, 0x8f, 0x36, + 0x2a, 0xec, 0x21, 0xe8, 0xbd, 0x0b, 0x78, 0xe9, 0x57, 0x64, 0xd3, 0x9c, 0xa5, 0xcc, 0x34, 0x2c, + 0x50, 0x4e, 0x34, 0x17, 0xee, 0x10, 0x5e, 0xf5, 0xea, 0x86, 0x73, 0xe4, 0x68, 0x01, 0xf8, 0xb0, + 0xc6, 0xd1, 0x0d, 0x72, 0x43, 0xc3, 0x31, 0xd7, 0x29, 0x4b, 0x41, 0xaa, 0x59, 0xf8, 0x86, 0xf7, + 0xeb, 0x54, 0x6f, 0x7b, 0xee, 0x89, 0x02, 0xa1, 0x98, 0x08, 0x66, 0x71, 0x06, 0xaa, 0xb4, 0x2e, + 0x0d, 0x54, 0x69, 0xb8, 0x32, 0x0c, 0xb6, 0x3a, 0xdb, 0x77, 0xa3, 0xaa, 0xdf, 0x51, 0xd3, 0xef, + 0x68, 0xaf, 0xee, 0xf7, 0xce, 0x3b, 0xcf, 0x5f, 0xae, 0x2f, 0x9d, 0xbc, 0x5c, 0xef, 0x3d, 0xda, + 0xd9, 0x7d, 0x5c, 0xf9, 0x1e, 0x7a, 0xd7, 0x5f, 0xff, 0x5a, 0x0f, 0x46, 0x3d, 0x4c, 0xc4, 0xc2, + 0x2b, 0xfd, 0x9e, 0xac, 0xf9, 0x82, 0x4c, 0x40, 0x9f, 0x8f, 0xf5, 0xe6, 0x65, 0xb1, 0xae, 0xb9, + 0x58, 0x9e, 0xf7, 0x76, 0xc3, 0xb1, 0x48, 0x7e, 0x40, 0x7a, 0xa5, 0x4c, 0x94, 0x4c, 0x51, 0x66, + 0x0d, 0xeb, 0xb5, 0xd7, 0x67, 0xed, 0x9e, 0x39, 0xd7, 0x7c, 0x1f, 0x11, 0x3a, 0x45, 0x63, 0x95, + 0x46, 0xc1, 0x73, 0x06, 0xd2, 0x6a, 0x04, 0x13, 0x5e, 0xf7, 0x3d, 0x5c, 0x9d, 0x5b, 0x1e, 0x54, + 0x06, 0xfa, 0x09, 0x59, 0x33, 0x39, 0x37, 0xd3, 0xb3, 0xfe, 0xb0, 0x54, 0x1d, 0x4b, 0x97, 0x65, + 0xd8, 0xf5, 0x05, 0xbf, 0xed, 0xcd, 0x4d, 0x57, 0xf6, 0x6a, 0x23, 0xfd, 0x81, 0xdc, 0x69, 0x80, + 0xec, 0x47, 0x8e, 0x39, 0x6b, 0xa6, 0x29, 0xec, 0x5d, 0x26, 0xfe, 0x66, 0x23, 0xfe, 0xb7, 0x7f, + 0x7e, 0xff, 0x20, 0x18, 0xdd, 0x6a, 0x78, 0xf6, 0x39, 0xe6, 0x0d, 0x88, 0x7e, 0x46, 0xfa, 0xaf, + 0xe8, 0x2a, 0x93, 0x1c, 0x98, 0xc1, 0x4c, 0x86, 0xab, 0x5e, 0xda, 0xda, 0x39, 0x69, 0xce, 0x3e, + 0xc6, 0x4c, 0x6e, 0xfe, 0x11, 0x90, 0x3b, 0xf3, 0xe1, 0xfb, 0x12, 0x24, 0x18, 0x34, 0x63, 0xcb, + 0x2d, 0xd0, 0x7d, 0xb2, 0x52, 0xf8, 0x61, 0xf4, 0xb3, 0xd6, 0xd9, 0xfe, 0x30, 0xba, 0x78, 0xb7, + 0x44, 0xe7, 0x07, 0x78, 0xe7, 0xaa, 0x93, 0x3e, 0xaa, 0x19, 0xe8, 0x98, 0x74, 0x5a, 0x93, 0xea, + 0xc7, 0xae, 0xb3, 0x7d, 0xef, 0xff, 0x08, 0x77, 0xe7, 0xf0, 0x47, 0x72, 0xa2, 0x6a, 0xbe, 0x36, + 0xcb, 0xe6, 0xcf, 0x57, 0x48, 0xf7, 0x1c, 0x8c, 0x1e, 0x90, 0x1b, 0xd5, 0x4e, 0x62, 0xc6, 0x25, + 0x51, 0x4b, 0xbf, 0x17, 0x61, 0x22, 0xa2, 0xf6, 0xc6, 0x8a, 0x5a, 0x3b, 0xca, 0x45, 0xf3, 0xaf, + 0x3e, 0xef, 0x51, 0x47, 0xcc, 0x2f, 0xf4, 0x5b, 0xd2, 0x15, 0x4a, 0x1a, 0x90, 0xa6, 0x34, 0x35, + 0x65, 0x25, 0x3e, 0xba, 0x94, 0xb2, 0x71, 0xab, 0x58, 0xdf, 0x12, 0x0b, 0x77, 0x7a, 0x40, 0xba, + 0x28, 0xd1, 0x22, 0xcf, 0xd9, 0x11, 0xcf, 0x99, 0x01, 0x1b, 0x2e, 0x0f, 0x97, 0xb7, 0x3a, 0xdb, + 0xc3, 0x36, 0x8f, 0x5b, 0x96, 0xd1, 0x13, 0x9e, 0x63, 0xea, 0x32, 0xfc, 0xa6, 0x48, 0xb9, 0x85, + 0xba, 0x14, 0x37, 0x6b, 0xf7, 0x27, 0x3c, 0x1f, 0x83, 0xdd, 0x19, 0x3f, 0x3f, 0x19, 0x04, 0x2f, + 0x4e, 0x06, 0xc1, 0xdf, 0x27, 0x83, 0xe0, 0x97, 0xd3, 0xc1, 0xd2, 0x8b, 0xd3, 0xc1, 0xd2, 0x9f, + 0xa7, 0x83, 0xa5, 0xef, 0x3e, 0xcd, 0xd0, 0x4e, 0xcb, 0xc4, 0xd5, 0x36, 0x7e, 0x50, 0x15, 0xfc, + 0x00, 0xec, 0xb1, 0xd2, 0x4f, 0xe3, 0xe6, 0xab, 0xf2, 0xec, 0x95, 0xef, 0x8a, 0x5f, 0xd0, 0xc9, + 0x8a, 0xff, 0x4b, 0x7e, 0xfc, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7, 0xc6, 0x07, 0xf5, 0x7f, + 0x06, 0x00, 0x00, } func (m *SubscriberParams) Marshal() (dAtA []byte, err error) { From 8d0db6ca3447ca6bf6111db93b4443b22e9cae3e Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 1 Sep 2024 12:31:30 +0000 Subject: [PATCH 29/52] refactor(dogfood,operator): carve out wrapped key The wrapped consensus key object has utility in the subscriber module as well, and, may have some utility in the coordinator module. Hence, it is better located in a `types` subpackage. --- testutil/tx/signer.go | 6 +-- .../consensus_key.go | 23 ++++++------ .../consensus_key_test.go | 2 +- utils/utils.go | 11 +++--- x/dogfood/keeper/abci.go | 36 +++++++++--------- x/dogfood/keeper/genesis.go | 14 +++---- x/dogfood/keeper/impl_delegation_hooks.go | 4 +- x/dogfood/keeper/impl_epochs_hooks_test.go | 37 ++++++++++--------- x/dogfood/keeper/impl_operator_hooks.go | 9 +++-- x/dogfood/keeper/opt_out_test.go | 3 +- x/dogfood/keeper/validators.go | 37 ++++++------------- x/dogfood/types/expected_keepers.go | 9 +++-- x/dogfood/types/genesis.go | 4 +- x/operator/keeper/consensus_keys.go | 34 +++++++++-------- x/operator/keeper/grpc_query.go | 3 +- x/operator/keeper/msg_server.go | 5 ++- x/operator/keeper/opt.go | 7 +++- x/operator/types/expected_keepers.go | 9 +++-- x/operator/types/hooks.go | 9 +++-- x/operator/types/msg.go | 5 ++- 20 files changed, 134 insertions(+), 133 deletions(-) rename x/operator/types/consensus_keys.go => types/consensus_key.go (95%) rename x/operator/types/consensus_keys_test.go => types/consensus_key_test.go (98%) diff --git a/testutil/tx/signer.go b/testutil/tx/signer.go index 14eadd10c..fcb545019 100644 --- a/testutil/tx/signer.go +++ b/testutil/tx/signer.go @@ -3,7 +3,7 @@ package tx import ( "fmt" - operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" + "github.com/ExocoreNetwork/exocore/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -43,13 +43,13 @@ func GenerateAddress() common.Address { } // GenerateConsensusKey generates a consensus key. -func GenerateConsensusKey() operatortypes.WrappedConsKey { +func GenerateConsensusKey() types.WrappedConsKey { privVal := mock.NewPV() pubKey, err := privVal.GetPubKey() if err != nil { return nil } - return operatortypes.NewWrappedConsKeyFromHex(hexutil.Encode(pubKey.Bytes())) + return types.NewWrappedConsKeyFromHex(hexutil.Encode(pubKey.Bytes())) } var _ keyring.Signer = &Signer{} diff --git a/x/operator/types/consensus_keys.go b/types/consensus_key.go similarity index 95% rename from x/operator/types/consensus_keys.go rename to types/consensus_key.go index 7e5c58ffd..bd731ed9e 100644 --- a/x/operator/types/consensus_keys.go +++ b/types/consensus_key.go @@ -3,6 +3,7 @@ package types import ( "encoding/base64" "encoding/json" + fmt "fmt" errorsmod "cosmossdk.io/errors" @@ -38,6 +39,14 @@ type WrappedConsKey interface { EqualsWrapped(WrappedConsKey) bool } +// KeyWithPower is a key with its associated power. This helper structure +// is used for passing within the keeper functions and is not stored since +// serialization for this structure is not implemented. +type WrappedConsKeyWithPower struct { + Key WrappedConsKey + Power int64 +} + // interface guard var ( _ WrappedConsKey = &wrappedConsKeyImpl{} @@ -228,7 +237,7 @@ func tmKeyFromJSON(key string) (res *tmprotocrypto.PublicKey, err error) { if keyType, keyString, err := base64KeyFromJSON(key); err != nil { return nil, errorsmod.Wrap(err, "invalid public key") } else if keyType != supportedKeyType { - return nil, errorsmod.Wrap(ErrParameterInvalid, "invalid public key type") + return nil, fmt.Errorf("unsupported key type: %s", keyType) } else if res, err = tmKeyFromBase64Key(keyString); err != nil { return nil, errorsmod.Wrap(err, "invalid public key") } @@ -267,19 +276,11 @@ func tmKeyFromBase64Key(pubKey string) (*tmprotocrypto.PublicKey, error) { // `exocored keys consensus-pubkey-to-bytes` func tmKeyFromHex(key string) (*tmprotocrypto.PublicKey, error) { if len(key) != 66 { - return nil, errorsmod.Wrapf( - ErrInvalidPubKey, - "expected 66 length string, got %d", - len(key), - ) + return nil, fmt.Errorf("expected 66 length string, got %d", len(key)) } keyBytes, err := hexutil.Decode(key) if err != nil { - return nil, errorsmod.Wrapf( - ErrInvalidPubKey, - "failed to decode hex string: %s", - err, - ) + return nil, fmt.Errorf("failed to decode hex string: %s", err) } return &tmprotocrypto.PublicKey{ Sum: &tmprotocrypto.PublicKey_Ed25519{ diff --git a/x/operator/types/consensus_keys_test.go b/types/consensus_key_test.go similarity index 98% rename from x/operator/types/consensus_keys_test.go rename to types/consensus_key_test.go index 1350a6f4b..1eb0ad8d1 100644 --- a/x/operator/types/consensus_keys_test.go +++ b/types/consensus_key_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/ExocoreNetwork/exocore/x/operator/types" + "github.com/ExocoreNetwork/exocore/types" "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cometbft/cometbft/crypto/secp256k1" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" diff --git a/utils/utils.go b/utils/utils.go index 6f026fb95..9def1b3bc 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,13 +5,12 @@ import ( "sort" "strings" - "github.com/evmos/evmos/v14/crypto/ethsecp256k1" - - operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" + "github.com/ExocoreNetwork/exocore/types" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/evmos/evmos/v14/crypto/ethsecp256k1" ) const ( @@ -123,9 +122,9 @@ func IsSupportedKey(pubkey cryptotypes.PubKey) bool { // the bytes. func SortByPower( operatorAddrs []sdk.AccAddress, - pubKeys []operatortypes.WrappedConsKey, + pubKeys []types.WrappedConsKey, powers []int64, -) ([]sdk.AccAddress, []operatortypes.WrappedConsKey, []int64) { +) ([]sdk.AccAddress, []types.WrappedConsKey, []int64) { // Create a slice of indices indices := make([]int, len(powers)) for i := range indices { @@ -145,7 +144,7 @@ func SortByPower( // Reorder all slices using the sorted indices sortedOperatorAddrs := make([]sdk.AccAddress, len(operatorAddrs)) - sortedPubKeys := make([]operatortypes.WrappedConsKey, len(pubKeys)) + sortedPubKeys := make([]types.WrappedConsKey, len(pubKeys)) sortedPowers := make([]int64, len(powers)) for i, idx := range indices { sortedOperatorAddrs[i] = operatorAddrs[idx] diff --git a/x/dogfood/keeper/abci.go b/x/dogfood/keeper/abci.go index b9f1085da..e81b0dbf0 100644 --- a/x/dogfood/keeper/abci.go +++ b/x/dogfood/keeper/abci.go @@ -2,10 +2,10 @@ package keeper import ( "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" "github.com/ExocoreNetwork/exocore/utils" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" abci "github.com/cometbft/cometbft/abci/types" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -38,7 +38,9 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { // then, let the operator module know that the opt out has finished. optOuts := k.GetPendingOptOuts(ctx) for _, addr := range optOuts.GetList() { - err := k.operatorKeeper.CompleteOperatorKeyRemovalForChainID(ctx, addr, chainIDWithoutRevision) + err := k.operatorKeeper.CompleteOperatorKeyRemovalForChainID( + ctx, addr, chainIDWithoutRevision, + ) if err != nil { k.Logger(ctx).Error("error decrementing undelegation hold count", "error", err) } @@ -91,7 +93,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { // the capacity of this list is twice the maximum number of validators. // this is because we can have a maximum of maxVals validators, and we can also have // a maximum of maxVals validators that are removed. - res := make([]abci.ValidatorUpdate, 0, maxVals*2) + res := make([]exocoretypes.WrappedConsKeyWithPower, 0, maxVals*2) for i := range operators { // #nosec G701 // ok on 64-bit systems. if i >= int(maxVals) { @@ -110,15 +112,14 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { } // find the previous power. wrappedKey := keys[i] - address := wrappedKey.ToConsAddr() - addressString := address.String() + addressString := wrappedKey.ToConsAddr().String() prevPower, found := prevMap[addressString] if found { - // if the power has changed, queue an update. + // if the power has changed, queue an update. skip, otherwise. if prevPower != power { - res = append(res, abci.ValidatorUpdate{ - PubKey: *wrappedKey.ToTmProtoKey(), - Power: power, + res = append(res, exocoretypes.WrappedConsKeyWithPower{ + Key: wrappedKey, + Power: power, }) } // remove the validator from the previous map, so that 0 power @@ -126,11 +127,12 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { delete(prevMap, addressString) } else { // new consensus key, queue an update. - res = append(res, abci.ValidatorUpdate{ - PubKey: *wrappedKey.ToTmProtoKey(), - Power: power, + res = append(res, exocoretypes.WrappedConsKeyWithPower{ + Key: wrappedKey, + Power: power, }) } + // all powers, regardless of whether the key exists, are added to the total power. totalPower = totalPower.Add(sdk.NewInt(power)) } k.Logger(ctx).Info("total power", "totalPower", totalPower, "len(res)", len(res)) @@ -142,13 +144,9 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { addressString := sdk.GetConsAddress(pubKey).String() // Check if this validator is still in prevMap (i.e., hasn't been deleted) if _, exists := prevMap[addressString]; exists { // O(1) since hash map - tmprotoKey, err := cryptocodec.ToTmProtoPublicKey(pubKey) - if err != nil { - continue - } - res = append(res, abci.ValidatorUpdate{ - PubKey: tmprotoKey, - Power: 0, + res = append(res, exocoretypes.WrappedConsKeyWithPower{ + Key: exocoretypes.NewWrappedConsKeyFromSdkKey(pubKey), + Power: 0, }) // while calculating total power, we started with 0 and not previous power. // so the previous power of these validators does not need to be subtracted. diff --git a/x/dogfood/keeper/genesis.go b/x/dogfood/keeper/genesis.go index 6873f4bf8..6f523c8ad 100644 --- a/x/dogfood/keeper/genesis.go +++ b/x/dogfood/keeper/genesis.go @@ -3,9 +3,9 @@ package keeper import ( "fmt" + exocoretypes "github.com/ExocoreNetwork/exocore/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/dogfood/types" - operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" abci "github.com/cometbft/cometbft/abci/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -48,10 +48,10 @@ func (k Keeper) InitGenesis( avsAddrString := avsAddr.String() ctx.Logger().With(types.ModuleName).Info(fmt.Sprintf("created dogfood avs %s %s", avsAddrString, ctx.ChainID())) // create the validators - out := make([]abci.ValidatorUpdate, 0, len(genState.ValSet)) + out := make([]exocoretypes.WrappedConsKeyWithPower, 0, len(genState.ValSet)) for _, val := range genState.ValSet { - // wrappedKey can never be nil - wrappedKey := operatortypes.NewWrappedConsKeyFromHex(val.PublicKey) + // we have already checked in gs.Validate() that wrappedKey is not nil + wrappedKey := exocoretypes.NewWrappedConsKeyFromHex(val.PublicKey) // #nosec G703 // already validated operatorAddr, _ := sdk.AccAddressFromBech32(val.OperatorAccAddr) // OptIntoAVS checks that the operator exists and will error if it does not. @@ -60,9 +60,9 @@ func (k Keeper) InitGenesis( ); err != nil { panic(fmt.Errorf("failed to opt into avs: %s", err)) } - out = append(out, abci.ValidatorUpdate{ - PubKey: *wrappedKey.ToTmProtoKey(), - Power: val.Power, + out = append(out, exocoretypes.WrappedConsKeyWithPower{ + Power: val.Power, + Key: wrappedKey, }) } for i := range genState.OptOutExpiries { diff --git a/x/dogfood/keeper/impl_delegation_hooks.go b/x/dogfood/keeper/impl_delegation_hooks.go index 7924131a5..3bbf6574d 100644 --- a/x/dogfood/keeper/impl_delegation_hooks.go +++ b/x/dogfood/keeper/impl_delegation_hooks.go @@ -3,9 +3,9 @@ package keeper import ( "fmt" + exocoretypes "github.com/ExocoreNetwork/exocore/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" - operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -49,7 +49,7 @@ func (wrapper DelegationHooksWrapper) AfterUndelegationStarted( // because the operator is not in the validator set. } else { var found bool - var wrappedKey operatortypes.WrappedConsKey + var wrappedKey exocoretypes.WrappedConsKey if found, wrappedKey, _ = wrapper.keeper.operatorKeeper.GetOperatorConsKeyForChainID( ctx, operator, chainIDWithoutRevision, ); !found { diff --git a/x/dogfood/keeper/impl_epochs_hooks_test.go b/x/dogfood/keeper/impl_epochs_hooks_test.go index f157545f0..e2d67cf90 100644 --- a/x/dogfood/keeper/impl_epochs_hooks_test.go +++ b/x/dogfood/keeper/impl_epochs_hooks_test.go @@ -3,6 +3,7 @@ package keeper_test import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" + exocoretypes "github.com/ExocoreNetwork/exocore/types" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" @@ -114,7 +115,7 @@ func (suite *KeeperTestSuite) TestSameEpochOperations() { errValues []error expUpdatesCount int powers []int64 - validatorKey operatortypes.WrappedConsKey + validatorKey exocoretypes.WrappedConsKey }{ { name: "opt in - base case", @@ -294,9 +295,9 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { errValues []error expUpdatesCount []int powers [][]int64 - validatorKeys []operatortypes.WrappedConsKey - ultimateKey operatortypes.WrappedConsKey - absentKeys []operatortypes.WrappedConsKey + validatorKeys []exocoretypes.WrappedConsKey + ultimateKey exocoretypes.WrappedConsKey + absentKeys []exocoretypes.WrappedConsKey }{ { name: "opt in - base case", @@ -308,9 +309,9 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { powers: [][]int64{ []int64{amountUSD}, }, - validatorKeys: []operatortypes.WrappedConsKey{oldKey}, + validatorKeys: []exocoretypes.WrappedConsKey{oldKey}, ultimateKey: oldKey, - absentKeys: []operatortypes.WrappedConsKey{newKey}, + absentKeys: []exocoretypes.WrappedConsKey{newKey}, }, { name: "opt out without opting in", @@ -322,9 +323,9 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { powers: [][]int64{ []int64{}, }, - validatorKeys: []operatortypes.WrappedConsKey{nil}, + validatorKeys: []exocoretypes.WrappedConsKey{nil}, ultimateKey: nil, - absentKeys: []operatortypes.WrappedConsKey{oldKey, newKey}, + absentKeys: []exocoretypes.WrappedConsKey{oldKey, newKey}, }, { name: "set key without opting in", @@ -336,9 +337,9 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { powers: [][]int64{ []int64{}, }, - validatorKeys: []operatortypes.WrappedConsKey{nil}, + validatorKeys: []exocoretypes.WrappedConsKey{nil}, ultimateKey: nil, - absentKeys: []operatortypes.WrappedConsKey{oldKey, newKey}, + absentKeys: []exocoretypes.WrappedConsKey{oldKey, newKey}, }, { name: "opt in then replace", @@ -351,11 +352,11 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { []int64{amountUSD}, []int64{amountUSD, 0}, }, - validatorKeys: []operatortypes.WrappedConsKey{ + validatorKeys: []exocoretypes.WrappedConsKey{ oldKey, newKey, }, ultimateKey: newKey, - absentKeys: []operatortypes.WrappedConsKey{oldKey}, + absentKeys: []exocoretypes.WrappedConsKey{oldKey}, }, { name: "opt in then opt out", @@ -368,9 +369,9 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { []int64{amountUSD}, []int64{0}, }, - validatorKeys: []operatortypes.WrappedConsKey{oldKey, nil}, + validatorKeys: []exocoretypes.WrappedConsKey{oldKey, nil}, ultimateKey: nil, - absentKeys: []operatortypes.WrappedConsKey{oldKey, newKey}, + absentKeys: []exocoretypes.WrappedConsKey{oldKey, newKey}, }, { name: "opt in then replace then opt out", @@ -384,9 +385,9 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { []int64{amountUSD, 0}, []int64{0}, }, - validatorKeys: []operatortypes.WrappedConsKey{oldKey, newKey, nil}, + validatorKeys: []exocoretypes.WrappedConsKey{oldKey, newKey, nil}, ultimateKey: nil, - absentKeys: []operatortypes.WrappedConsKey{oldKey, newKey}, + absentKeys: []exocoretypes.WrappedConsKey{oldKey, newKey}, }, { name: "opt in then opt out then opt in", @@ -400,9 +401,9 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { []int64{0}, []int64{}, }, - validatorKeys: []operatortypes.WrappedConsKey{oldKey, nil, nil}, + validatorKeys: []exocoretypes.WrappedConsKey{oldKey, nil, nil}, ultimateKey: nil, - absentKeys: []operatortypes.WrappedConsKey{oldKey, newKey}, + absentKeys: []exocoretypes.WrappedConsKey{oldKey, newKey}, }, } for _, tc := range testcases { diff --git a/x/dogfood/keeper/impl_operator_hooks.go b/x/dogfood/keeper/impl_operator_hooks.go index 8c3f8c23a..25c095d2a 100644 --- a/x/dogfood/keeper/impl_operator_hooks.go +++ b/x/dogfood/keeper/impl_operator_hooks.go @@ -1,6 +1,7 @@ package keeper import ( + exocoretypes "github.com/ExocoreNetwork/exocore/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -22,7 +23,7 @@ func (k *Keeper) OperatorHooks() OperatorHooksWrapper { // AfterOperatorKeySet is the implementation of the operator hooks. // CONTRACT: an operator cannot set their key if they are already in the process of removing it. func (h OperatorHooksWrapper) AfterOperatorKeySet( - sdk.Context, sdk.AccAddress, string, operatortypes.WrappedConsKey, + sdk.Context, sdk.AccAddress, string, exocoretypes.WrappedConsKey, ) { // an operator opting in does not meaningfully affect this module, since // this information will be fetched at the end of the epoch @@ -35,8 +36,8 @@ func (h OperatorHooksWrapper) AfterOperatorKeySet( // CONTRACT: key replacement from newKey to oldKey is not allowed, after a replacement from // oldKey to newKey. func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( - ctx sdk.Context, _ sdk.AccAddress, oldKey operatortypes.WrappedConsKey, - _ operatortypes.WrappedConsKey, chainID string, + ctx sdk.Context, _ sdk.AccAddress, oldKey exocoretypes.WrappedConsKey, + _ exocoretypes.WrappedConsKey, chainID string, ) { // the impact of key replacement is: // 1. vote power of old key is 0, which happens automatically at epoch end in EndBlock. this @@ -71,7 +72,7 @@ func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( // AfterOperatorKeyRemovalInitiated is the implementation of the operator hooks. func (h OperatorHooksWrapper) AfterOperatorKeyRemovalInitiated( - ctx sdk.Context, operator sdk.AccAddress, chainID string, key operatortypes.WrappedConsKey, + ctx sdk.Context, operator sdk.AccAddress, chainID string, key exocoretypes.WrappedConsKey, ) { // the impact of key removal is: // 1. vote power of the operator is 0, which happens automatically at epoch end in EndBlock. diff --git a/x/dogfood/keeper/opt_out_test.go b/x/dogfood/keeper/opt_out_test.go index 93fa4edb5..b18e495df 100644 --- a/x/dogfood/keeper/opt_out_test.go +++ b/x/dogfood/keeper/opt_out_test.go @@ -4,6 +4,7 @@ import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" + exocoretypes "github.com/ExocoreNetwork/exocore/types" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" @@ -338,7 +339,7 @@ func (suite *KeeperTestSuite) CheckLengthOfValidatorUpdates( } func (suite *KeeperTestSuite) CheckValidatorFound( - key operatortypes.WrappedConsKey, expected bool, + key exocoretypes.WrappedConsKey, expected bool, chainIDWithoutRevision string, operatorAddress sdk.AccAddress, ) { diff --git a/x/dogfood/keeper/validators.go b/x/dogfood/keeper/validators.go index c2d69d0a7..0cf938643 100644 --- a/x/dogfood/keeper/validators.go +++ b/x/dogfood/keeper/validators.go @@ -1,7 +1,3 @@ -// This file is a duplicate of the subscriber module's validators file with minor changes. -// The function ApplyValidatorChanges can likely be carved out into a shared package with -// the appchain module when it is ready. - package keeper import ( @@ -9,6 +5,7 @@ import ( "time" "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/dogfood/types" abci "github.com/cometbft/cometbft/abci/types" @@ -41,25 +38,12 @@ func (k Keeper) UnbondingTime(ctx sdk.Context) time.Duration { // on the keeper to be executed. Lastly, it stores the validator set against the // provided validator set id. func (k Keeper) ApplyValidatorChanges( - ctx sdk.Context, changes []abci.ValidatorUpdate, + ctx sdk.Context, changes []exocoretypes.WrappedConsKeyWithPower, ) []abci.ValidatorUpdate { ret := []abci.ValidatorUpdate{} logger := k.Logger(ctx) for _, change := range changes { - // convert TM pubkey to SDK pubkey for storage within the validator object. - pubkey, err := cryptocodec.FromTmProtoPublicKey(change.GetPubKey()) - if err != nil { - // An error here would indicate that this change is invalid. - // The change is received either from the genesis file, or from - // other parts of the module. - // In no situation it should happen; however, if it does, - // we do not panic. Simply skip the change. - logger.Error("could not convert tendermint pubkey to sdk pubkey", "error", err) - continue - } - // the address is just derived from the public key and - // has no correlation with the operator address on Exocore. - addr := sdk.GetConsAddress(pubkey) + addr := change.Key.ToConsAddr() val, found := k.GetExocoreValidator(ctx, addr) switch found { case true: @@ -71,8 +55,7 @@ func (k Keeper) ApplyValidatorChanges( k.DeleteExocoreValidator(cc, addr) // sdk slashing.AfterValidatorRemoved deletes the lookup from cons address to // cons pub key - err = k.Hooks().AfterValidatorRemoved(cc, addr, nil) - if err != nil { + if err := k.Hooks().AfterValidatorRemoved(cc, addr, nil); err != nil { logger.Error("error in AfterValidatorRemoved", "error", err) continue } @@ -94,8 +77,9 @@ func (k Keeper) ApplyValidatorChanges( logger.Error("operator address not found for validator", "cons address", addr) continue } - err = k.Hooks().AfterValidatorCreated(cc, sdk.ValAddress(accAddress)) - if err != nil { + if err := k.Hooks().AfterValidatorCreated( + cc, sdk.ValAddress(accAddress), + ); err != nil { logger.Error("error in AfterValidatorCreated", "error", err) continue } @@ -104,7 +88,7 @@ func (k Keeper) ApplyValidatorChanges( case false: if change.Power > 0 { // create a new validator. - ocVal, err := types.NewExocoreValidator(addr, change.Power, pubkey) + ocVal, err := types.NewExocoreValidator(addr, change.Power, change.Key.ToSdkKey()) if err != nil { logger.Error("could not create new exocore validator", "error", err) continue @@ -127,7 +111,10 @@ func (k Keeper) ApplyValidatorChanges( continue } } - ret = append(ret, change) + ret = append(ret, abci.ValidatorUpdate{ + PubKey: *change.Key.ToTmProtoKey(), + Power: change.Power, + }) } // sort for determinism diff --git a/x/dogfood/types/expected_keepers.go b/x/dogfood/types/expected_keepers.go index d5b0a1511..3ae4b1b78 100644 --- a/x/dogfood/types/expected_keepers.go +++ b/x/dogfood/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" epochsTypes "github.com/ExocoreNetwork/exocore/x/epochs/types" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -54,7 +55,7 @@ type OperatorKeeper interface { // at each epoch, get the list and create validator update GetActiveOperatorsForChainID( sdk.Context, string, - ) ([]sdk.AccAddress, []operatortypes.WrappedConsKey) + ) ([]sdk.AccAddress, []exocoretypes.WrappedConsKey) // get vote power GetVotePowerForChainID( sdk.Context, []sdk.AccAddress, string, @@ -68,13 +69,13 @@ type OperatorKeeper interface { ClearPreviousConsensusKeys(ctx sdk.Context, chainID string) GetOperatorConsKeyForChainID( sdk.Context, sdk.AccAddress, string, - ) (bool, operatortypes.WrappedConsKey, error) + ) (bool, exocoretypes.WrappedConsKey, error) GetOperatorPrevConsKeyForChainID( sdk.Context, sdk.AccAddress, string, - ) (bool, operatortypes.WrappedConsKey, error) + ) (bool, exocoretypes.WrappedConsKey, error) // OptInWithConsKey is used at genesis to opt in with a consensus key OptInWithConsKey( - sdk.Context, sdk.AccAddress, string, operatortypes.WrappedConsKey, + sdk.Context, sdk.AccAddress, string, exocoretypes.WrappedConsKey, ) error // GetOrCalculateOperatorUSDValues is used to get the self staking value for the operator GetOrCalculateOperatorUSDValues(sdk.Context, sdk.AccAddress, string) (operatortypes.OperatorOptedUSDValue, error) diff --git a/x/dogfood/types/genesis.go b/x/dogfood/types/genesis.go index e857b501e..fe78c285a 100644 --- a/x/dogfood/types/genesis.go +++ b/x/dogfood/types/genesis.go @@ -3,8 +3,8 @@ package types import ( errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" - operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common/hexutil" ) @@ -75,7 +75,7 @@ func (gs GenesisState) Validate() error { ) } // check for validity of the public key - if wrappedKey := operatortypes.NewWrappedConsKeyFromHex( + if wrappedKey := exocoretypes.NewWrappedConsKeyFromHex( val.PublicKey, ); wrappedKey == nil { return errorsmod.Wrapf( diff --git a/x/operator/keeper/consensus_keys.go b/x/operator/keeper/consensus_keys.go index fd24600af..b91a9394c 100644 --- a/x/operator/keeper/consensus_keys.go +++ b/x/operator/keeper/consensus_keys.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -32,7 +33,7 @@ func (k *Keeper) SetOperatorConsKeyForChainID( ctx sdk.Context, opAccAddr sdk.AccAddress, chainID string, - wrappedKey types.WrappedConsKey, + wrappedKey exocoretypes.WrappedConsKey, ) error { return k.setOperatorConsKeyForChainID(ctx, opAccAddr, chainID, wrappedKey, false /* genesis */) } @@ -44,7 +45,7 @@ func (k *Keeper) setOperatorConsKeyForChainID( ctx sdk.Context, opAccAddr sdk.AccAddress, chainID string, - wrappedKey types.WrappedConsKey, + wrappedKey exocoretypes.WrappedConsKey, genesis bool, ) error { // check for slashing @@ -136,7 +137,7 @@ func (k *Keeper) setOperatorPrevConsKeyForChainID( ctx sdk.Context, opAccAddr sdk.AccAddress, chainID string, - prevKey types.WrappedConsKey, + prevKey exocoretypes.WrappedConsKey, ) { bz := k.cdc.MustMarshal(prevKey.ToTmProtoKey()) store := ctx.KVStore(k.storeKey) @@ -149,7 +150,7 @@ func (k *Keeper) setOperatorPrevConsKeyForChainID( // and whether the operator is registered in this module. func (k *Keeper) GetOperatorPrevConsKeyForChainID( ctx sdk.Context, opAccAddr sdk.AccAddress, chainID string, -) (bool, types.WrappedConsKey, error) { +) (bool, exocoretypes.WrappedConsKey, error) { // check if we are an operator if !k.IsOperator(ctx, opAccAddr) { return false, nil, delegationtypes.ErrOperatorNotExist @@ -168,7 +169,7 @@ func (k *Keeper) getOperatorPrevConsKeyForChainID( ctx sdk.Context, opAccAddr sdk.AccAddress, chainID string, -) (bool, types.WrappedConsKey) { +) (bool, exocoretypes.WrappedConsKey) { store := ctx.KVStore(k.storeKey) res := store.Get(types.KeyForChainIDAndOperatorToPrevConsKey(chainID, opAccAddr)) if res == nil { @@ -176,7 +177,7 @@ func (k *Keeper) getOperatorPrevConsKeyForChainID( } key := &tmprotocrypto.PublicKey{} k.cdc.MustUnmarshal(res, key) - return true, types.NewWrappedConsKeyFromTmProtoKey(key) + return true, exocoretypes.NewWrappedConsKeyFromTmProtoKey(key) } // GetOperatorConsKeyForChainID gets the (consensus) public key for the given operator address @@ -186,7 +187,7 @@ func (k Keeper) GetOperatorConsKeyForChainID( ctx sdk.Context, opAccAddr sdk.AccAddress, chainID string, -) (bool, types.WrappedConsKey, error) { +) (bool, exocoretypes.WrappedConsKey, error) { // check if we are an operator if !k.IsOperator(ctx, opAccAddr) { return false, nil, delegationtypes.ErrOperatorNotExist @@ -205,7 +206,7 @@ func (k *Keeper) getOperatorConsKeyForChainID( ctx sdk.Context, opAccAddr sdk.AccAddress, chainID string, -) (bool, types.WrappedConsKey) { +) (bool, exocoretypes.WrappedConsKey) { store := ctx.KVStore(k.storeKey) res := store.Get(types.KeyForOperatorAndChainIDToConsKey(opAccAddr, chainID)) if res == nil { @@ -213,7 +214,7 @@ func (k *Keeper) getOperatorConsKeyForChainID( } key := &tmprotocrypto.PublicKey{} k.cdc.MustUnmarshal(res, key) - return true, types.NewWrappedConsKeyFromTmProtoKey(key) + return true, exocoretypes.NewWrappedConsKeyFromTmProtoKey(key) } // GetOperatorAddressForChainIDAndConsAddr returns the operator address for the given chain id @@ -292,7 +293,7 @@ func (k Keeper) CompleteOperatorKeyRemovalForChainID( // jailed operators, frozen operators and those in the process of opting out. func (k *Keeper) GetOperatorsForChainID( ctx sdk.Context, chainID string, -) ([]sdk.AccAddress, []types.WrappedConsKey) { +) ([]sdk.AccAddress, []exocoretypes.WrappedConsKey) { k.Logger(ctx).Info("GetOperatorsForChainID", "chainID", chainID) if isAvs, _ := k.avsKeeper.IsAVSByChainID(ctx, chainID); !isAvs { k.Logger(ctx).Info("GetOperatorsForChainID the chainID is not supported by AVS", "chainID", chainID) @@ -309,7 +310,7 @@ func (k *Keeper) GetOperatorsForChainID( ) defer iterator.Close() var addrs []sdk.AccAddress - var pubKeys []types.WrappedConsKey + var pubKeys []exocoretypes.WrappedConsKey for ; iterator.Valid(); iterator.Next() { // this key is of the format prefix | len | chainID | addr // and our prefix is of the format prefix | len | chainID @@ -318,8 +319,11 @@ func (k *Keeper) GetOperatorsForChainID( res := iterator.Value() ret := &tmprotocrypto.PublicKey{} k.cdc.MustUnmarshal(res, ret) - addrs = append(addrs, addr) - pubKeys = append(pubKeys, types.NewWrappedConsKeyFromTmProtoKey(ret)) + wrappedKey := exocoretypes.NewWrappedConsKeyFromTmProtoKey(ret) + if wrappedKey != nil { + addrs = append(addrs, addr) + pubKeys = append(pubKeys, wrappedKey) + } } return addrs, pubKeys } @@ -329,7 +333,7 @@ func (k *Keeper) GetOperatorsForChainID( // of doing so. func (k Keeper) GetActiveOperatorsForChainID( ctx sdk.Context, chainID string, -) ([]sdk.AccAddress, []types.WrappedConsKey) { +) ([]sdk.AccAddress, []exocoretypes.WrappedConsKey) { isAvs, avsAddr := k.avsKeeper.IsAVSByChainID(ctx, chainID) if !isAvs { k.Logger(ctx).Error("GetActiveOperatorsForChainID the chainID is not supported by AVS", "chainID", chainID) @@ -338,7 +342,7 @@ func (k Keeper) GetActiveOperatorsForChainID( operatorsAddr, pks := k.GetOperatorsForChainID(ctx, chainID) avsAddrString := avsAddr.String() activeOperator := make([]sdk.AccAddress, 0) - activePks := make([]types.WrappedConsKey, 0) + activePks := make([]exocoretypes.WrappedConsKey, 0) // check if the operator is active for i, operator := range operatorsAddr { if k.IsActive(ctx, operator, avsAddrString) { diff --git a/x/operator/keeper/grpc_query.go b/x/operator/keeper/grpc_query.go index cb41ed15e..e4b9cf5b3 100644 --- a/x/operator/keeper/grpc_query.go +++ b/x/operator/keeper/grpc_query.go @@ -6,6 +6,7 @@ import ( assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/operator/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" @@ -156,7 +157,7 @@ func (k Keeper) QueryAllOperatorConsAddrsByChainID( if err := ret.Unmarshal(value); err != nil { return err } - wrappedKey := types.NewWrappedConsKeyFromTmProtoKey(ret) + wrappedKey := exocoretypes.NewWrappedConsKeyFromTmProtoKey(ret) if wrappedKey == nil { return types.ErrInvalidConsKey } diff --git a/x/operator/keeper/msg_server.go b/x/operator/keeper/msg_server.go index ee51329d0..d2de23d82 100644 --- a/x/operator/keeper/msg_server.go +++ b/x/operator/keeper/msg_server.go @@ -4,6 +4,7 @@ import ( context "context" errorsmod "cosmossdk.io/errors" + exocoretypes "github.com/ExocoreNetwork/exocore/types" "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -50,7 +51,7 @@ func (msgServer *MsgServerImpl) OptIntoAVS(goCtx context.Context, req *types.Opt return nil, err } } else { - key := types.NewWrappedConsKeyFromJSON(req.PublicKeyJSON) + key := exocoretypes.NewWrappedConsKeyFromJSON(req.PublicKeyJSON) if key == nil { return nil, errorsmod.Wrap(types.ErrInvalidPubKey, "invalid public key") } @@ -92,7 +93,7 @@ func (msgServer *MsgServerImpl) SetConsKey(goCtx context.Context, req *types.Set if !msgServer.keeper.IsActive(ctx, accAddr, req.AvsAddress) { return nil, errorsmod.Wrap(types.ErrNotOptedIn, "operator is not active") } - wrappedKey := types.NewWrappedConsKeyFromJSON(req.PublicKeyJSON) + wrappedKey := exocoretypes.NewWrappedConsKeyFromJSON(req.PublicKeyJSON) if wrappedKey == nil { return nil, errorsmod.Wrap(types.ErrInvalidPubKey, "invalid public key") } diff --git a/x/operator/keeper/opt.go b/x/operator/keeper/opt.go index f58f4ef8a..9d5d1bf02 100644 --- a/x/operator/keeper/opt.go +++ b/x/operator/keeper/opt.go @@ -3,6 +3,7 @@ package keeper import ( sdkmath "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -16,7 +17,9 @@ type AssetPriceAndDecimal struct { // OptIn call this function to opt in to an AVS. // The caller must ensure that the operatorAddress passed is valid. -func (k *Keeper) OptIn(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr string) error { +func (k *Keeper) OptIn( + ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr string, +) error { // check that the operator is registered if !k.IsOperator(ctx, operatorAddress) { return delegationtypes.ErrOperatorNotExist @@ -64,7 +67,7 @@ func (k *Keeper) OptIn(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr // OptInWithConsKey is a wrapper function to call OptIn and then SetOperatorConsKeyForChainID. // The caller must ensure that the operatorAddress passed is valid and that the AVS is a chain-type AVS. func (k Keeper) OptInWithConsKey( - ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr string, key types.WrappedConsKey, + ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr string, key exocoretypes.WrappedConsKey, ) error { err := k.OptIn(ctx, operatorAddress, avsAddr) if err != nil { diff --git a/x/operator/types/expected_keepers.go b/x/operator/types/expected_keepers.go index b8259014d..4e622cf1f 100644 --- a/x/operator/types/expected_keepers.go +++ b/x/operator/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( sdkmath "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" delegationkeeper "github.com/ExocoreNetwork/exocore/x/delegation/keeper" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" @@ -119,16 +120,16 @@ type OperatorHooks interface { // This hook is called when an operator declares the consensus key for the provided chain. AfterOperatorKeySet( ctx sdk.Context, addr sdk.AccAddress, chainID string, - pubKey WrappedConsKey, + pubKey exocoretypes.WrappedConsKey, ) // This hook is called when an operator's consensus key is replaced for a chain. AfterOperatorKeyReplaced( - ctx sdk.Context, addr sdk.AccAddress, oldKey WrappedConsKey, - newKey WrappedConsKey, chainID string, + ctx sdk.Context, addr sdk.AccAddress, oldKey exocoretypes.WrappedConsKey, + newKey exocoretypes.WrappedConsKey, chainID string, ) // This hook is called when an operator initiates the removal of a consensus key for a // chain. AfterOperatorKeyRemovalInitiated( - ctx sdk.Context, addr sdk.AccAddress, chainID string, key WrappedConsKey, + ctx sdk.Context, addr sdk.AccAddress, chainID string, key exocoretypes.WrappedConsKey, ) } diff --git a/x/operator/types/hooks.go b/x/operator/types/hooks.go index c4e9a1a08..5186827ee 100644 --- a/x/operator/types/hooks.go +++ b/x/operator/types/hooks.go @@ -1,6 +1,7 @@ package types import ( + exocoretypes "github.com/ExocoreNetwork/exocore/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -16,7 +17,7 @@ func (hooks MultiOperatorHooks) AfterOperatorKeySet( ctx sdk.Context, addr sdk.AccAddress, chainID string, - pubKey WrappedConsKey, + pubKey exocoretypes.WrappedConsKey, ) { for _, hook := range hooks { hook.AfterOperatorKeySet(ctx, addr, chainID, pubKey) @@ -26,8 +27,8 @@ func (hooks MultiOperatorHooks) AfterOperatorKeySet( func (hooks MultiOperatorHooks) AfterOperatorKeyReplaced( ctx sdk.Context, addr sdk.AccAddress, - oldKey WrappedConsKey, - newAddr WrappedConsKey, + oldKey exocoretypes.WrappedConsKey, + newAddr exocoretypes.WrappedConsKey, chainID string, ) { for _, hook := range hooks { @@ -36,7 +37,7 @@ func (hooks MultiOperatorHooks) AfterOperatorKeyReplaced( } func (hooks MultiOperatorHooks) AfterOperatorKeyRemovalInitiated( - ctx sdk.Context, addr sdk.AccAddress, chainID string, key WrappedConsKey, + ctx sdk.Context, addr sdk.AccAddress, chainID string, key exocoretypes.WrappedConsKey, ) { for _, hook := range hooks { hook.AfterOperatorKeyRemovalInitiated(ctx, addr, chainID, key) diff --git a/x/operator/types/msg.go b/x/operator/types/msg.go index d4839f485..c83ad7a07 100644 --- a/x/operator/types/msg.go +++ b/x/operator/types/msg.go @@ -2,6 +2,7 @@ package types import ( errorsmod "cosmossdk.io/errors" + exocoretypes "github.com/ExocoreNetwork/exocore/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" ) @@ -68,7 +69,7 @@ func (m *SetConsKeyReq) ValidateBasic() error { if !common.IsHexAddress(m.AvsAddress) { return errorsmod.Wrap(ErrParameterInvalid, "invalid AVS address") } - if wrappedKey := NewWrappedConsKeyFromJSON(m.PublicKeyJSON); wrappedKey == nil { + if wrappedKey := exocoretypes.NewWrappedConsKeyFromJSON(m.PublicKeyJSON); wrappedKey == nil { return errorsmod.Wrapf(ErrParameterInvalid, "invalid public key") } return nil @@ -106,7 +107,7 @@ func (m *OptIntoAVSReq) ValidateBasic() error { // cannot check whether a public key is required or not, // since that is a stateful check if key := m.PublicKeyJSON; len(key) > 0 { - if wrappedKey := NewWrappedConsKeyFromJSON(key); wrappedKey == nil { + if wrappedKey := exocoretypes.NewWrappedConsKeyFromJSON(key); wrappedKey == nil { return errorsmod.Wrapf(ErrParameterInvalid, "invalid public key") } } From 079953e4e0502c7002ad919dbeac307a5bbba68f Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 1 Sep 2024 12:32:21 +0000 Subject: [PATCH 30/52] feat(subscriber): load genesis validators --- proto/exocore/appchain/common/v1/common.proto | 2 +- .../appchain/subscriber/v1/genesis.proto | 12 +- .../appchain/subscriber/v1/subscriber.proto | 23 + x/appchain/common/types/common.pb.go | 2 +- x/appchain/common/types/expected_keepers.go | 13 + x/appchain/common/types/keys.go | 6 + .../coordinator/types/expected_keepers.go | 4 +- x/appchain/subscriber/keeper/connection.go | 23 + x/appchain/subscriber/keeper/genesis.go | 32 +- x/appchain/subscriber/keeper/keeper.go | 72 ++- x/appchain/subscriber/keeper/validators.go | 141 ++++++ x/appchain/subscriber/types/genesis.go | 4 +- x/appchain/subscriber/types/genesis.pb.go | 202 +++++++- x/appchain/subscriber/types/keys.go | 46 ++ x/appchain/subscriber/types/subscriber.pb.go | 430 ++++++++++++++++++ x/appchain/subscriber/types/validator.go | 46 ++ 16 files changed, 1028 insertions(+), 30 deletions(-) create mode 100644 proto/exocore/appchain/subscriber/v1/subscriber.proto create mode 100644 x/appchain/common/types/keys.go create mode 100644 x/appchain/subscriber/keeper/connection.go create mode 100644 x/appchain/subscriber/keeper/validators.go create mode 100644 x/appchain/subscriber/types/subscriber.pb.go create mode 100644 x/appchain/subscriber/types/validator.go diff --git a/proto/exocore/appchain/common/v1/common.proto b/proto/exocore/appchain/common/v1/common.proto index 138148319..41c5f59a3 100644 --- a/proto/exocore/appchain/common/v1/common.proto +++ b/proto/exocore/appchain/common/v1/common.proto @@ -100,7 +100,7 @@ message CoordinatorInfo { ibc.lightclients.tendermint.v1.ClientState client_state = 1; // consensus_state is the consensus state of the coordinator chain. ibc.lightclients.tendermint.v1.ConsensusState consensus_state = 2; - // initial_val_set is the initial validator set of the coordinator chain. + // initial_val_set is the initial validator set of the subscriber chain. repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 [ (gogoproto.nullable) = false ]; } \ No newline at end of file diff --git a/proto/exocore/appchain/subscriber/v1/genesis.proto b/proto/exocore/appchain/subscriber/v1/genesis.proto index 2df7a1654..00c1c8c38 100644 --- a/proto/exocore/appchain/subscriber/v1/genesis.proto +++ b/proto/exocore/appchain/subscriber/v1/genesis.proto @@ -9,6 +9,16 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/typ // GenesisState is the genesis state for the appchain subscriber module. message GenesisState { - // Params is the parameters for the appchain subscriber module. + // The first two fields are word-for-word pulled from `common.proto`, to be + // filled by the coordinator module (or an export). + // params is the parameters for the appchain subscriber module. exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false]; + // coordinator is the coordinator information for the subscriber. + exocore.appchain.common.v1.CoordinatorInfo coordinator = 2 [ (gogoproto.nullable) = false ]; + // Below are the IBC parameters + // coordinator_client_id is the client id of the coordinator chain. + string coordinator_client_id = 3 [ (gogoproto.customname) = "CoordinatorClientID" ]; + // coordinator_channel_id is the channel id of the coordinator chain. + string coordinator_channel_id = 4 [ (gogoproto.customname) = "CoordinatorChannelID" ]; + // operational parameters that are to be exported can go here. } diff --git a/proto/exocore/appchain/subscriber/v1/subscriber.proto b/proto/exocore/appchain/subscriber/v1/subscriber.proto new file mode 100644 index 000000000..f4467cc45 --- /dev/null +++ b/proto/exocore/appchain/subscriber/v1/subscriber.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package exocore.appchain.subscriber.v1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; + +message OmniChainValidator { + // The address is derived from the consenus key. It has no relation with the operator + // address on Exocore. + bytes address = 1; + // Last known + int64 power = 2; + // pubkey is the consensus public key of the validator, as a Protobuf Any. + google.protobuf.Any pubkey = 3 [ + (cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", + (gogoproto.moretags) = "yaml:\"consensus_pubkey\"" + ]; +} + diff --git a/x/appchain/common/types/common.pb.go b/x/appchain/common/types/common.pb.go index c2341e051..8b230e1aa 100644 --- a/x/appchain/common/types/common.pb.go +++ b/x/appchain/common/types/common.pb.go @@ -258,7 +258,7 @@ type CoordinatorInfo struct { ClientState *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty"` // consensus_state is the consensus state of the coordinator chain. ConsensusState *_07_tendermint.ConsensusState `protobuf:"bytes,2,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty"` - // initial_val_set is the initial validator set of the coordinator chain. + // initial_val_set is the initial validator set of the subscriber chain. InitialValSet []types.ValidatorUpdate `protobuf:"bytes,3,rep,name=initial_val_set,json=initialValSet,proto3" json:"initial_val_set"` } diff --git a/x/appchain/common/types/expected_keepers.go b/x/appchain/common/types/expected_keepers.go index 57f9416ae..dde8f9acf 100644 --- a/x/appchain/common/types/expected_keepers.go +++ b/x/appchain/common/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) @@ -17,3 +18,15 @@ type ClientKeeper interface { sdk.Context, ibcexported.Height, ) (ibcexported.ConsensusState, error) } + +// ScopedKeeper defines the expected IBC capability keeper +type ScopedKeeper interface { + GetCapability(sdk.Context, string) (*capabilitytypes.Capability, bool) + AuthenticateCapability(sdk.Context, *capabilitytypes.Capability, string) bool + ClaimCapability(sdk.Context, *capabilitytypes.Capability, string) error +} + +// PortKeeper defines the expected IBC port keeper +type PortKeeper interface { + BindPort(ctx sdk.Context, portID string) *capabilitytypes.Capability +} diff --git a/x/appchain/common/types/keys.go b/x/appchain/common/types/keys.go new file mode 100644 index 000000000..cd5bc687a --- /dev/null +++ b/x/appchain/common/types/keys.go @@ -0,0 +1,6 @@ +package types + +const ( + // SubscriberPortID is the port id for the subscriber module. + SubscriberPortID = "subscriber" +) diff --git a/x/appchain/coordinator/types/expected_keepers.go b/x/appchain/coordinator/types/expected_keepers.go index 52d8c568a..dba2d1e25 100644 --- a/x/appchain/coordinator/types/expected_keepers.go +++ b/x/appchain/coordinator/types/expected_keepers.go @@ -3,9 +3,9 @@ package types import ( time "time" + "github.com/ExocoreNetwork/exocore/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" - operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" ) @@ -29,6 +29,6 @@ type StakingKeeper interface { // OperatorKeeper represents the expected keeper interface for the operator module. type OperatorKeeper interface { - GetActiveOperatorsForChainID(sdk.Context, string) ([]sdk.AccAddress, []operatortypes.WrappedConsKey) + GetActiveOperatorsForChainID(sdk.Context, string) ([]sdk.AccAddress, []types.WrappedConsKey) GetVotePowerForChainID(sdk.Context, []sdk.AccAddress, string) ([]int64, error) } diff --git a/x/appchain/subscriber/keeper/connection.go b/x/appchain/subscriber/keeper/connection.go new file mode 100644 index 000000000..519a5efc3 --- /dev/null +++ b/x/appchain/subscriber/keeper/connection.go @@ -0,0 +1,23 @@ +package keeper + +import ( + types "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SetCoordinatorClientID sets the clientID of the coordinator chain +func (k Keeper) SetCoordinatorClientID(ctx sdk.Context, clientID string) { + store := ctx.KVStore(k.storeKey) + store.Set(types.CoordinatorClientIDKey(), []byte(clientID)) +} + +// GetCoordinatorClientID gets the clientID of the coordinator chain +func (k Keeper) GetCoordinatorClientID(ctx sdk.Context) (string, bool) { + store := ctx.KVStore(k.storeKey) + key := types.CoordinatorClientIDKey() + if !store.Has(key) { + return "", false + } + bz := store.Get(key) + return string(bz), true +} diff --git a/x/appchain/subscriber/keeper/genesis.go b/x/appchain/subscriber/keeper/genesis.go index 3e353f09e..e5afd41c4 100644 --- a/x/appchain/subscriber/keeper/genesis.go +++ b/x/appchain/subscriber/keeper/genesis.go @@ -1,14 +1,44 @@ package keeper import ( + "fmt" + + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" ) +// InitGenesis initializes the subscriber module's state from a genesis state. +// This state is typically obtained from a coordinator chain, however, it +// may be exported from a previous state of the subscriber chain. func (k Keeper) InitGenesis(ctx sdk.Context, gs types.GenesisState) []abci.ValidatorUpdate { + // do not support switchover use case yet. + if ctx.BlockHeight() > 0 { + // this is not supported not because of any technical limitations + // but rather because the business logic and the security logic + // around switchover is not yet fully designed. + panic("switchover use case not supported yet") + } k.SetParams(ctx, gs.Params) - return []abci.ValidatorUpdate{} + k.SetPort(ctx, commontypes.SubscriberPortID) + // only bind to the port if the capability keeper hasn't done so already + if !k.IsBound(ctx, commontypes.SubscriberPortID) { + k.Logger(ctx).Info("binding port", "port", commontypes.SubscriberPortID) + if err := k.portKeeper.BindPort(ctx, commontypes.SubscriberPortID); err != nil { + panic(fmt.Sprintf("could not claim port capability: %v", err)) + } + } + // the client state and the consensus state are provided by the coordinator. + clientID, err := k.clientKeeper.CreateClient( + ctx, gs.Coordinator.ClientState, gs.Coordinator.ConsensusState, + ) + if err != nil { + panic(fmt.Sprintf("could not create client for coordinator chain: %v", err)) + } + k.SetCoordinatorClientID(ctx, clientID) + k.SetValsetUpdateIDForHeight(ctx, ctx.BlockHeight(), types.FirstValsetUpdateID) + return k.ApplyValidatorChanges(ctx, gs.Coordinator.InitialValSet) } func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { diff --git a/x/appchain/subscriber/keeper/keeper.go b/x/appchain/subscriber/keeper/keeper.go index 9a73b1fba..49628e36c 100644 --- a/x/appchain/subscriber/keeper/keeper.go +++ b/x/appchain/subscriber/keeper/keeper.go @@ -1,19 +1,79 @@ package keeper import ( + "fmt" + + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) type Keeper struct { - cdc codec.BinaryCodec - storeKey storetypes.StoreKey + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + scopedKeeper commontypes.ScopedKeeper + portKeeper commontypes.PortKeeper + clientKeeper commontypes.ClientKeeper } -// NewKeeper creates a new coordinator keeper. -func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey) Keeper { +// NewKeeper creates a new subscriber keeper. +func NewKeeper( + cdc codec.BinaryCodec, + storeKey storetypes.StoreKey, + scopedKeeper commontypes.ScopedKeeper, + portKeeper commontypes.PortKeeper, + clientKeeper commontypes.ClientKeeper, +) Keeper { return Keeper{ - cdc: cdc, - storeKey: storeKey, + cdc: cdc, + storeKey: storeKey, + scopedKeeper: scopedKeeper, + portKeeper: portKeeper, + clientKeeper: clientKeeper, } } + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +// GetPort returns the portID for the IBC app module. Used in ExportGenesis +func (k Keeper) GetPort(ctx sdk.Context) string { + store := ctx.KVStore(k.storeKey) + return string(store.Get(types.PortKey())) +} + +// SetPort sets the portID for the IBC app module. Used in InitGenesis +func (k Keeper) SetPort(ctx sdk.Context, portID string) { + store := ctx.KVStore(k.storeKey) + store.Set(types.PortKey(), []byte(portID)) +} + +// IsBound checks if the IBC app module is already bound to the desired port +func (k Keeper) IsBound(ctx sdk.Context, portID string) bool { + _, ok := k.scopedKeeper.GetCapability(ctx, host.PortPath(portID)) + return ok +} + +// BindPort defines a wrapper function for the port Keeper's function in +// order to expose it to module's InitGenesis function +func (k Keeper) BindPort(ctx sdk.Context, portID string) error { + cap := k.portKeeper.BindPort(ctx, portID) + return k.ClaimCapability(ctx, cap, host.PortPath(portID)) +} + +// ClaimCapability allows the IBC app module to claim a capability that core IBC +// passes to it +func (k Keeper) ClaimCapability( + ctx sdk.Context, + cap *capabilitytypes.Capability, + name string, +) error { + return k.scopedKeeper.ClaimCapability(ctx, cap, name) +} diff --git a/x/appchain/subscriber/keeper/validators.go b/x/appchain/subscriber/keeper/validators.go new file mode 100644 index 000000000..719bbb821 --- /dev/null +++ b/x/appchain/subscriber/keeper/validators.go @@ -0,0 +1,141 @@ +package keeper + +import ( + "fmt" + + exocoretypes "github.com/ExocoreNetwork/exocore/types" + types "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SetValsetUpdateIDForHeight sets the valset update ID for a given height +func (k Keeper) SetValsetUpdateIDForHeight( + ctx sdk.Context, height int64, valsetUpdateID uint64, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.ValsetUpdateIDKey(height), sdk.Uint64ToBigEndian(valsetUpdateID)) +} + +// GetValsetUpdateIDForHeight gets the valset update ID for a given height +func (k Keeper) GetValsetUpdateIDForHeight( + ctx sdk.Context, height int64, +) (uint64, bool) { + store := ctx.KVStore(k.storeKey) + key := types.ValsetUpdateIDKey(height) + if !store.Has(key) { + return 0, false + } + bz := store.Get(key) + return sdk.BigEndianToUint64(bz), true +} + +// ApplyValidatorChanges is a wrapper function that returns the provided validator set +// update. The wrapping allows to save the validator set information in the store. +// The caller should (but _not_ must) provide `changes` that are different from the +// ones already with Tendermint. +func (k Keeper) ApplyValidatorChanges( + ctx sdk.Context, + // in dogfood, we use the wrappedkeywithpower because the operator module provides + // keys in that format. since the subscriber chain doesn't need the operator module + // we can use the tm validator update type. + changes []abci.ValidatorUpdate, +) []abci.ValidatorUpdate { + ret := make([]abci.ValidatorUpdate, 0, len(changes)) + logger := k.Logger(ctx) + for _, change := range changes { + wrappedKey := exocoretypes.NewWrappedConsKeyFromTmProtoKey(&change.PubKey) + if wrappedKey == nil { + // an error in deserializing the key would indicate that the coordinator + // has provided invalid data. this is a critical error and should be + // investigated. + panic(fmt.Sprintf("invalid pubkey %s", change.PubKey)) + } + consAddress := wrappedKey.ToConsAddr() + val, found := k.GetOmnichainValidator(ctx, consAddress) + switch found { + case true: + if change.Power < 1 { + logger.Info("deleting validator", "consAddress", consAddress) + k.DeleteOmnichainValidator(ctx, consAddress) + } else { + logger.Info("updating validator", "consAddress", consAddress) + val.Power = change.Power + k.SetOmnichainValidator(ctx, val) + } + case false: + if change.Power > 0 { + ocVal, err := types.NewOmniChainValidator( + consAddress, change.Power, wrappedKey.ToSdkKey(), + ) + if err != nil { + // cannot happen, but just in case add this check. + // simply skip the validator if it does. + continue + } + logger.Info("adding validator", "consAddress", consAddress) + k.SetOmnichainValidator(ctx, ocVal) + ret = append(ret, change) + } else { + // edge case: we received an update for 0 power + // but the validator is already deleted. Do not forward + // to tendermint. + logger.Info( + "received update for non-existent validator", + "cons address", consAddress, + ) + continue + } + } + ret = append(ret, change) + } + return ret +} + +// SetOmnichainValidator stores a validator based on the pub key derived address. +func (k Keeper) SetOmnichainValidator( + ctx sdk.Context, validator types.OmniChainValidator, +) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&validator) + + store.Set(types.OmniChainValidatorKey(validator.Address), bz) +} + +// GetOmnichainValidator gets a validator based on the pub key derived (consensus) address. +func (k Keeper) GetOmnichainValidator( + ctx sdk.Context, addr sdk.ConsAddress, +) (validator types.OmniChainValidator, found bool) { + store := ctx.KVStore(k.storeKey) + v := store.Get(types.OmniChainValidatorKey(addr.Bytes())) + if v == nil { + return + } + k.cdc.MustUnmarshal(v, &validator) + found = true + + return +} + +// DeleteOmnichainValidator deletes a validator based on the pub key derived address. +func (k Keeper) DeleteOmnichainValidator(ctx sdk.Context, addr sdk.ConsAddress) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.OmniChainValidatorKey(addr.Bytes())) +} + +// GetAllOmnichainValidators returns all validators in the store. +func (k Keeper) GetAllOmnichainValidators( + ctx sdk.Context, +) (validators []types.OmniChainValidator) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, []byte{types.OmniChainValidatorBytePrefix}) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + val := types.OmniChainValidator{} + k.cdc.MustUnmarshal(iterator.Value(), &val) + validators = append(validators, val) + } + + return validators +} diff --git a/x/appchain/subscriber/types/genesis.go b/x/appchain/subscriber/types/genesis.go index 7d5e514e6..ca211ece9 100644 --- a/x/appchain/subscriber/types/genesis.go +++ b/x/appchain/subscriber/types/genesis.go @@ -10,7 +10,9 @@ func DefaultGenesis() *GenesisState { } // NewGenesis creates a new genesis state with the provided parameters and -// data. +// data. Since most of the genesis fields are filled by the coordinator, +// the subscriber module only needs to fill the subscriber params. +// Even those will be overwritten. func NewGenesis(params commontypes.SubscriberParams) *GenesisState { return &GenesisState{Params: params} } diff --git a/x/appchain/subscriber/types/genesis.pb.go b/x/appchain/subscriber/types/genesis.pb.go index 4d3f210f0..c52234281 100644 --- a/x/appchain/subscriber/types/genesis.pb.go +++ b/x/appchain/subscriber/types/genesis.pb.go @@ -26,8 +26,17 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState is the genesis state for the appchain subscriber module. type GenesisState struct { - // Params is the parameters for the appchain subscriber module. + // The first two fields are word-for-word pulled from `common.proto`, to be + // filled by the coordinator module (or an export). + // params is the parameters for the appchain subscriber module. Params types.SubscriberParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // coordinator is the coordinator information for the subscriber. + Coordinator types.CoordinatorInfo `protobuf:"bytes,2,opt,name=coordinator,proto3" json:"coordinator"` + // Below are the IBC parameters + // coordinator_client_id is the client id of the coordinator chain. + CoordinatorClientID string `protobuf:"bytes,3,opt,name=coordinator_client_id,json=coordinatorClientId,proto3" json:"coordinator_client_id,omitempty"` + // coordinator_channel_id is the channel id of the coordinator chain. + CoordinatorChannelID string `protobuf:"bytes,4,opt,name=coordinator_channel_id,json=coordinatorChannelId,proto3" json:"coordinator_channel_id,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -70,6 +79,27 @@ func (m *GenesisState) GetParams() types.SubscriberParams { return types.SubscriberParams{} } +func (m *GenesisState) GetCoordinator() types.CoordinatorInfo { + if m != nil { + return m.Coordinator + } + return types.CoordinatorInfo{} +} + +func (m *GenesisState) GetCoordinatorClientID() string { + if m != nil { + return m.CoordinatorClientID + } + return "" +} + +func (m *GenesisState) GetCoordinatorChannelID() string { + if m != nil { + return m.CoordinatorChannelID + } + return "" +} + func init() { proto.RegisterType((*GenesisState)(nil), "exocore.appchain.subscriber.v1.GenesisState") } @@ -79,22 +109,29 @@ func init() { } var fileDescriptor_f608de439fd2c5db = []byte{ - // 232 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x49, 0xad, 0xc8, 0x4f, - 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2f, 0x2e, 0x4d, - 0x2a, 0x4e, 0x2e, 0xca, 0x4c, 0x4a, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, - 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0xaa, 0xd6, 0x83, 0xa9, 0xd6, - 0x43, 0xa8, 0xd6, 0x2b, 0x33, 0x94, 0x52, 0xc7, 0x30, 0x2d, 0x39, 0x3f, 0x37, 0x37, 0x3f, 0x0f, - 0x64, 0x12, 0x84, 0x05, 0x31, 0x48, 0x4a, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xcc, 0xd4, 0x07, 0xb1, - 0x20, 0xa2, 0x4a, 0x51, 0x5c, 0x3c, 0xee, 0x10, 0xfb, 0x82, 0x4b, 0x12, 0x4b, 0x52, 0x85, 0xbc, - 0xb8, 0xd8, 0x0a, 0x12, 0x8b, 0x12, 0x73, 0x8b, 0x25, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0x74, - 0xf4, 0x30, 0xec, 0x87, 0x9a, 0x5a, 0x66, 0xa8, 0x17, 0x0c, 0x77, 0x49, 0x00, 0x58, 0x8f, 0x13, - 0xcb, 0x89, 0x7b, 0xf2, 0x0c, 0x41, 0x50, 0x13, 0x9c, 0xc2, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, - 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, - 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x36, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x09, 0x64, 0x94, 0xbe, 0x2b, - 0xc4, 0x7c, 0xbf, 0xd4, 0x92, 0xf2, 0xfc, 0xa2, 0x6c, 0x7d, 0x98, 0x77, 0x2a, 0xb0, 0x06, 0x4f, - 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0xed, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x3c, 0xba, 0x2f, 0x3b, 0x4a, 0x01, 0x00, 0x00, + // 340 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0xd2, 0xbf, 0x4f, 0xc2, 0x40, + 0x14, 0x07, 0xf0, 0x16, 0x09, 0x89, 0xc5, 0xa9, 0xa0, 0x36, 0x0c, 0x07, 0x71, 0x91, 0x44, 0xd2, + 0x0b, 0x3a, 0xbb, 0x00, 0xc6, 0xa0, 0x09, 0x31, 0x30, 0x98, 0xb8, 0x90, 0xeb, 0xf5, 0x2c, 0x17, + 0xe1, 0x5e, 0x73, 0x3d, 0x10, 0xff, 0x0b, 0xff, 0x2c, 0x06, 0x07, 0x46, 0x27, 0x62, 0xca, 0x3f, + 0x62, 0xfa, 0x03, 0xa9, 0xa9, 0x71, 0x7b, 0x7d, 0xfd, 0xf6, 0xd3, 0xd7, 0xbe, 0x33, 0x5a, 0x6c, + 0x09, 0x14, 0x24, 0xc3, 0xc4, 0xf7, 0xe9, 0x84, 0x70, 0x81, 0x83, 0xb9, 0x13, 0x50, 0xc9, 0x1d, + 0x26, 0xf1, 0xa2, 0x8d, 0x3d, 0x26, 0x58, 0xc0, 0x03, 0xdb, 0x97, 0xa0, 0xc0, 0x44, 0x69, 0xda, + 0xde, 0xa5, 0xed, 0x7d, 0xda, 0x5e, 0xb4, 0x6b, 0xe7, 0x39, 0x8d, 0xc2, 0x6c, 0x06, 0x22, 0x92, + 0x92, 0x2a, 0x81, 0x6a, 0x55, 0x0f, 0x3c, 0x88, 0x4b, 0x1c, 0x55, 0x49, 0xf7, 0xec, 0xa3, 0x60, + 0x1c, 0xdd, 0x26, 0x2f, 0x1c, 0x29, 0xa2, 0x98, 0x79, 0x67, 0x94, 0x7c, 0x22, 0xc9, 0x2c, 0xb0, + 0xf4, 0x86, 0xde, 0x2c, 0x5f, 0xb6, 0xec, 0xdc, 0x00, 0x29, 0xbb, 0x68, 0xdb, 0xa3, 0x9f, 0x51, + 0x1e, 0xe2, 0x67, 0x3a, 0xc5, 0xd5, 0xa6, 0xae, 0x0d, 0x53, 0xc1, 0x1c, 0x19, 0x65, 0x0a, 0x20, + 0x5d, 0x2e, 0x88, 0x02, 0x69, 0x15, 0x62, 0xf0, 0xe2, 0x3f, 0xb0, 0xbb, 0x8f, 0xf7, 0xc5, 0x33, + 0xa4, 0x5e, 0x56, 0x31, 0xef, 0x8d, 0xe3, 0xcc, 0xe5, 0x98, 0x4e, 0x39, 0x13, 0x6a, 0xcc, 0x5d, + 0xeb, 0xa0, 0xa1, 0x37, 0x0f, 0x3b, 0xa7, 0xe1, 0xa6, 0x5e, 0xc9, 0x30, 0xdd, 0xf8, 0x7e, 0xbf, + 0x37, 0xac, 0xd0, 0x5c, 0xd3, 0x35, 0x07, 0xc6, 0xc9, 0x2f, 0x6c, 0x42, 0x84, 0x60, 0xd3, 0x48, + 0x2b, 0xc6, 0x9a, 0x15, 0x6e, 0xea, 0xd5, 0xac, 0x96, 0x04, 0xfa, 0xbd, 0x61, 0x95, 0xe6, 0xbb, + 0x6e, 0xe7, 0x71, 0x15, 0x22, 0x7d, 0x1d, 0x22, 0xfd, 0x2b, 0x44, 0xfa, 0xfb, 0x16, 0x69, 0xeb, + 0x2d, 0xd2, 0x3e, 0xb7, 0x48, 0x7b, 0xba, 0xf6, 0xb8, 0x9a, 0xcc, 0x9d, 0xe8, 0x5b, 0xf1, 0x4d, + 0xf2, 0x03, 0x06, 0x4c, 0xbd, 0x82, 0x7c, 0xc1, 0xbb, 0x0d, 0x2e, 0xff, 0x3c, 0x11, 0xea, 0xcd, + 0x67, 0x81, 0x53, 0x8a, 0xd7, 0x75, 0xf5, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x07, 0x9b, 0x62, 0x88, + 0x3d, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -117,6 +154,30 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CoordinatorChannelID) > 0 { + i -= len(m.CoordinatorChannelID) + copy(dAtA[i:], m.CoordinatorChannelID) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.CoordinatorChannelID))) + i-- + dAtA[i] = 0x22 + } + if len(m.CoordinatorClientID) > 0 { + i -= len(m.CoordinatorClientID) + copy(dAtA[i:], m.CoordinatorClientID) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.CoordinatorClientID))) + i-- + dAtA[i] = 0x1a + } + { + size, err := m.Coordinator.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 { size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -149,6 +210,16 @@ func (m *GenesisState) Size() (n int) { _ = l l = m.Params.Size() n += 1 + l + sovGenesis(uint64(l)) + l = m.Coordinator.Size() + n += 1 + l + sovGenesis(uint64(l)) + l = len(m.CoordinatorClientID) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.CoordinatorChannelID) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -220,6 +291,103 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Coordinator", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Coordinator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CoordinatorClientID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CoordinatorClientID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CoordinatorChannelID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CoordinatorChannelID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/appchain/subscriber/types/keys.go b/x/appchain/subscriber/types/keys.go index e67ac4d65..f8178090f 100644 --- a/x/appchain/subscriber/types/keys.go +++ b/x/appchain/subscriber/types/keys.go @@ -1,5 +1,9 @@ package types +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + const ( // ModuleName defines the module name ModuleName = "subscriber" @@ -16,15 +20,57 @@ const ( // PortID is the default port id that module binds to PortID = "subscriber" + // SubscriberRedistributeName is the name of the fee pool address that stores + // the tokens that aren't sent to the coordinator SubscriberRedistributeName = "subscriber_redistribute" + // SubscriberToSendToCoordinatorName is the name of the fee pool address that + // stores the tokens that are sent to the coordinator SubscriberToSendToCoordinatorName = "subscriber_to_send_to_coordinator" ) const ( + // FirstValsetUpdateID is the first update ID for the validator set + FirstValsetUpdateID uint64 = 0 +) + +const ( + // ParamsBytePrefix is the prefix for the params key ParamsBytePrefix byte = iota + 1 + // PortBytePrefix is the prefix for the port key + PortBytePrefix + // CoordinatorClientIDBytePrefix is the prefix for the coordinator client ID key + CoordinatorClientIDBytePrefix + // ValsetUpdateIDBytePrefix is the prefix for the valset update ID key + ValsetUpdateIDBytePrefix + // OmniChainValidatorBytePrefix is the prefix for the omni chain validator key + OmniChainValidatorBytePrefix ) +// ParamsKey returns the key for the params func ParamsKey() []byte { return []byte{ParamsBytePrefix} } + +// PortKey returns the key for the port (hello Harry Potter!) +func PortKey() []byte { + return []byte{PortBytePrefix} +} + +// CoordinatorClientIDKey returns the key for the coordinator client ID +func CoordinatorClientIDKey() []byte { + return []byte{CoordinatorClientIDBytePrefix} +} + +// ValsetUpdateIDKey returns the key for the valset update ID against the provided height. +func ValsetUpdateIDKey(height int64) []byte { + return append( + []byte{ValsetUpdateIDBytePrefix}, + sdk.Uint64ToBigEndian(uint64(height))..., + ) +} + +// OmniChainValidatorKey returns the key for the omni chain validator against the provided address. +func OmniChainValidatorKey(address sdk.ConsAddress) []byte { + return append([]byte{OmniChainValidatorBytePrefix}, address...) +} diff --git a/x/appchain/subscriber/types/subscriber.pb.go b/x/appchain/subscriber/types/subscriber.pb.go new file mode 100644 index 000000000..445a4076e --- /dev/null +++ b/x/appchain/subscriber/types/subscriber.pb.go @@ -0,0 +1,430 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/subscriber/v1/subscriber.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + types "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type OmniChainValidator struct { + // The address is derived from the consenus key. It has no relation with the operator + // address on Exocore. + Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // Last known + Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` + // pubkey is the consensus public key of the validator, as a Protobuf Any. + Pubkey *types.Any `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" yaml:"consensus_pubkey"` +} + +func (m *OmniChainValidator) Reset() { *m = OmniChainValidator{} } +func (m *OmniChainValidator) String() string { return proto.CompactTextString(m) } +func (*OmniChainValidator) ProtoMessage() {} +func (*OmniChainValidator) Descriptor() ([]byte, []int) { + return fileDescriptor_1c15efc73dd829e9, []int{0} +} +func (m *OmniChainValidator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OmniChainValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OmniChainValidator.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *OmniChainValidator) XXX_Merge(src proto.Message) { + xxx_messageInfo_OmniChainValidator.Merge(m, src) +} +func (m *OmniChainValidator) XXX_Size() int { + return m.Size() +} +func (m *OmniChainValidator) XXX_DiscardUnknown() { + xxx_messageInfo_OmniChainValidator.DiscardUnknown(m) +} + +var xxx_messageInfo_OmniChainValidator proto.InternalMessageInfo + +func (m *OmniChainValidator) GetAddress() []byte { + if m != nil { + return m.Address + } + return nil +} + +func (m *OmniChainValidator) GetPower() int64 { + if m != nil { + return m.Power + } + return 0 +} + +func (m *OmniChainValidator) GetPubkey() *types.Any { + if m != nil { + return m.Pubkey + } + return nil +} + +func init() { + proto.RegisterType((*OmniChainValidator)(nil), "exocore.appchain.subscriber.v1.OmniChainValidator") +} + +func init() { + proto.RegisterFile("exocore/appchain/subscriber/v1/subscriber.proto", fileDescriptor_1c15efc73dd829e9) +} + +var fileDescriptor_1c15efc73dd829e9 = []byte{ + // 320 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4e, 0x02, 0x31, + 0x14, 0x86, 0xa9, 0x44, 0x4c, 0x46, 0x57, 0x93, 0x49, 0x1c, 0x58, 0x54, 0xc2, 0x8a, 0x8d, 0x6d, + 0x90, 0x9d, 0x89, 0x0b, 0x31, 0xae, 0x4c, 0xd4, 0xb0, 0xd0, 0xc4, 0x0d, 0x69, 0x4b, 0x1d, 0x26, + 0x30, 0xf3, 0x9a, 0x76, 0x0a, 0xf4, 0x16, 0xde, 0xc2, 0x0b, 0x78, 0x08, 0xe3, 0x8a, 0xa5, 0x2b, + 0x63, 0xe0, 0x06, 0x9e, 0xc0, 0x40, 0x07, 0xc3, 0xc2, 0xdd, 0xfb, 0xfb, 0xfe, 0xbf, 0xef, 0xcb, + 0x1f, 0x50, 0x39, 0x07, 0x01, 0x5a, 0x52, 0xa6, 0x94, 0x18, 0xb1, 0x34, 0xa7, 0xc6, 0x72, 0x23, + 0x74, 0xca, 0xa5, 0xa6, 0xd3, 0xce, 0x8e, 0x22, 0x4a, 0x43, 0x01, 0x21, 0x2e, 0x03, 0x64, 0x1b, + 0x20, 0x3b, 0x96, 0x69, 0xa7, 0x51, 0x4f, 0x00, 0x92, 0x89, 0xa4, 0x1b, 0x37, 0xb7, 0xcf, 0x94, + 0xe5, 0xce, 0x47, 0x1b, 0x51, 0x02, 0x09, 0x6c, 0x46, 0xba, 0x9e, 0xca, 0xd7, 0xba, 0x00, 0x93, + 0x81, 0x19, 0xf8, 0x85, 0x17, 0x7e, 0xd5, 0x7a, 0x45, 0x41, 0x78, 0x97, 0xe5, 0xe9, 0xd5, 0xfa, + 0xce, 0x03, 0x9b, 0xa4, 0x43, 0x56, 0x80, 0x0e, 0xe3, 0xe0, 0x80, 0x0d, 0x87, 0x5a, 0x1a, 0x13, + 0xa3, 0x26, 0x6a, 0x1f, 0xf5, 0xb7, 0x32, 0x8c, 0x82, 0x7d, 0x05, 0x33, 0xa9, 0xe3, 0xbd, 0x26, + 0x6a, 0x57, 0xfb, 0x5e, 0x84, 0x2c, 0xa8, 0x29, 0xcb, 0xc7, 0xd2, 0xc5, 0xd5, 0x26, 0x6a, 0x1f, + 0x9e, 0x45, 0xc4, 0x33, 0x92, 0x2d, 0x23, 0xb9, 0xcc, 0x5d, 0xaf, 0xfb, 0xf3, 0x75, 0x72, 0xec, + 0x58, 0x36, 0x39, 0x6f, 0x09, 0xc8, 0x8d, 0xcc, 0x8d, 0x35, 0x03, 0x9f, 0x6b, 0x7d, 0xbc, 0x9d, + 0x46, 0x25, 0x99, 0xd0, 0x4e, 0x15, 0x40, 0xee, 0x2d, 0xbf, 0x91, 0xae, 0x5f, 0x7e, 0xdc, 0x7b, + 0x7c, 0x5f, 0x62, 0xb4, 0x58, 0x62, 0xf4, 0xbd, 0xc4, 0xe8, 0x65, 0x85, 0x2b, 0x8b, 0x15, 0xae, + 0x7c, 0xae, 0x70, 0xe5, 0xe9, 0x22, 0x49, 0x8b, 0x91, 0xe5, 0x44, 0x40, 0x46, 0xaf, 0x7d, 0x75, + 0xb7, 0xb2, 0x98, 0x81, 0x1e, 0xff, 0x55, 0x3f, 0xff, 0xb7, 0xfc, 0xc2, 0x29, 0x69, 0x78, 0x6d, + 0xc3, 0xd8, 0xfd, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xee, 0x66, 0xe1, 0x6d, 0xa8, 0x01, 0x00, 0x00, +} + +func (m *OmniChainValidator) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *OmniChainValidator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OmniChainValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pubkey != nil { + { + size, err := m.Pubkey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSubscriber(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Power != 0 { + i = encodeVarintSubscriber(dAtA, i, uint64(m.Power)) + i-- + dAtA[i] = 0x10 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintSubscriber(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintSubscriber(dAtA []byte, offset int, v uint64) int { + offset -= sovSubscriber(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *OmniChainValidator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovSubscriber(uint64(l)) + } + if m.Power != 0 { + n += 1 + sovSubscriber(uint64(m.Power)) + } + if m.Pubkey != nil { + l = m.Pubkey.Size() + n += 1 + l + sovSubscriber(uint64(l)) + } + return n +} + +func sovSubscriber(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSubscriber(x uint64) (n int) { + return sovSubscriber(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *OmniChainValidator) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubscriber + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: OmniChainValidator: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OmniChainValidator: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubscriber + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSubscriber + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSubscriber + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...) + if m.Address == nil { + m.Address = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType) + } + m.Power = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubscriber + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Power |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pubkey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubscriber + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubscriber + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubscriber + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pubkey == nil { + m.Pubkey = &types.Any{} + } + if err := m.Pubkey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSubscriber(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubscriber + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSubscriber(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSubscriber + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSubscriber + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSubscriber + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthSubscriber + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupSubscriber + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthSubscriber + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthSubscriber = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSubscriber = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupSubscriber = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/subscriber/types/validator.go b/x/appchain/subscriber/types/validator.go new file mode 100644 index 000000000..3bc44fa41 --- /dev/null +++ b/x/appchain/subscriber/types/validator.go @@ -0,0 +1,46 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// NewOmniChainValidator creates a new OmniChainValidator instance. +func NewOmniChainValidator( + address []byte, power int64, pubKey cryptotypes.PubKey, +) (OmniChainValidator, error) { + pkAny, err := codectypes.NewAnyWithValue(pubKey) + if err != nil { + return OmniChainValidator{}, err + } + + return OmniChainValidator{ + Address: address, + Power: power, + Pubkey: pkAny, + }, nil +} + +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces. +// It is required to ensure that ConsPubKey below works. +func (ocv OmniChainValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + var pk cryptotypes.PubKey + return unpacker.UnpackAny(ocv.Pubkey, &pk) +} + +// ConsPubKey returns the validator PubKey as a cryptotypes.PubKey. +func (ocv OmniChainValidator) ConsPubKey() (cryptotypes.PubKey, error) { + pk, ok := ocv.Pubkey.GetCachedValue().(cryptotypes.PubKey) + if !ok { + return nil, errorsmod.Wrapf( + sdkerrors.ErrInvalidType, + "expecting cryptotypes.PubKey, got %T", + pk, + ) + } + + return pk, nil +} From eb18ccbb16a60bd6fed056b5956002e9fb6f8df9 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 1 Sep 2024 13:20:11 +0000 Subject: [PATCH 31/52] fix: unnecessary parent code import --- types/chain_id.go | 8 +++----- types/errors.go | 13 +++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 types/errors.go diff --git a/types/chain_id.go b/types/chain_id.go index f4cb91d36..e8bf2b4c0 100644 --- a/types/chain_id.go +++ b/types/chain_id.go @@ -7,8 +7,6 @@ import ( "strings" errorsmod "cosmossdk.io/errors" - - "github.com/evmos/evmos/v14/types" ) var ( @@ -39,18 +37,18 @@ func IsValidChainID(chainID string) bool { func ParseChainID(chainID string) (*big.Int, error) { chainID = strings.TrimSpace(chainID) if len(chainID) > 48 { - return nil, errorsmod.Wrapf(types.ErrInvalidChainID, "chain-id '%s' cannot exceed 48 chars", chainID) + return nil, errorsmod.Wrapf(ErrInvalidChainID, "chain-id '%s' cannot exceed 48 chars", chainID) } matches := evmosChainID.FindStringSubmatch(chainID) if matches == nil || len(matches) != 4 || matches[1] == "" { - return nil, errorsmod.Wrapf(types.ErrInvalidChainID, "%s: %v", chainID, matches) + return nil, errorsmod.Wrapf(ErrInvalidChainID, "%s: %v", chainID, matches) } // verify that the chain-id entered is a base 10 integer chainIDInt, ok := new(big.Int).SetString(matches[2], 10) if !ok { - return nil, errorsmod.Wrapf(types.ErrInvalidChainID, "epoch %s must be base-10 integer format", matches[2]) + return nil, errorsmod.Wrapf(ErrInvalidChainID, "epoch %s must be base-10 integer format", matches[2]) } return chainIDInt, nil diff --git a/types/errors.go b/types/errors.go new file mode 100644 index 000000000..e993de29d --- /dev/null +++ b/types/errors.go @@ -0,0 +1,13 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" +) + +// RootCodespace is the codespace for all errors defined in this package +const RootCodespace = "exocore" + +// ErrInvalidChainID returns an error resulting from an invalid chain ID. +var ErrInvalidChainID = errorsmod.Register( + RootCodespace, 3, "invalid chain ID", +) From f99dbca0bed18e368d08557485b97feb6792b677 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 1 Sep 2024 13:24:01 +0000 Subject: [PATCH 32/52] fix: remove double proto warning The `types` package is imported from our parent codebase and importing it creates a weird packaging issue. Instead, we import the two newly created files into their own subpackage --- testutil/tx/signer.go | 6 +++--- types/{ => keys}/consensus_key.go | 2 +- types/{ => keys}/consensus_key_test.go | 4 ++-- utils/utils.go | 8 ++++---- x/appchain/coordinator/types/expected_keepers.go | 2 +- x/appchain/subscriber/keeper/validators.go | 2 +- x/dogfood/keeper/abci.go | 2 +- x/dogfood/keeper/genesis.go | 2 +- x/dogfood/keeper/impl_delegation_hooks.go | 2 +- x/dogfood/keeper/impl_epochs_hooks_test.go | 2 +- x/dogfood/keeper/impl_operator_hooks.go | 2 +- x/dogfood/keeper/opt_out_test.go | 2 +- x/dogfood/keeper/validators.go | 2 +- x/dogfood/types/expected_keepers.go | 2 +- x/dogfood/types/genesis.go | 2 +- x/operator/keeper/consensus_keys.go | 2 +- x/operator/keeper/grpc_query.go | 2 +- x/operator/keeper/msg_server.go | 2 +- x/operator/keeper/opt.go | 2 +- x/operator/types/expected_keepers.go | 2 +- x/operator/types/hooks.go | 2 +- x/operator/types/msg.go | 2 +- 22 files changed, 28 insertions(+), 28 deletions(-) rename types/{ => keys}/consensus_key.go (99%) rename types/{ => keys}/consensus_key_test.go (97%) diff --git a/testutil/tx/signer.go b/testutil/tx/signer.go index fcb545019..4b3fa4d31 100644 --- a/testutil/tx/signer.go +++ b/testutil/tx/signer.go @@ -3,7 +3,7 @@ package tx import ( "fmt" - "github.com/ExocoreNetwork/exocore/types" + "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -43,13 +43,13 @@ func GenerateAddress() common.Address { } // GenerateConsensusKey generates a consensus key. -func GenerateConsensusKey() types.WrappedConsKey { +func GenerateConsensusKey() keys.WrappedConsKey { privVal := mock.NewPV() pubKey, err := privVal.GetPubKey() if err != nil { return nil } - return types.NewWrappedConsKeyFromHex(hexutil.Encode(pubKey.Bytes())) + return keys.NewWrappedConsKeyFromHex(hexutil.Encode(pubKey.Bytes())) } var _ keyring.Signer = &Signer{} diff --git a/types/consensus_key.go b/types/keys/consensus_key.go similarity index 99% rename from types/consensus_key.go rename to types/keys/consensus_key.go index bd731ed9e..28d18b050 100644 --- a/types/consensus_key.go +++ b/types/keys/consensus_key.go @@ -1,4 +1,4 @@ -package types +package keys import ( "encoding/base64" diff --git a/types/consensus_key_test.go b/types/keys/consensus_key_test.go similarity index 97% rename from types/consensus_key_test.go rename to types/keys/consensus_key_test.go index 1eb0ad8d1..fcb8027aa 100644 --- a/types/consensus_key_test.go +++ b/types/keys/consensus_key_test.go @@ -1,9 +1,9 @@ -package types_test +package keys_test import ( "testing" - "github.com/ExocoreNetwork/exocore/types" + types "github.com/ExocoreNetwork/exocore/types/keys" "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cometbft/cometbft/crypto/secp256k1" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" diff --git a/utils/utils.go b/utils/utils.go index 9def1b3bc..1cd30536d 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,7 +5,7 @@ import ( "sort" "strings" - "github.com/ExocoreNetwork/exocore/types" + "github.com/ExocoreNetwork/exocore/types/keys" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" @@ -122,9 +122,9 @@ func IsSupportedKey(pubkey cryptotypes.PubKey) bool { // the bytes. func SortByPower( operatorAddrs []sdk.AccAddress, - pubKeys []types.WrappedConsKey, + pubKeys []keys.WrappedConsKey, powers []int64, -) ([]sdk.AccAddress, []types.WrappedConsKey, []int64) { +) ([]sdk.AccAddress, []keys.WrappedConsKey, []int64) { // Create a slice of indices indices := make([]int, len(powers)) for i := range indices { @@ -144,7 +144,7 @@ func SortByPower( // Reorder all slices using the sorted indices sortedOperatorAddrs := make([]sdk.AccAddress, len(operatorAddrs)) - sortedPubKeys := make([]types.WrappedConsKey, len(pubKeys)) + sortedPubKeys := make([]keys.WrappedConsKey, len(pubKeys)) sortedPowers := make([]int64, len(powers)) for i, idx := range indices { sortedOperatorAddrs[i] = operatorAddrs[idx] diff --git a/x/appchain/coordinator/types/expected_keepers.go b/x/appchain/coordinator/types/expected_keepers.go index dba2d1e25..4f2ae94be 100644 --- a/x/appchain/coordinator/types/expected_keepers.go +++ b/x/appchain/coordinator/types/expected_keepers.go @@ -3,7 +3,7 @@ package types import ( time "time" - "github.com/ExocoreNetwork/exocore/types" + types "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/appchain/subscriber/keeper/validators.go b/x/appchain/subscriber/keeper/validators.go index 719bbb821..d27e960b2 100644 --- a/x/appchain/subscriber/keeper/validators.go +++ b/x/appchain/subscriber/keeper/validators.go @@ -3,7 +3,7 @@ package keeper import ( "fmt" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" types "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/dogfood/keeper/abci.go b/x/dogfood/keeper/abci.go index e81b0dbf0..4569e7f77 100644 --- a/x/dogfood/keeper/abci.go +++ b/x/dogfood/keeper/abci.go @@ -2,7 +2,7 @@ package keeper import ( "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ExocoreNetwork/exocore/utils" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" abci "github.com/cometbft/cometbft/abci/types" diff --git a/x/dogfood/keeper/genesis.go b/x/dogfood/keeper/genesis.go index 6f523c8ad..a8bcdf9b2 100644 --- a/x/dogfood/keeper/genesis.go +++ b/x/dogfood/keeper/genesis.go @@ -3,7 +3,7 @@ package keeper import ( "fmt" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/dogfood/types" abci "github.com/cometbft/cometbft/abci/types" diff --git a/x/dogfood/keeper/impl_delegation_hooks.go b/x/dogfood/keeper/impl_delegation_hooks.go index 3bbf6574d..7f298ae79 100644 --- a/x/dogfood/keeper/impl_delegation_hooks.go +++ b/x/dogfood/keeper/impl_delegation_hooks.go @@ -3,7 +3,7 @@ package keeper import ( "fmt" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/dogfood/keeper/impl_epochs_hooks_test.go b/x/dogfood/keeper/impl_epochs_hooks_test.go index e2d67cf90..727dc66ec 100644 --- a/x/dogfood/keeper/impl_epochs_hooks_test.go +++ b/x/dogfood/keeper/impl_epochs_hooks_test.go @@ -3,7 +3,7 @@ package keeper_test import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" diff --git a/x/dogfood/keeper/impl_operator_hooks.go b/x/dogfood/keeper/impl_operator_hooks.go index 25c095d2a..2d9532649 100644 --- a/x/dogfood/keeper/impl_operator_hooks.go +++ b/x/dogfood/keeper/impl_operator_hooks.go @@ -1,7 +1,7 @@ package keeper import ( - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/dogfood/keeper/opt_out_test.go b/x/dogfood/keeper/opt_out_test.go index b18e495df..1a2726612 100644 --- a/x/dogfood/keeper/opt_out_test.go +++ b/x/dogfood/keeper/opt_out_test.go @@ -4,7 +4,7 @@ import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" diff --git a/x/dogfood/keeper/validators.go b/x/dogfood/keeper/validators.go index 0cf938643..f8283d101 100644 --- a/x/dogfood/keeper/validators.go +++ b/x/dogfood/keeper/validators.go @@ -5,7 +5,7 @@ import ( "time" "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/dogfood/types" abci "github.com/cometbft/cometbft/abci/types" diff --git a/x/dogfood/types/expected_keepers.go b/x/dogfood/types/expected_keepers.go index 3ae4b1b78..0a27e5a6d 100644 --- a/x/dogfood/types/expected_keepers.go +++ b/x/dogfood/types/expected_keepers.go @@ -2,7 +2,7 @@ package types import ( "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" epochsTypes "github.com/ExocoreNetwork/exocore/x/epochs/types" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" diff --git a/x/dogfood/types/genesis.go b/x/dogfood/types/genesis.go index fe78c285a..bc647aed5 100644 --- a/x/dogfood/types/genesis.go +++ b/x/dogfood/types/genesis.go @@ -3,7 +3,7 @@ package types import ( errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common/hexutil" diff --git a/x/operator/keeper/consensus_keys.go b/x/operator/keeper/consensus_keys.go index b91a9394c..fbc1cedfd 100644 --- a/x/operator/keeper/consensus_keys.go +++ b/x/operator/keeper/consensus_keys.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" diff --git a/x/operator/keeper/grpc_query.go b/x/operator/keeper/grpc_query.go index e4b9cf5b3..b5628960c 100644 --- a/x/operator/keeper/grpc_query.go +++ b/x/operator/keeper/grpc_query.go @@ -6,7 +6,7 @@ import ( assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/operator/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" diff --git a/x/operator/keeper/msg_server.go b/x/operator/keeper/msg_server.go index d2de23d82..b59bf3a9f 100644 --- a/x/operator/keeper/msg_server.go +++ b/x/operator/keeper/msg_server.go @@ -4,7 +4,7 @@ import ( context "context" errorsmod "cosmossdk.io/errors" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/operator/keeper/opt.go b/x/operator/keeper/opt.go index 9d5d1bf02..ac71ebedc 100644 --- a/x/operator/keeper/opt.go +++ b/x/operator/keeper/opt.go @@ -3,7 +3,7 @@ package keeper import ( sdkmath "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/operator/types/expected_keepers.go b/x/operator/types/expected_keepers.go index 4e622cf1f..25cb5aa38 100644 --- a/x/operator/types/expected_keepers.go +++ b/x/operator/types/expected_keepers.go @@ -2,7 +2,7 @@ package types import ( sdkmath "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" delegationkeeper "github.com/ExocoreNetwork/exocore/x/delegation/keeper" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" diff --git a/x/operator/types/hooks.go b/x/operator/types/hooks.go index 5186827ee..6dbf9b0c6 100644 --- a/x/operator/types/hooks.go +++ b/x/operator/types/hooks.go @@ -1,7 +1,7 @@ package types import ( - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/operator/types/msg.go b/x/operator/types/msg.go index c83ad7a07..87735031c 100644 --- a/x/operator/types/msg.go +++ b/x/operator/types/msg.go @@ -2,7 +2,7 @@ package types import ( errorsmod "cosmossdk.io/errors" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" ) From 79833d58cdc9f008aa957d66e0e75a650012410b Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 2 Sep 2024 02:32:15 +0000 Subject: [PATCH 33/52] refactor(operator): carve out AppendMany --- utils/utils.go | 42 +++++++++++++++++++++++++++++ x/operator/keeper/consensus_keys.go | 4 +-- x/operator/keeper/grpc_query.go | 3 ++- x/operator/types/keys.go | 12 ++++----- x/operator/types/utils.go | 11 ++------ 5 files changed, 54 insertions(+), 18 deletions(-) diff --git a/utils/utils.go b/utils/utils.go index 1cd30536d..94dc0fe7c 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/ExocoreNetwork/exocore/types/keys" + abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" @@ -153,3 +154,44 @@ func SortByPower( } return sortedOperatorAddrs, sortedPubKeys, sortedPowers } + +// AccumulateChanges accumulates the current and new validator updates and returns +// a list of unique validator updates. The list is sorted by power in descending order. +func AccumulateChanges( + currentChanges, newChanges []abci.ValidatorUpdate, +) []abci.ValidatorUpdate { + // get only unieque updates + m := make(map[string]abci.ValidatorUpdate) + for i := 0; i < len(currentChanges); i++ { + m[currentChanges[i].PubKey.String()] = currentChanges[i] + } + for i := 0; i < len(newChanges); i++ { + // overwrite with new power + m[newChanges[i].PubKey.String()] = newChanges[i] + } + + // convert to list + var out []abci.ValidatorUpdate + for _, update := range m { + out = append(out, update) + } + + // The list of tendermint updates should hash the same across all consensus nodes + // that means it is necessary to sort for determinism. + sort.Slice(out, func(i, j int) bool { + if out[i].Power != out[j].Power { + return out[i].Power > out[j].Power + } + return out[i].PubKey.String() > out[j].PubKey.String() + }) + + return out +} + +// AppendMany appends a variable number of byte slices together +func AppendMany(byteses ...[]byte) (out []byte) { + for _, bytes := range byteses { + out = append(out, bytes...) + } + return out +} diff --git a/x/operator/keeper/consensus_keys.go b/x/operator/keeper/consensus_keys.go index fbc1cedfd..50818f03b 100644 --- a/x/operator/keeper/consensus_keys.go +++ b/x/operator/keeper/consensus_keys.go @@ -9,9 +9,9 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + "github.com/ExocoreNetwork/exocore/utils" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" - tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" ) @@ -431,7 +431,7 @@ func (k Keeper) ClearPreviousConsensusKeys(ctx sdk.Context, chainID string) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator( store, - types.AppendMany( + utils.AppendMany( []byte{types.BytePrefixForOperatorAndChainIDToPrevConsKey}, partialKey, ), diff --git a/x/operator/keeper/grpc_query.go b/x/operator/keeper/grpc_query.go index b5628960c..5a2c84d41 100644 --- a/x/operator/keeper/grpc_query.go +++ b/x/operator/keeper/grpc_query.go @@ -7,6 +7,7 @@ import ( assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + "github.com/ExocoreNetwork/exocore/utils" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/operator/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" @@ -203,7 +204,7 @@ func (k *Keeper) QueryOperatorSlashInfo(goCtx context.Context, req *types.QueryO ctx := sdk.UnwrapSDKContext(goCtx) res := make([]*types.OperatorSlashInfoByID, 0) - slashPrefix := types.AppendMany(types.KeyPrefixOperatorSlashInfo, assetstype.GetJoinedStoreKeyForPrefix(req.Details.OperatorAddr, req.Details.AVSAddress)) + slashPrefix := utils.AppendMany(types.KeyPrefixOperatorSlashInfo, assetstype.GetJoinedStoreKeyForPrefix(req.Details.OperatorAddr, req.Details.AVSAddress)) store := prefix.NewStore(ctx.KVStore(k.storeKey), slashPrefix) pageRes, err := query.Paginate(store, req.Pagination, func(key []byte, value []byte) error { ret := &types.OperatorSlashInfo{} diff --git a/x/operator/types/keys.go b/x/operator/types/keys.go index 6ce14a873..52c71cb73 100644 --- a/x/operator/types/keys.go +++ b/x/operator/types/keys.go @@ -3,10 +3,10 @@ package types import ( "math" + "github.com/ExocoreNetwork/exocore/utils" + sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/ethereum/go-ethereum/common" - - sdk "github.com/cosmos/cosmos-sdk/types" ) // constants @@ -96,7 +96,7 @@ func init() { func AddrAndChainIDKey(prefix byte, addr sdk.AccAddress, chainID string) []byte { partialKey := ChainIDWithLenKey(chainID) - return AppendMany( + return utils.AppendMany( // Append the prefix []byte{prefix}, // Append the addr bytes first so we can iterate over all chain ids @@ -109,7 +109,7 @@ func AddrAndChainIDKey(prefix byte, addr sdk.AccAddress, chainID string) []byte func ChainIDAndAddrKey(prefix byte, chainID string, addr sdk.AccAddress) []byte { partialKey := ChainIDWithLenKey(chainID) - return AppendMany( + return utils.AppendMany( // Append the prefix []byte{prefix}, // Append the partialKey so that we can look for any operator keys @@ -141,7 +141,7 @@ func KeyForChainIDAndOperatorToConsKey(chainID string, addr sdk.AccAddress) []by } func KeyForChainIDAndConsKeyToOperator(chainID string, addr sdk.ConsAddress) []byte { - return AppendMany( + return utils.AppendMany( []byte{BytePrefixForChainIDAndConsKeyToOperator}, ChainIDWithLenKey(chainID), addr, @@ -149,7 +149,7 @@ func KeyForChainIDAndConsKeyToOperator(chainID string, addr sdk.ConsAddress) []b } func KeyForOperatorKeyRemovalForChainID(addr sdk.AccAddress, chainID string) []byte { - return AppendMany( + return utils.AppendMany( []byte{BytePrefixForOperatorKeyRemovalForChainID}, addr, ChainIDWithLenKey(chainID), ) diff --git a/x/operator/types/utils.go b/x/operator/types/utils.go index 6ec7351a9..38ad58667 100644 --- a/x/operator/types/utils.go +++ b/x/operator/types/utils.go @@ -1,23 +1,16 @@ package types import ( + "github.com/ExocoreNetwork/exocore/utils" sdk "github.com/cosmos/cosmos-sdk/types" ) -// AppendMany appends a variable number of byte slices together -func AppendMany(byteses ...[]byte) (out []byte) { - for _, bytes := range byteses { - out = append(out, bytes...) - } - return out -} - // ChainIDWithLenKey returns the key with the following format: // bytePrefix | len(chainId) | chainId // This is similar to Solidity's ABI encoding. func ChainIDWithLenKey(chainID string) []byte { chainIDL := len(chainID) - return AppendMany( + return utils.AppendMany( // Append the chainID length // #nosec G701 sdk.Uint64ToBigEndian(uint64(chainIDL)), From b12b362b9c5a879a111c99f00249e74ddf89c814 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 2 Sep 2024 02:33:48 +0000 Subject: [PATCH 34/52] feat(appchain): load subscriber genesis, ibc --- proto/exocore/appchain/common/v1/wire.proto | 73 ++ .../appchain/subscriber/v1/genesis.proto | 12 + x/appchain/common/types/errors.go | 32 + x/appchain/common/types/events.go | 9 +- x/appchain/common/types/expected_keepers.go | 44 ++ x/appchain/common/types/keys.go | 12 +- x/appchain/common/types/types.go | 12 + x/appchain/common/types/wire.pb.go | 665 ++++++++++++++++++ x/appchain/coordinator/keeper/connection.go | 164 +++++ x/appchain/coordinator/keeper/distribution.go | 14 + x/appchain/coordinator/keeper/identifiers.go | 32 + x/appchain/coordinator/keeper/keeper.go | 72 +- x/appchain/coordinator/module.go | 2 +- x/appchain/coordinator/module_ibc.go | 307 ++++++++ x/appchain/coordinator/types/errors.go | 28 +- x/appchain/coordinator/types/keys.go | 37 +- x/appchain/subscriber/keeper/connection.go | 63 ++ x/appchain/subscriber/keeper/distribution.go | 29 + x/appchain/subscriber/keeper/ibc_client.go | 21 + x/appchain/subscriber/keeper/keeper.go | 79 ++- x/appchain/subscriber/keeper/params.go | 29 + x/appchain/subscriber/keeper/relay.go | 145 ++++ x/appchain/subscriber/module.go | 2 +- x/appchain/subscriber/module_ibc.go | 375 ++++++++++ x/appchain/subscriber/types/errors.go | 10 + x/appchain/subscriber/types/events.go | 5 + x/appchain/subscriber/types/genesis.pb.go | 266 ++++++- x/appchain/subscriber/types/keys.go | 36 + 28 files changed, 2506 insertions(+), 69 deletions(-) create mode 100644 proto/exocore/appchain/common/v1/wire.proto create mode 100644 x/appchain/common/types/errors.go create mode 100644 x/appchain/common/types/types.go create mode 100644 x/appchain/common/types/wire.pb.go create mode 100644 x/appchain/coordinator/keeper/connection.go create mode 100644 x/appchain/coordinator/keeper/distribution.go create mode 100644 x/appchain/coordinator/module_ibc.go create mode 100644 x/appchain/subscriber/keeper/distribution.go create mode 100644 x/appchain/subscriber/keeper/ibc_client.go create mode 100644 x/appchain/subscriber/keeper/relay.go create mode 100644 x/appchain/subscriber/module_ibc.go create mode 100644 x/appchain/subscriber/types/errors.go create mode 100644 x/appchain/subscriber/types/events.go diff --git a/proto/exocore/appchain/common/v1/wire.proto b/proto/exocore/appchain/common/v1/wire.proto new file mode 100644 index 000000000..991a3650f --- /dev/null +++ b/proto/exocore/appchain/common/v1/wire.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + +package exocore.appchain.common.v1; + +import "cosmos/staking/v1beta1/staking.proto"; +import "gogoproto/gogo.proto"; +import "tendermint/abci/types.proto"; + +option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/common/types"; + +// This file containts all of the information that is sent over the wire by either +// the coordinator or each of the subcribers. + +message HandshakeMetadata { + // This address is where the subscriber chain will send the fees proportionally + string coordinator_fee_pool_addr = 1; + string version = 2; +} + +// // This packet is sent from the subscriber chain to the coordinator chain +// // to request the slashing of a validator as a result of an infraction +// // committed on the subscriber chain. +// message SlashPacketData { +// tendermint.abci.Validator validator = 1 [ +// (gogoproto.nullable) = false, +// (gogoproto.moretags) = "yaml:\"validator\"" +// ]; +// // map to the infraction block height on the coordinator +// uint64 valset_update_id = 2; +// // tell if the slashing is for a downtime or a double-signing infraction +// cosmos.staking.v1beta1.Infraction infraction = 3; +// } + +// // This packet is sent from subsciber to coordinator to indicate that the validator set change +// // with the specified id has matured on the subscriber chain. This is used to know when to +// // prune some information on the coordinator. +// message VscMaturedPacketData { +// uint64 valset_update_id = 1; +// } + +// // Type of SubscriberPacketData +// enum SubscriberPacketDataType { +// option (gogoproto.goproto_enum_prefix) = false; + +// SUBSCRIBER_PACKET_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "UnspecifiedPacket" ]; +// SUBSCRIBER_PACKET_TYPE_SLASH = 1 [ (gogoproto.enumvalue_customname) = "SlashPacket" ]; +// SUBSCRIBER_PACKET_TYPE_VSC_MATURED = 2 [ (gogoproto.enumvalue_customname) = "VscMaturedPacket" ];; +// } + +// // Overall packet +// message SubscriberPacketData { +// SubscriberPacketDataType type = 1; + +// oneof data { +// SlashPacketData slashPacketData = 2; +// VscMaturedPacketData vscMaturedPacketData = 3; +// } +// } + +// ValidatorSetChangePacketData is sent from the coordinator chain to the subscriber chain +// containing the new validator set and the id of the validator set change. +message ValidatorSetChangePacketData { + // validator_updates is the edits to the existing validator set + repeated .tendermint.abci.ValidatorUpdate validator_updates = 1 [ + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"validator_updates\"" + ]; + // valset_update_id is the id of the validator set change + uint64 valset_update_id = 2 [(gogoproto.customname) = "ValsetUpdateID"]; + // slash_acks is the list of consensus addresses slashed on the coordinator chain, + // in response to such requests from the subscriber chain. + repeated string slash_acks = 3; +} \ No newline at end of file diff --git a/proto/exocore/appchain/subscriber/v1/genesis.proto b/proto/exocore/appchain/subscriber/v1/genesis.proto index 00c1c8c38..cb7fd887b 100644 --- a/proto/exocore/appchain/subscriber/v1/genesis.proto +++ b/proto/exocore/appchain/subscriber/v1/genesis.proto @@ -4,6 +4,7 @@ package exocore.appchain.subscriber.v1; import "exocore/appchain/common/v1/common.proto"; import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; @@ -22,3 +23,14 @@ message GenesisState { string coordinator_channel_id = 4 [ (gogoproto.customname) = "CoordinatorChannelID" ]; // operational parameters that are to be exported can go here. } + +// MaturingVSCPacket represents a vsc packet that is maturing internal to the +// subscriber module, where it has not yet relayed a VSCMatured packet back. +// While it is technically feasible to store this just as a key in the state, +// keeping it as a separate type allows exporting the genesis data. +// The key used is prefix + time + vscId. +message MaturingVSCPacket { + uint64 vscId = 1 [ (gogoproto.customname) = "ID" ]; + google.protobuf.Timestamp maturity_time = 2 + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; +} \ No newline at end of file diff --git a/x/appchain/common/types/errors.go b/x/appchain/common/types/errors.go new file mode 100644 index 000000000..feb9e4e65 --- /dev/null +++ b/x/appchain/common/types/errors.go @@ -0,0 +1,32 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" +) + +var ( + ErrInvalidChannelFlow = errorsmod.Register( + ModuleName, 2, + "invalid message sent to channel end", + ) + ErrDuplicateChannel = errorsmod.Register( + ModuleName, 3, + "channel already exists", + ) + ErrInvalidVersion = errorsmod.Register( + ModuleName, 4, + "invalid version", + ) + ErrInvalidHandshakeMetadata = errorsmod.Register( + ModuleName, 5, + "invalid handshake metadata", + ) + ErrChannelNotFound = errorsmod.Register( + ModuleName, 6, + "channel not found", + ) + ErrClientNotFound = errorsmod.Register( + ModuleName, 7, + "client not found", + ) +) diff --git a/x/appchain/common/types/events.go b/x/appchain/common/types/events.go index 5d8899972..5f2bcbd49 100644 --- a/x/appchain/common/types/events.go +++ b/x/appchain/common/types/events.go @@ -1,5 +1,12 @@ package types const ( - AttributeChainID = "chain_id" + AttributeChainID = "chain_id" + AttributeKeyAckSuccess = "success" + AttributeKeyAck = "acknowledgement" + AttributeKeyAckError = "ack_error" + + EventTypeChannelEstablished = "channel_established" + EventTypePacket = "common_packet" + EventTypeTimeout = "common_timeout" ) diff --git a/x/appchain/common/types/expected_keepers.go b/x/appchain/common/types/expected_keepers.go index dde8f9acf..a677c2335 100644 --- a/x/appchain/common/types/expected_keepers.go +++ b/x/appchain/common/types/expected_keepers.go @@ -1,11 +1,18 @@ package types import ( + "context" + sdk "github.com/cosmos/cosmos-sdk/types" + auth "github.com/cosmos/cosmos-sdk/x/auth/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) +// ClientKeeper defines the expected IBC client keeper type ClientKeeper interface { CreateClient( sdk.Context, ibcexported.ClientState, ibcexported.ConsensusState, @@ -30,3 +37,40 @@ type ScopedKeeper interface { type PortKeeper interface { BindPort(ctx sdk.Context, portID string) *capabilitytypes.Capability } + +// ConnectionKeeper defines the expected IBC connection keeper +type ConnectionKeeper interface { + GetConnection(ctx sdk.Context, connectionID string) (conntypes.ConnectionEnd, bool) +} + +// ChannelKeeper defines the expected IBC channel keeper +type ChannelKeeper interface { + GetChannel(sdk.Context, string, string) (channeltypes.Channel, bool) + GetNextSequenceSend(sdk.Context, string, string) (uint64, bool) + SendPacket( + sdk.Context, *capabilitytypes.Capability, + string, string, clienttypes.Height, + uint64, []byte, + ) (uint64, error) + WriteAcknowledgement( + sdk.Context, *capabilitytypes.Capability, + ibcexported.PacketI, ibcexported.Acknowledgement, + ) error + ChanCloseInit( + sdk.Context, string, string, *capabilitytypes.Capability, + ) error + GetChannelConnection(sdk.Context, string, string) (string, ibcexported.ConnectionI, error) +} + +// IBCKeeper defines the expected interface needed for openning a +// channel +type IBCCoreKeeper interface { + ChannelOpenInit( + context.Context, *channeltypes.MsgChannelOpenInit, + ) (*channeltypes.MsgChannelOpenInitResponse, error) +} + +// AccountKeeper defines the expected account keeper +type AccountKeeper interface { + GetModuleAccount(ctx sdk.Context, name string) auth.ModuleAccountI +} diff --git a/x/appchain/common/types/keys.go b/x/appchain/common/types/keys.go index cd5bc687a..de754c673 100644 --- a/x/appchain/common/types/keys.go +++ b/x/appchain/common/types/keys.go @@ -1,6 +1,16 @@ package types const ( - // SubscriberPortID is the port id for the subscriber module. + // ModuleName is the name of the module + ModuleName = "appchain" + // Version is the current version of the module + Version = ModuleName + "-1" + // CoordinatorPortID is the default port id to which the coordinator module binds + CoordinatorPortID = "coordinator" + // SubscriberPortID is the default port id to which the subscriber module binds SubscriberPortID = "subscriber" + // StoreKey defines the store key for the module (used in tests) + StoreKey = ModuleName + // MemStoreKey defines the in-memory store key (used in tests) + MemStoreKey = "mem_appchain" ) diff --git a/x/appchain/common/types/types.go b/x/appchain/common/types/types.go new file mode 100644 index 000000000..025040981 --- /dev/null +++ b/x/appchain/common/types/types.go @@ -0,0 +1,12 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" +) + +// NewErrorAcknowledgementWithLog creates an error acknowledgement with a log message. +func NewErrorAcknowledgementWithLog(ctx sdk.Context, err error) channeltypes.Acknowledgement { + ctx.Logger().Error("IBC ErrorAcknowledgement constructed", "error", err) + return channeltypes.NewErrorAcknowledgement(err) +} diff --git a/x/appchain/common/types/wire.pb.go b/x/appchain/common/types/wire.pb.go new file mode 100644 index 000000000..ac0580928 --- /dev/null +++ b/x/appchain/common/types/wire.pb.go @@ -0,0 +1,665 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exocore/appchain/common/v1/wire.proto + +package types + +import ( + fmt "fmt" + types "github.com/cometbft/cometbft/abci/types" + _ "github.com/cosmos/cosmos-sdk/x/staking/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type HandshakeMetadata struct { + // This address is where the subscriber chain will send the fees proportionally + CoordinatorFeePoolAddr string `protobuf:"bytes,1,opt,name=coordinator_fee_pool_addr,json=coordinatorFeePoolAddr,proto3" json:"coordinator_fee_pool_addr,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` +} + +func (m *HandshakeMetadata) Reset() { *m = HandshakeMetadata{} } +func (m *HandshakeMetadata) String() string { return proto.CompactTextString(m) } +func (*HandshakeMetadata) ProtoMessage() {} +func (*HandshakeMetadata) Descriptor() ([]byte, []int) { + return fileDescriptor_646142158918d547, []int{0} +} +func (m *HandshakeMetadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HandshakeMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HandshakeMetadata.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HandshakeMetadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_HandshakeMetadata.Merge(m, src) +} +func (m *HandshakeMetadata) XXX_Size() int { + return m.Size() +} +func (m *HandshakeMetadata) XXX_DiscardUnknown() { + xxx_messageInfo_HandshakeMetadata.DiscardUnknown(m) +} + +var xxx_messageInfo_HandshakeMetadata proto.InternalMessageInfo + +func (m *HandshakeMetadata) GetCoordinatorFeePoolAddr() string { + if m != nil { + return m.CoordinatorFeePoolAddr + } + return "" +} + +func (m *HandshakeMetadata) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +// ValidatorSetChangePacketData is sent from the coordinator chain to the subscriber chain +// containing the new validator set and the id of the validator set change. +type ValidatorSetChangePacketData struct { + // validator_updates is the edits to the existing validator set + ValidatorUpdates []types.ValidatorUpdate `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates" yaml:"validator_updates"` + // valset_update_id is the id of the validator set change + ValsetUpdateID uint64 `protobuf:"varint,2,opt,name=valset_update_id,json=valsetUpdateId,proto3" json:"valset_update_id,omitempty"` + // slash_acks is the list of consensus addresses slashed on the coordinator chain, + // in response to such requests from the subscriber chain. + SlashAcks []string `protobuf:"bytes,3,rep,name=slash_acks,json=slashAcks,proto3" json:"slash_acks,omitempty"` +} + +func (m *ValidatorSetChangePacketData) Reset() { *m = ValidatorSetChangePacketData{} } +func (m *ValidatorSetChangePacketData) String() string { return proto.CompactTextString(m) } +func (*ValidatorSetChangePacketData) ProtoMessage() {} +func (*ValidatorSetChangePacketData) Descriptor() ([]byte, []int) { + return fileDescriptor_646142158918d547, []int{1} +} +func (m *ValidatorSetChangePacketData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatorSetChangePacketData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ValidatorSetChangePacketData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ValidatorSetChangePacketData) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatorSetChangePacketData.Merge(m, src) +} +func (m *ValidatorSetChangePacketData) XXX_Size() int { + return m.Size() +} +func (m *ValidatorSetChangePacketData) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatorSetChangePacketData.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatorSetChangePacketData proto.InternalMessageInfo + +func (m *ValidatorSetChangePacketData) GetValidatorUpdates() []types.ValidatorUpdate { + if m != nil { + return m.ValidatorUpdates + } + return nil +} + +func (m *ValidatorSetChangePacketData) GetValsetUpdateID() uint64 { + if m != nil { + return m.ValsetUpdateID + } + return 0 +} + +func (m *ValidatorSetChangePacketData) GetSlashAcks() []string { + if m != nil { + return m.SlashAcks + } + return nil +} + +func init() { + proto.RegisterType((*HandshakeMetadata)(nil), "exocore.appchain.common.v1.HandshakeMetadata") + proto.RegisterType((*ValidatorSetChangePacketData)(nil), "exocore.appchain.common.v1.ValidatorSetChangePacketData") +} + +func init() { + proto.RegisterFile("exocore/appchain/common/v1/wire.proto", fileDescriptor_646142158918d547) +} + +var fileDescriptor_646142158918d547 = []byte{ + // 420 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0x4f, 0x6f, 0xd3, 0x4c, + 0x10, 0xc6, 0xe3, 0x37, 0xaf, 0x40, 0x59, 0xa4, 0x8a, 0x5a, 0x08, 0x99, 0x00, 0x8e, 0x15, 0x81, + 0x94, 0x93, 0x57, 0x81, 0x53, 0x11, 0x97, 0x86, 0x82, 0xe0, 0x00, 0xaa, 0x52, 0xd1, 0x03, 0x17, + 0x6b, 0xb2, 0x3b, 0xd8, 0x2b, 0xdb, 0x3b, 0xd6, 0xee, 0xd6, 0x6d, 0xbf, 0x05, 0x1f, 0xab, 0xc7, + 0x1e, 0x39, 0x45, 0x28, 0xb9, 0x72, 0xe2, 0x13, 0x20, 0xdb, 0x31, 0x14, 0xf5, 0x36, 0x7f, 0x7e, + 0xf3, 0xec, 0x8e, 0x9e, 0x61, 0xcf, 0xf1, 0x82, 0x04, 0x19, 0xe4, 0x50, 0x55, 0x22, 0x03, 0xa5, + 0xb9, 0xa0, 0xb2, 0x24, 0xcd, 0xeb, 0x39, 0x3f, 0x57, 0x06, 0xe3, 0xca, 0x90, 0x23, 0x7f, 0xbc, + 0xc3, 0xe2, 0x1e, 0x8b, 0x3b, 0x2c, 0xae, 0xe7, 0xe3, 0x67, 0x82, 0x6c, 0x49, 0x96, 0x5b, 0x07, + 0xb9, 0xd2, 0x29, 0xaf, 0xe7, 0x2b, 0x74, 0x30, 0xef, 0xf3, 0x4e, 0x61, 0xfc, 0x20, 0xa5, 0x94, + 0xda, 0x90, 0x37, 0xd1, 0xae, 0xfa, 0xd8, 0xa1, 0x96, 0x68, 0x4a, 0xa5, 0x1d, 0x87, 0x95, 0x50, + 0xdc, 0x5d, 0x56, 0x68, 0xbb, 0xe6, 0x34, 0x63, 0xfb, 0xef, 0x41, 0x4b, 0x9b, 0x41, 0x8e, 0x1f, + 0xd1, 0x81, 0x04, 0x07, 0xfe, 0x01, 0x7b, 0x24, 0x88, 0x8c, 0x54, 0x1a, 0x1c, 0x99, 0xe4, 0x2b, + 0x62, 0x52, 0x11, 0x15, 0x09, 0x48, 0x69, 0x02, 0x2f, 0xf2, 0x66, 0xa3, 0xe5, 0xc3, 0x1b, 0xc0, + 0x3b, 0xc4, 0x63, 0xa2, 0xe2, 0x50, 0x4a, 0xe3, 0x07, 0xec, 0x6e, 0x8d, 0xc6, 0x2a, 0xd2, 0xc1, + 0x7f, 0x2d, 0xd8, 0xa7, 0xd3, 0x9f, 0x1e, 0x7b, 0x72, 0x0a, 0x85, 0x92, 0xcd, 0xc8, 0x09, 0xba, + 0x37, 0x19, 0xe8, 0x14, 0x8f, 0x41, 0xe4, 0xe8, 0x8e, 0x9a, 0x57, 0x89, 0xed, 0xd7, 0x7d, 0x3f, + 0x39, 0xab, 0x24, 0x38, 0xb4, 0x81, 0x17, 0x0d, 0x67, 0xf7, 0x5e, 0x44, 0xf1, 0xdf, 0x1d, 0xe2, + 0x66, 0x87, 0xf8, 0x8f, 0xd2, 0xe7, 0x16, 0x5c, 0x44, 0x57, 0xeb, 0xc9, 0xe0, 0xd7, 0x7a, 0x12, + 0x5c, 0x42, 0x59, 0xbc, 0x9a, 0xde, 0x12, 0x9a, 0x2e, 0xef, 0xd7, 0xff, 0x8e, 0x58, 0xff, 0x35, + 0x6b, 0x6a, 0x16, 0xdd, 0x0e, 0x4a, 0x94, 0x6c, 0x3f, 0xfd, 0xff, 0xc2, 0xdf, 0xac, 0x27, 0x7b, + 0xa7, 0x6d, 0xaf, 0x83, 0x3f, 0x1c, 0x2d, 0xf7, 0xea, 0x9b, 0xb9, 0xf4, 0x9f, 0x32, 0x66, 0x0b, + 0xb0, 0x59, 0x02, 0x22, 0xb7, 0xc1, 0x30, 0x1a, 0xce, 0x46, 0xcb, 0x51, 0x5b, 0x39, 0x14, 0xb9, + 0x5d, 0x9c, 0x5c, 0x6d, 0x42, 0xef, 0x7a, 0x13, 0x7a, 0x3f, 0x36, 0xa1, 0xf7, 0x6d, 0x1b, 0x0e, + 0xae, 0xb7, 0xe1, 0xe0, 0xfb, 0x36, 0x1c, 0x7c, 0x39, 0x48, 0x95, 0xcb, 0xce, 0x56, 0x8d, 0xbb, + 0xfc, 0x6d, 0x67, 0xf9, 0x27, 0x74, 0xe7, 0x64, 0x72, 0xde, 0x1f, 0xca, 0xc5, 0xad, 0x53, 0x69, + 0x3d, 0x5b, 0xdd, 0x69, 0x4d, 0x7b, 0xf9, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x29, 0x74, 0xa9, 0x8a, + 0x52, 0x02, 0x00, 0x00, +} + +func (m *HandshakeMetadata) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HandshakeMetadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HandshakeMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintWire(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x12 + } + if len(m.CoordinatorFeePoolAddr) > 0 { + i -= len(m.CoordinatorFeePoolAddr) + copy(dAtA[i:], m.CoordinatorFeePoolAddr) + i = encodeVarintWire(dAtA, i, uint64(len(m.CoordinatorFeePoolAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ValidatorSetChangePacketData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatorSetChangePacketData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatorSetChangePacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SlashAcks) > 0 { + for iNdEx := len(m.SlashAcks) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SlashAcks[iNdEx]) + copy(dAtA[i:], m.SlashAcks[iNdEx]) + i = encodeVarintWire(dAtA, i, uint64(len(m.SlashAcks[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if m.ValsetUpdateID != 0 { + i = encodeVarintWire(dAtA, i, uint64(m.ValsetUpdateID)) + i-- + dAtA[i] = 0x10 + } + if len(m.ValidatorUpdates) > 0 { + for iNdEx := len(m.ValidatorUpdates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ValidatorUpdates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWire(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintWire(dAtA []byte, offset int, v uint64) int { + offset -= sovWire(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *HandshakeMetadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.CoordinatorFeePoolAddr) + if l > 0 { + n += 1 + l + sovWire(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovWire(uint64(l)) + } + return n +} + +func (m *ValidatorSetChangePacketData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ValidatorUpdates) > 0 { + for _, e := range m.ValidatorUpdates { + l = e.Size() + n += 1 + l + sovWire(uint64(l)) + } + } + if m.ValsetUpdateID != 0 { + n += 1 + sovWire(uint64(m.ValsetUpdateID)) + } + if len(m.SlashAcks) > 0 { + for _, s := range m.SlashAcks { + l = len(s) + n += 1 + l + sovWire(uint64(l)) + } + } + return n +} + +func sovWire(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozWire(x uint64) (n int) { + return sovWire(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *HandshakeMetadata) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HandshakeMetadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HandshakeMetadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CoordinatorFeePoolAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthWire + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWire + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CoordinatorFeePoolAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthWire + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWire + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWire(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWire + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatorSetChangePacketData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatorSetChangePacketData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatorSetChangePacketData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorUpdates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWire + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWire + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorUpdates = append(m.ValidatorUpdates, types.ValidatorUpdate{}) + if err := m.ValidatorUpdates[len(m.ValidatorUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValsetUpdateID", wireType) + } + m.ValsetUpdateID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValsetUpdateID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashAcks", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthWire + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWire + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SlashAcks = append(m.SlashAcks, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWire(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWire + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipWire(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWire + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWire + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWire + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthWire + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupWire + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthWire + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthWire = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowWire = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupWire = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/appchain/coordinator/keeper/connection.go b/x/appchain/coordinator/keeper/connection.go new file mode 100644 index 000000000..e8a4668a5 --- /dev/null +++ b/x/appchain/coordinator/keeper/connection.go @@ -0,0 +1,164 @@ +package keeper + +import ( + "encoding/binary" + + errorsmod "cosmossdk.io/errors" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + subscribertypes "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" +) + +// VerifySubscriberChain verifies the chain trying to connect on the channel handshake. +// The verification includes the number of connection hops, the presence of a light client, +// as well as the channel's presence. +func (k Keeper) VerifySubscriberChain( + ctx sdk.Context, + channelID string, + connectionHops []string, +) error { + if len(connectionHops) != 1 { + return errorsmod.Wrap( + channeltypes.ErrTooManyConnectionHops, + "must have direct connection to coordinator chain", + ) + } + connectionID := connectionHops[0] + clientID, tmClient, err := k.getUnderlyingClient(ctx, connectionID) + if err != nil { + return err + } + storedClientID, found := k.GetClientForChain(ctx, tmClient.ChainId) + if !found { + return errorsmod.Wrapf( + commontypes.ErrClientNotFound, + "cannot find client for subscriber chain %s", + tmClient.ChainId, + ) + } + if storedClientID != clientID { + return errorsmod.Wrapf( + types.ErrInvalidSubscriberClient, + "channel must be built on top of client. expected %s, got %s", + storedClientID, clientID, + ) + } + + // Verify that there isn't already a stored channel + if prevChannel, ok := k.GetChannelForChain(ctx, tmClient.ChainId); ok { + return errorsmod.Wrapf( + commontypes.ErrDuplicateChannel, + "channel with ID: %s already created for subscriber chain %s", + prevChannel, tmClient.ChainId, + ) + } + return nil +} + +// getUnderlyingClient gets the client state of the subscriber chain, +// as deployed on the coordinator chain. +func (k Keeper) getUnderlyingClient(ctx sdk.Context, connectionID string) ( + clientID string, tmClient *ibctmtypes.ClientState, err error, +) { + conn, ok := k.connectionKeeper.GetConnection(ctx, connectionID) + if !ok { + return "", nil, errorsmod.Wrapf(conntypes.ErrConnectionNotFound, + "connection not found for connection ID: %s", connectionID) + } + clientID = conn.ClientId + clientState, ok := k.clientKeeper.GetClientState(ctx, clientID) + if !ok { + return "", nil, errorsmod.Wrapf(clienttypes.ErrClientNotFound, + "client not found for client ID: %s", clientID) + } + tmClient, ok = clientState.(*ibctmtypes.ClientState) + if !ok { + return "", nil, errorsmod.Wrapf( + clienttypes.ErrInvalidClientType, + "invalid client type. expected %s, got %s", + ibchost.Tendermint, + clientState.ClientType(), + ) + } + return clientID, tmClient, nil +} + +// SetSubscriberChain sets the subscriber chain for the given channel ID. +// It is called when the connection handshake is complete. +func (k Keeper) SetSubscriberChain(ctx sdk.Context, channelID string) error { + channel, ok := k.channelKeeper.GetChannel(ctx, commontypes.CoordinatorPortID, channelID) + if !ok { + return errorsmod.Wrapf( + channeltypes.ErrChannelNotFound, + "channel not found for channel ID: %s", channelID, + ) + } + if len(channel.ConnectionHops) != 1 { + return errorsmod.Wrap( + channeltypes.ErrTooManyConnectionHops, + "must have direct connection to subscriber chain", + ) + } + connectionID := channel.ConnectionHops[0] + clientID, tmClient, err := k.getUnderlyingClient(ctx, connectionID) + if err != nil { + return err + } + // Verify that there isn't already a channel for the subscriber chain + chainID := tmClient.ChainId + if prevChannelID, ok := k.GetChannelForChain(ctx, chainID); ok { + return errorsmod.Wrapf( + commontypes.ErrDuplicateChannel, + "channel with Id: %s already created for subscriber chain %s", + prevChannelID, chainID, + ) + } + + // the channel is established: + // - set channel mappings + k.SetChannelForChain(ctx, chainID, channelID) + k.SetChainForChannel(ctx, channelID, chainID) + // - set current block height for the subscriber chain initialization + k.SetInitChainHeight(ctx, chainID, uint64(ctx.BlockHeight())) + // remove init timeout timestamp + k.DeleteInitTimeoutTimestamp(ctx, chainID) + + // emit event on successful addition + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypeChannelEstablished, + sdk.NewAttribute(sdk.AttributeKeyModule, subscribertypes.ModuleName), + sdk.NewAttribute(commontypes.AttributeChainID, chainID), + sdk.NewAttribute(conntypes.AttributeKeyClientID, clientID), + sdk.NewAttribute(channeltypes.AttributeKeyChannelID, channelID), + sdk.NewAttribute(conntypes.AttributeKeyConnectionID, connectionID), + ), + ) + return nil +} + +// SetInitChainHeight sets the Exocore block height when the given app chain was initiated +func (k Keeper) SetInitChainHeight(ctx sdk.Context, chainID string, height uint64) { + store := ctx.KVStore(k.storeKey) + heightBytes := make([]byte, 8) + binary.BigEndian.PutUint64(heightBytes, height) + + store.Set(types.InitChainHeightKey(chainID), heightBytes) +} + +// GetInitChainHeight returns the Exocore block height when the given app chain was initiated +func (k Keeper) GetInitChainHeight(ctx sdk.Context, chainID string) (uint64, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.InitChainHeightKey(chainID)) + if bz == nil { + return 0, false + } + + return binary.BigEndian.Uint64(bz), true +} diff --git a/x/appchain/coordinator/keeper/distribution.go b/x/appchain/coordinator/keeper/distribution.go new file mode 100644 index 000000000..699139d39 --- /dev/null +++ b/x/appchain/coordinator/keeper/distribution.go @@ -0,0 +1,14 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// GetSubscriberRewardsPoolAddressStr gets the subscriber rewards pool address string. +// It is the bech32 string corresponding to a hardcoded module account. +func (k Keeper) GetSubscriberRewardsPoolAddressStr(ctx sdk.Context) string { + return k.accountKeeper.GetModuleAccount( + ctx, types.SubscriberRewardsPool, + ).GetAddress().String() +} diff --git a/x/appchain/coordinator/keeper/identifiers.go b/x/appchain/coordinator/keeper/identifiers.go index 63b8b3353..6cb1c2b5a 100644 --- a/x/appchain/coordinator/keeper/identifiers.go +++ b/x/appchain/coordinator/keeper/identifiers.go @@ -30,3 +30,35 @@ func (k Keeper) DeleteClientForChain(ctx sdk.Context, chainID string) { store := ctx.KVStore(k.storeKey) store.Delete(types.ClientForChainKey(chainID)) } + +// SetChannelForChain sets the ibc channel id for a given chain id. +func (k Keeper) SetChannelForChain(ctx sdk.Context, chainID string, channelID string) { + store := ctx.KVStore(k.storeKey) + store.Set(types.ChannelForChainKey(chainID), []byte(channelID)) +} + +// GetChannelForChain gets the ibc channel id for a given chain id. +func (k Keeper) GetChannelForChain(ctx sdk.Context, chainID string) (string, bool) { + store := ctx.KVStore(k.storeKey) + bytes := store.Get(types.ChannelForChainKey(chainID)) + if bytes == nil { + return "", false + } + return string(bytes), true +} + +// SetChainForChannel sets the chain id for a given channel id. +func (k Keeper) SetChainForChannel(ctx sdk.Context, channelID string, chainID string) { + store := ctx.KVStore(k.storeKey) + store.Set(types.ChainForChannelKey(channelID), []byte(chainID)) +} + +// GetChainForChannel gets the chain id for a given channel id. +func (k Keeper) GetChainForChannel(ctx sdk.Context, channelID string) (string, bool) { + store := ctx.KVStore(k.storeKey) + bytes := store.Get(types.ChainForChannelKey(channelID)) + if bytes == nil { + return "", false + } + return string(bytes), true +} diff --git a/x/appchain/coordinator/keeper/keeper.go b/x/appchain/coordinator/keeper/keeper.go index ead9bc645..366ed1228 100644 --- a/x/appchain/coordinator/keeper/keeper.go +++ b/x/appchain/coordinator/keeper/keeper.go @@ -3,23 +3,28 @@ package keeper import ( "fmt" - "github.com/cometbft/cometbft/libs/log" - commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) type Keeper struct { - cdc codec.BinaryCodec - storeKey storetypes.StoreKey - avsKeeper types.AVSKeeper - epochsKeeper types.EpochsKeeper - operatorKeeper types.OperatorKeeper - stakingKeeper types.StakingKeeper - clientKeeper commontypes.ClientKeeper + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + avsKeeper types.AVSKeeper + epochsKeeper types.EpochsKeeper + operatorKeeper types.OperatorKeeper + stakingKeeper types.StakingKeeper + clientKeeper commontypes.ClientKeeper + portKeeper commontypes.PortKeeper + scopedKeeper commontypes.ScopedKeeper + channelKeeper commontypes.ChannelKeeper + connectionKeeper commontypes.ConnectionKeeper } // NewKeeper creates a new coordinator keeper. @@ -31,15 +36,23 @@ func NewKeeper( operatorKeeper types.OperatorKeeper, stakingKeeper types.StakingKeeper, clientKeeper commontypes.ClientKeeper, + portKeeper commontypes.PortKeeper, + scopedKeeper commontypes.ScopedKeeper, + channelKeeper commontypes.ChannelKeeper, + connectionKeeper commontypes.ConnectionKeeper, ) Keeper { return Keeper{ - cdc: cdc, - storeKey: storeKey, - avsKeeper: avsKeeper, - epochsKeeper: epochsKeeper, - operatorKeeper: operatorKeeper, - stakingKeeper: stakingKeeper, - clientKeeper: clientKeeper, + cdc: cdc, + storeKey: storeKey, + avsKeeper: avsKeeper, + epochsKeeper: epochsKeeper, + operatorKeeper: operatorKeeper, + stakingKeeper: stakingKeeper, + clientKeeper: clientKeeper, + portKeeper: portKeeper, + scopedKeeper: scopedKeeper, + channelKeeper: channelKeeper, + connectionKeeper: connectionKeeper, } } @@ -47,3 +60,30 @@ func NewKeeper( func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } + +// BindPort defines a wrapper function for the port Keeper's function in +// order to expose it to module's InitGenesis function +func (k Keeper) BindPort(ctx sdk.Context, portID string) error { + cap := k.portKeeper.BindPort(ctx, portID) + return k.ClaimCapability(ctx, cap, host.PortPath(portID)) +} + +// GetPort returns the portID for the IBC app module. Used in ExportGenesis +func (k Keeper) GetPort(ctx sdk.Context) string { + store := ctx.KVStore(k.storeKey) + return string(store.Get(types.PortKey())) +} + +// SetPort sets the portID for the IBC app module. Used in InitGenesis +func (k Keeper) SetPort(ctx sdk.Context, portID string) { + store := ctx.KVStore(k.storeKey) + store.Set(types.PortKey(), []byte(portID)) +} + +// ClaimCapability allows the IBC app module to claim a capability that core IBC +// passes to it +func (k Keeper) ClaimCapability( + ctx sdk.Context, cap *capabilitytypes.Capability, name string, +) error { + return k.scopedKeeper.ClaimCapability(ctx, cap, name) +} diff --git a/x/appchain/coordinator/module.go b/x/appchain/coordinator/module.go index efaed5a7e..c823ae3f1 100644 --- a/x/appchain/coordinator/module.go +++ b/x/appchain/coordinator/module.go @@ -1,4 +1,4 @@ -package dogfood +package coordinator import ( "context" diff --git a/x/appchain/coordinator/module_ibc.go b/x/appchain/coordinator/module_ibc.go new file mode 100644 index 000000000..1a0a09719 --- /dev/null +++ b/x/appchain/coordinator/module_ibc.go @@ -0,0 +1,307 @@ +package coordinator + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/keeper" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// IBCModule is the IBC module for the subscriber module. +type IBCModule struct { + keeper keeper.Keeper +} + +// interface guard +var _ porttypes.IBCModule = IBCModule{} + +// NewIBCModule creates a new IBCModule instance +func NewIBCModule(k keeper.Keeper) IBCModule { + return IBCModule{ + keeper: k, + } +} + +// OnChanOpenInit implements the IBCModule interface +func (im IBCModule) OnChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portId string, + channelId string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, +) (string, error) { + im.keeper.Logger(ctx).Debug( + "OnChanOpenInit", + ) + return version, errorsmod.Wrap( + commontypes.ErrInvalidChannelFlow, + "channel handshake must be initiated by subscriber chain", + ) +} + +// OnChanOpenTry implements the IBCModule interface +func (im IBCModule) OnChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, +) (string, error) { + im.keeper.Logger(ctx).Debug( + "OnChanOpenTry", + ) + // channel ordering + if order != channeltypes.ORDERED { + return "", errorsmod.Wrapf( + channeltypes.ErrInvalidChannelOrdering, + "expected %s channel, got %s", channeltypes.ORDERED, order, + ) + } + + // the channel's portId should match the module's + boundPort := im.keeper.GetPort(ctx) + if boundPort != portID { + return "", errorsmod.Wrapf( + porttypes.ErrInvalidPort, + "invalid port: %s, expected %s", portID, boundPort, + ) + } + + if counterpartyVersion != commontypes.Version { + return "", errorsmod.Wrapf( + commontypes.ErrInvalidVersion, + "invalid counterparty version: got: %s, expected %s", + counterpartyVersion, + commontypes.Version, + ) + } + + if counterparty.PortId != commontypes.SubscriberPortID { + return "", errorsmod.Wrapf( + porttypes.ErrInvalidPort, + "invalid counterparty port Id: got %s, expected %s", + counterparty.PortId, + commontypes.SubscriberPortID, + ) + } + + // Claim channel capability + if err := im.keeper.ClaimCapability( + ctx, chanCap, host.ChannelCapabilityPath(portID, channelID), + ); err != nil { + return "", err + } + + if err := im.keeper.VerifySubscriberChain( + ctx, channelID, connectionHops, + ); err != nil { + return "", err + } + + md := commontypes.HandshakeMetadata{ + CoordinatorFeePoolAddr: im.keeper.GetSubscriberRewardsPoolAddressStr(ctx), + Version: commontypes.Version, + } + // no k.cdc here so use this + mdBz, err := (&md).Marshal() + if err != nil { + return "", errorsmod.Wrapf(commontypes.ErrInvalidHandshakeMetadata, + "error marshalling ibc-try metadata: %v", err) + } + return string(mdBz), nil +} + +// OnChanOpenAck implements the IBCModule interface +func (im IBCModule) OnChanOpenAck( + ctx sdk.Context, + portId, + channelId string, + _, + counterpartyVersion string, +) error { + im.keeper.Logger(ctx).Error( + "OnChanOpenAck", + ) + return errorsmod.Wrap( + commontypes.ErrInvalidChannelFlow, + "channel handshake must be initiated by subscriber chain", + ) +} + +// OnChanOpenConfirm implements the IBCModule interface +func (im IBCModule) OnChanOpenConfirm( + ctx sdk.Context, + portId string, + channelId string, +) error { + im.keeper.Logger(ctx).Error( + "OnChanOpenConfirm", + ) + err := im.keeper.SetSubscriberChain(ctx, channelId) + if err != nil { + return err + } + return nil +} + +// OnChanCloseInit implements the IBCModule interface +func (im IBCModule) OnChanCloseInit( + ctx sdk.Context, + portId string, + channelId string, +) error { + im.keeper.Logger(ctx).Error( + "OnChanCloseInit", + ) + // Disallow user-initiated channel closing for channels + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") +} + +// OnChanCloseConfirm implements the IBCModule interface +func (im IBCModule) OnChanCloseConfirm( + ctx sdk.Context, + portId, + channelId string, +) error { + im.keeper.Logger(ctx).Error( + "OnChanCloseConfirm", + ) + return nil +} + +// OnRecvPacket implements the IBCModule interface +func (im IBCModule) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + _ sdk.AccAddress, +) ibcexported.Acknowledgement { + im.keeper.Logger(ctx).Error( + "OnRecvPacket", + ) + var ( + ack ibcexported.Acknowledgement + data commontypes.SubscriberPacketData + ) + + if err := commontypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { + errAck := utils.NewErrorAcknowledgementWithLog(ctx, err) + ack = &errAck + } else { + switch data.Type { + case commontypes.SlashPacket: + im.keeper.Logger(ctx).Error( + "OnRecvSlashPacket", + "packet data", data, + ) + ack = im.keeper.OnRecvSlashPacket(ctx, packet, *data.GetSlashPacketData()) + case commontypes.VscMaturedPacket: + im.keeper.Logger(ctx).Error( + "OnRecvVscMaturedPacket", + "packet data", data, + ) + ack = im.keeper.OnRecvVscMaturedPacket(ctx, packet, *data.GetVscMaturedPacketData()) + default: + errAck := utils.NewErrorAcknowledgementWithLog(ctx, fmt.Errorf("unknown packet type: %s", data.Type)) + ack = &errAck + } + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypePacket, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(commontypes.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack != nil)), + ), + ) + + return ack +} + +// OnAcknowledgementPacket implements the IBCModule interface +func (im IBCModule) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + _ sdk.AccAddress, +) error { + im.keeper.Logger(ctx).Error( + "OnAcknowledgementPacket", + ) + var ack channeltypes.Acknowledgement + if err := commontypes.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { + return errorsmod.Wrapf( + sdkerrors.ErrUnknownRequest, + "cannot unmarshal coordinator packet acknowledgement: %v", + err, + ) + } + + if err := im.keeper.OnAcknowledgementPacket(ctx, packet, ack); err != nil { + return err + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypePacket, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(commontypes.AttributeKeyAck, ack.String()), + ), + ) + + switch resp := ack.Response.(type) { + case *channeltypes.Acknowledgement_Result: + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypePacket, + sdk.NewAttribute(commontypes.AttributeKeyAckSuccess, string(resp.Result)), + ), + ) + case *channeltypes.Acknowledgement_Error: + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypePacket, + sdk.NewAttribute(commontypes.AttributeKeyAckError, resp.Error), + ), + ) + } + + return nil +} + +// OnTimeoutPacket implements the IBCModule interface +func (im IBCModule) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + _ sdk.AccAddress, +) error { + im.keeper.Logger(ctx).Error( + "OnTimeoutPacket", + ) + if err := im.keeper.OnTimeoutPacket(ctx, packet); err != nil { + return err + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypeTimeout, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + ), + ) + + return nil +} diff --git a/x/appchain/coordinator/types/errors.go b/x/appchain/coordinator/types/errors.go index 318378878..bef248121 100644 --- a/x/appchain/coordinator/types/errors.go +++ b/x/appchain/coordinator/types/errors.go @@ -9,15 +9,31 @@ const ( errCodeNilRequest errCodeDuplicateSubChain errCodeNoOperators + errCodeInvalidSubscriberClient ) var ( - // ErrInvalidRegistrationParams is the error returned when the subscriber chain registration params are invalid - ErrInvalidRegistrationParams = errorsmod.Register(ModuleName, errCodeInvalidParams, "invalid registration params") + // ErrInvalidRegistrationParams is the error returned when the subscriber chain + // registration params are invalid + ErrInvalidRegistrationParams = errorsmod.Register( + ModuleName, errCodeInvalidParams, "invalid registration params", + ) // ErrNilRequest is the error returned when the request is nil - ErrNilRequest = errorsmod.Register(ModuleName, errCodeNilRequest, "nil request") - // ErrDuplicateSubChain is the error returned when a client for the chain already exists - ErrDuplicateSubChain = errorsmod.Register(ModuleName, errCodeDuplicateSubChain, "subscriber chain already exists") + ErrNilRequest = errorsmod.Register( + ModuleName, errCodeNilRequest, "nil request", + ) + // ErrDuplicateSubChain is the error returned when + // a client for the chain already exists + ErrDuplicateSubChain = errorsmod.Register( + ModuleName, errCodeDuplicateSubChain, "subscriber chain already exists", + ) // ErrNoOperators is the error returned when no qualified operators are available - ErrNoOperators = errorsmod.Register(ModuleName, errCodeNoOperators, "no operators available") + ErrNoOperators = errorsmod.Register( + ModuleName, errCodeNoOperators, "no operators available", + ) + // ErrInvalidSubscriberClient is the error returned when the + // client for the subscriber chain is invalid + ErrInvalidSubscriberClient = errorsmod.Register( + ModuleName, errCodeInvalidSubscriberClient, "invalid subscriber client", + ) ) diff --git a/x/appchain/coordinator/types/keys.go b/x/appchain/coordinator/types/keys.go index 16565e190..12165f426 100644 --- a/x/appchain/coordinator/types/keys.go +++ b/x/appchain/coordinator/types/keys.go @@ -1,6 +1,7 @@ package types import ( + "github.com/ExocoreNetwork/exocore/utils" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -47,16 +48,15 @@ const ( SubscriberGenesisBytePrefix // InitTimeoutBytePrefix is the prefix for the init timeout key InitTimeoutBytePrefix + // PortBytePrefix is the prefix for the port key + PortBytePrefix + // ChannelForChainBytePrefix is the prefix for the channel for chain key + ChannelForChainBytePrefix + // ChainForChannelBytePrefix is the prefix for the chain for channel key + ChainForChannelBytePrefix ) -// AppendMany appends a variable number of byte slices together -func AppendMany(byteses ...[]byte) (out []byte) { - for _, bytes := range byteses { - out = append(out, bytes...) - } - return out -} - +// ParamsKey returns the key under which the coordinator module's parameters are stored. func ParamsKey() []byte { return []byte{ParamsBytePrefix} } @@ -65,7 +65,7 @@ func ParamsKey() []byte { // to begin with the starting of the epoch with identifier and number. Since the data // is stored alphabetically, this key structure is apt. func PendingSubscriberChainKey(epochIdentifier string, epochNumber uint64) []byte { - return AppendMany( + return utils.AppendMany( []byte{PendingSubscriberChainBytePrefix}, []byte(epochIdentifier), sdk.Uint64ToBigEndian(epochNumber), @@ -103,9 +103,26 @@ func SubscriberGenesisKey(chainID string) []byte { // InitTimeoutEpochKey returns the key under which the list of chains which will timeout (if not // initialized by then) at the beginning of the epoch is stored. func InitTimeoutEpochKey(epoch epochstypes.Epoch) []byte { - return AppendMany( + return utils.AppendMany( []byte{InitTimeoutBytePrefix}, []byte(epoch.EpochIdentifier), sdk.Uint64ToBigEndian(epoch.EpochNumber), ) } + +// PortKey returns the key for the port (hello Harry Potter!) +func PortKey() []byte { + return []byte{PortBytePrefix} +} + +// ChannelForChainKey returns the key under which the ibc channel id +// for the given chainId is stored. +func ChannelForChainKey(chainID string) []byte { + return append([]byte{ChannelForChainBytePrefix}, []byte(chainID)...) +} + +// ChainForChannelKey returns the key under which the chainId +// for the given channelId is stored. +func ChainForChannelKey(channelID string) []byte { + return append([]byte{ChainForChannelBytePrefix}, []byte(channelID)...) +} diff --git a/x/appchain/subscriber/keeper/connection.go b/x/appchain/subscriber/keeper/connection.go index 519a5efc3..29d2237a1 100644 --- a/x/appchain/subscriber/keeper/connection.go +++ b/x/appchain/subscriber/keeper/connection.go @@ -1,8 +1,12 @@ package keeper import ( + errorsmod "cosmossdk.io/errors" types "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // SetCoordinatorClientID sets the clientID of the coordinator chain @@ -21,3 +25,62 @@ func (k Keeper) GetCoordinatorClientID(ctx sdk.Context) (string, bool) { bz := store.Get(key) return string(bz), true } + +// SetCoordinatorChannel sets the channelId for the channel to the coordinator. +func (k Keeper) SetCoordinatorChannel(ctx sdk.Context, channelId string) { + store := ctx.KVStore(k.storeKey) + store.Set(types.CoordinatorChannelKey(), []byte(channelId)) +} + +// GetCoordinatorChannel gets the channelId for the channel to the coordinator. +func (k Keeper) GetCoordinatorChannel(ctx sdk.Context) (string, bool) { + store := ctx.KVStore(k.storeKey) + channelIdBytes := store.Get(types.CoordinatorChannelKey()) + if len(channelIdBytes) == 0 { + return "", false + } + return string(channelIdBytes), true +} + +// DeleteCoordinatorChannel deletes the channelId for the channel to the coordinator. +func (k Keeper) DeleteCoordinatorChannel(ctx sdk.Context) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.CoordinatorChannelKey()) +} + +// VerifyCoordinatorChain verifies the chain trying to connect on the channel handshake. +func (k Keeper) VerifyCoordinatorChain(ctx sdk.Context, connectionHops []string) error { + if len(connectionHops) != 1 { + return errorsmod.Wrap( + channeltypes.ErrTooManyConnectionHops, + "must have direct connection to coordinator chain", + ) + } + connectionId := connectionHops[0] + conn, ok := k.connectionKeeper.GetConnection(ctx, connectionId) + if !ok { + return errorsmod.Wrapf( + conntypes.ErrConnectionNotFound, + "connection not found for connection Id: %s", + connectionId, + ) + } + // Verify that client id is expected clientId + expectedClientId, ok := k.GetCoordinatorClientID(ctx) + if !ok { + return errorsmod.Wrapf( + clienttypes.ErrInvalidClient, + "could not find coordinator client id", + ) + } + if expectedClientId != conn.ClientId { + return errorsmod.Wrapf( + clienttypes.ErrInvalidClient, + "invalid client: %s, channel must be built on top of client: %s", + conn.ClientId, + expectedClientId, + ) + } + + return nil +} diff --git a/x/appchain/subscriber/keeper/distribution.go b/x/appchain/subscriber/keeper/distribution.go new file mode 100644 index 000000000..ca32aabf8 --- /dev/null +++ b/x/appchain/subscriber/keeper/distribution.go @@ -0,0 +1,29 @@ +package keeper + +import ( + errorsmod "cosmossdk.io/errors" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + sdk "github.com/cosmos/cosmos-sdk/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" +) + +func (k Keeper) ChannelOpenInit(ctx sdk.Context, msg *channeltypes.MsgChannelOpenInit) ( + *channeltypes.MsgChannelOpenInitResponse, error, +) { + return k.ibcCoreKeeper.ChannelOpenInit(sdk.WrapSDKContext(ctx), msg) +} + +func (k Keeper) TransferChannelExists(ctx sdk.Context, channelID string) bool { + _, found := k.channelKeeper.GetChannel(ctx, transfertypes.PortID, channelID) + return found +} + +func (k Keeper) GetConnectionHops(ctx sdk.Context, srcPort, srcChan string) ([]string, error) { + ch, found := k.channelKeeper.GetChannel(ctx, srcPort, srcChan) + if !found { + return []string{}, errorsmod.Wrapf(commontypes.ErrChannelNotFound, + "cannot get connection hops from non-existent channel") + } + return ch.ConnectionHops, nil +} diff --git a/x/appchain/subscriber/keeper/ibc_client.go b/x/appchain/subscriber/keeper/ibc_client.go new file mode 100644 index 000000000..06e515df7 --- /dev/null +++ b/x/appchain/subscriber/keeper/ibc_client.go @@ -0,0 +1,21 @@ +package keeper + +import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" +) + +// ChanCloseInit defines a wrapper function for the channel Keeper's function. +func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error { + capName := host.ChannelCapabilityPath(portID, channelID) + chanCap, ok := k.scopedKeeper.GetCapability(ctx, capName) + if !ok { + return errorsmod.Wrapf( + channeltypes.ErrChannelCapabilityNotFound, + "could not retrieve channel capability at: %s", capName, + ) + } + return k.channelKeeper.ChanCloseInit(ctx, portID, channelID, chanCap) +} diff --git a/x/appchain/subscriber/keeper/keeper.go b/x/appchain/subscriber/keeper/keeper.go index 49628e36c..6b2f6ab7d 100644 --- a/x/appchain/subscriber/keeper/keeper.go +++ b/x/appchain/subscriber/keeper/keeper.go @@ -2,6 +2,7 @@ package keeper import ( "fmt" + "time" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" @@ -14,11 +15,14 @@ import ( ) type Keeper struct { - cdc codec.BinaryCodec - storeKey storetypes.StoreKey - scopedKeeper commontypes.ScopedKeeper - portKeeper commontypes.PortKeeper - clientKeeper commontypes.ClientKeeper + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + scopedKeeper commontypes.ScopedKeeper + portKeeper commontypes.PortKeeper + clientKeeper commontypes.ClientKeeper + connectionKeeper commontypes.ConnectionKeeper + channelKeeper commontypes.ChannelKeeper + ibcCoreKeeper commontypes.IBCCoreKeeper } // NewKeeper creates a new subscriber keeper. @@ -28,13 +32,18 @@ func NewKeeper( scopedKeeper commontypes.ScopedKeeper, portKeeper commontypes.PortKeeper, clientKeeper commontypes.ClientKeeper, + connectionKeeper commontypes.ConnectionKeeper, + channelKeeper commontypes.ChannelKeeper, + ibcCoreKeeper commontypes.IBCCoreKeeper, ) Keeper { return Keeper{ - cdc: cdc, - storeKey: storeKey, - scopedKeeper: scopedKeeper, - portKeeper: portKeeper, - clientKeeper: clientKeeper, + cdc: cdc, + storeKey: storeKey, + scopedKeeper: scopedKeeper, + portKeeper: portKeeper, + clientKeeper: clientKeeper, + connectionKeeper: connectionKeeper, + channelKeeper: channelKeeper, } } @@ -77,3 +86,53 @@ func (k Keeper) ClaimCapability( ) error { return k.scopedKeeper.ClaimCapability(ctx, cap, name) } + +// GetPendingChanges gets the pending validator set changes that will be applied +// at the end of this block. +func (k Keeper) GetPendingChanges( + ctx sdk.Context, +) (*commontypes.ValidatorSetChangePacketData, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.PendingChangesKey()) + if bz == nil { + return nil, false + } + var res *commontypes.ValidatorSetChangePacketData + k.cdc.MustUnmarshal(bz, res) + return res, true +} + +// SetPendingChanges sets the pending validator set changes that will be applied +// at the end of this block. +func (k Keeper) SetPendingChanges( + ctx sdk.Context, + data *commontypes.ValidatorSetChangePacketData, +) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(data) + store.Set(types.PendingChangesKey(), bz) +} + +// SetPacketMaturityTime sets the maturity time for a given received VSC packet id +func (k Keeper) SetPacketMaturityTime( + ctx sdk.Context, vscId uint64, maturityTime time.Time, +) { + store := ctx.KVStore(k.storeKey) + maturingVSCPacket := &types.MaturingVSCPacket{ + ID: vscId, + MaturityTime: maturityTime, + } + store.Set( + types.PacketMaturityTimeKey(vscId, maturityTime), + k.cdc.MustMarshal(maturingVSCPacket), + ) +} + +// DeleteOutstandingDowntime deletes the outstanding downtime flag for the given validator +// consensus address +func (k Keeper) DeleteOutstandingDowntime( + ctx sdk.Context, consAddress sdk.ConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.OutstandingDowntimeKey(consAddress)) +} diff --git a/x/appchain/subscriber/keeper/params.go b/x/appchain/subscriber/keeper/params.go index 9ccc5c5b7..7480eb7dd 100644 --- a/x/appchain/subscriber/keeper/params.go +++ b/x/appchain/subscriber/keeper/params.go @@ -1,6 +1,8 @@ package keeper import ( + "time" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -21,3 +23,30 @@ func (k Keeper) GetParams(ctx sdk.Context) (res commontypes.SubscriberParams) { k.cdc.MustUnmarshal(bz, &res) return res } + +// SetCoordinatorFeePoolAddrStr sets the coordinator fee pool address string. +// This parameter is not necessarily provided at genesis and can be set later. +// This is because the genesis is generated by the coordinator chain based mostly +// on the registration transaction. +func (k Keeper) SetCoordinatorFeePoolAddrStr(ctx sdk.Context, addrStr string) { + params := k.GetParams(ctx) + params.CoordinatorFeePoolAddrStr = addrStr + k.SetParams(ctx, params) +} + +// GetDistributionTransmissionChannel gets the distribution transmission channel. +func (k Keeper) GetDistributionTransmissionChannel(ctx sdk.Context) string { + return k.GetParams(ctx).DistributionTransmissionChannel +} + +// SetDistributionTransmissionChannel sets the distribution transmission channel. +func (k Keeper) SetDistributionTransmissionChannel(ctx sdk.Context, channel string) { + params := k.GetParams(ctx) + params.DistributionTransmissionChannel = channel + k.SetParams(ctx, params) +} + +// GetUnbondingPeriod gets the unbonding period. +func (k Keeper) GetUnbondingPeriod(ctx sdk.Context) time.Duration { + return k.GetParams(ctx).UnbondingPeriod +} diff --git a/x/appchain/subscriber/keeper/relay.go b/x/appchain/subscriber/keeper/relay.go new file mode 100644 index 000000000..d2c035015 --- /dev/null +++ b/x/appchain/subscriber/keeper/relay.go @@ -0,0 +1,145 @@ +package keeper + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + + "github.com/ExocoreNetwork/exocore/utils" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + sdk "github.com/cosmos/cosmos-sdk/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// OnRecvVSCPacket processes a validator set change packet +func (k Keeper) OnRecvVSCPacket( + ctx sdk.Context, + packet channeltypes.Packet, + data commontypes.ValidatorSetChangePacketData, +) exported.Acknowledgement { + coordinatorChannel, found := k.GetCoordinatorChannel(ctx) + if found && packet.SourceChannel != coordinatorChannel { + // should never happen + k.Logger(ctx).Error( + "received VSCPacket on non-coordinator channel", + "source channel", packet.SourceChannel, + "coordinator channel", coordinatorChannel, + ) + return nil + } + if !found { + // first message on channel + k.SetCoordinatorChannel(ctx, packet.SourceChannel) + k.Logger(ctx).Info( + "channel established", + "port", packet.DestinationPort, + "channel", packet.DestinationChannel, + ) + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypeChannelEstablished, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(channeltypes.AttributeKeyChannelID, packet.DestinationChannel), + sdk.NewAttribute(channeltypes.AttributeKeyPortID, packet.DestinationPort), + ), + ) + } + // the changes are received within blocks, but can only be forwarded to + // Tendermint during EndBlock. hence, get the changes received so far, append to them + // and save them back + currentChanges, _ := k.GetPendingChanges(ctx) + pendingChanges := utils.AccumulateChanges( + currentChanges.ValidatorUpdates, + data.ValidatorUpdates, + ) + + k.SetPendingChanges(ctx, &commontypes.ValidatorSetChangePacketData{ + ValidatorUpdates: pendingChanges, + }) + + // Save maturity time and packet + maturityTime := ctx.BlockTime().Add(k.GetUnbondingPeriod(ctx)) + k.SetPacketMaturityTime(ctx, data.ValsetUpdateID, maturityTime) + k.Logger(ctx).Info( + "packet maturity time was set", + "vscID", data.ValsetUpdateID, + "maturity time (utc)", maturityTime.UTC(), + "maturity time (nano)", uint64(maturityTime.UnixNano()), + ) + + // set height to VSC id mapping; it is effective as of the next block + k.SetValsetUpdateIDForHeight( + ctx, ctx.BlockHeight()+1, data.ValsetUpdateID, + ) + k.Logger(ctx).Info( + "block height was mapped to vscID", + "height", ctx.BlockHeight()+1, + "vscID", data.ValsetUpdateID, + ) + + // remove outstanding slashing flags of the validators + // for which the slashing was acknowledged by the coordinator chain + // TODO(mm): since this packet is only received when there are validator set changes + // there is some additional lag between the slashing occurrence on the coordinator + // and deletion of this flag on the subscriber. does it matter? + for _, addr := range data.GetSlashAcks() { + consAddr, err := sdk.ConsAddressFromBech32(addr) + if err != nil { + k.Logger(ctx).Error( + "failed to parse consensus address", + "address", addr, "error", err, + ) + // returning an error will cause the coordinator to drop us + continue + } + k.DeleteOutstandingDowntime(ctx, consAddr) + } + + k.Logger(ctx).Info( + "finished receiving/handling VSCPacket", + "vscID", data.ValsetUpdateID, + "len updates", len(data.ValidatorUpdates), + "len slash acks", len(data.SlashAcks), + ) + // Acknowledge the packet + return channeltypes.NewResultAcknowledgement([]byte{byte(1)}) +} + +// OnAcknowledgementPacket processes an acknowledgement packet +func (k Keeper) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + ack channeltypes.Acknowledgement, +) error { + // the ack can only be error when packet parsing is failed + // or the packet type is wrong, or when the slash packet + // has incorrect data. none of these should happen + if err := ack.GetError(); err != "" { + k.Logger(ctx).Error( + "recv ErrorAcknowledgement", + "channel", packet.SourceChannel, + "error", err, + ) + // Initiate ChanCloseInit using packet source (non-counterparty) port and channel + err := k.ChanCloseInit(ctx, packet.SourcePort, packet.SourceChannel) + if err != nil { + return fmt.Errorf("ChanCloseInit(%s) failed: %s", packet.SourceChannel, err.Error()) + } + // check if there is an established channel to coordinator + channelID, found := k.GetCoordinatorChannel(ctx) + if !found { + return errorsmod.Wrapf( + types.ErrNoProposerChannelID, + "recv ErrorAcknowledgement on non-established channel %s", + packet.SourceChannel, + ) + } + if channelID != packet.SourceChannel { + // Close the established channel as well + return k.ChanCloseInit(ctx, commontypes.SubscriberPortID, channelID) + } + } + return nil +} diff --git a/x/appchain/subscriber/module.go b/x/appchain/subscriber/module.go index ede8b7a0f..3c8072218 100644 --- a/x/appchain/subscriber/module.go +++ b/x/appchain/subscriber/module.go @@ -1,4 +1,4 @@ -package dogfood +package subscriber import ( "context" diff --git a/x/appchain/subscriber/module_ibc.go b/x/appchain/subscriber/module_ibc.go new file mode 100644 index 000000000..22cb5d012 --- /dev/null +++ b/x/appchain/subscriber/module_ibc.go @@ -0,0 +1,375 @@ +package subscriber + +import ( + "fmt" + "strings" + + errorsmod "cosmossdk.io/errors" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/keeper" + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// IBCModule is the IBC module for the subscriber module. +type IBCModule struct { + keeper keeper.Keeper +} + +// interface guard +var _ porttypes.IBCModule = IBCModule{} + +// NewIBCModule creates a new IBCModule instance +func NewIBCModule(k keeper.Keeper) IBCModule { + return IBCModule{ + keeper: k, + } +} + +// OnChanOpenInit implements the IBCModule interface for the subscriber module. +// The function is called when the channel is created, typically by the relayer, +// which must be informed that the channel should be created on this chain. +// Starting the channel on the coordinator chain is not supported. +func (im IBCModule) OnChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, +) (string, error) { + im.keeper.Logger(ctx).Debug( + "OnChanOpenInit", + ) + + // ICS26 requires that it is set to the default version if empty + if strings.TrimSpace(version) == "" { + version = commontypes.Version + } + // check if channel has already been initialized + if storedChannel, ok := im.keeper.GetCoordinatorChannel(ctx); ok { + return "", errorsmod.Wrapf(commontypes.ErrDuplicateChannel, + "channel already exists with ID %s", storedChannel) + } + + // check channel params (subscriber end) + if order != channeltypes.ORDERED { + return "", errorsmod.Wrapf( + channeltypes.ErrInvalidChannelOrdering, + "expected %s channel, got %s ", + channeltypes.ORDERED, + order, + ) + } + // we set our port at genesis. check that the port of the channel is the same + if boundPort := im.keeper.GetPort(ctx); portID != boundPort { + return "", errorsmod.Wrapf( + porttypes.ErrInvalidPort, + "invalid port ID: %s, expected: %s", + portID, boundPort, + ) + } + // check that the version is correct + if version != commontypes.Version { + return "", errorsmod.Wrapf( + commontypes.ErrInvalidVersion, + "invalid version: %s, expected: %s", + version, commontypes.Version, + ) + } + // check channel params (coordinator end) + if counterparty.PortId != commontypes.CoordinatorPortID { + return "", errorsmod.Wrapf( + porttypes.ErrInvalidPort, + "invalid counterparty port ID: %s, expected: %s", + counterparty.PortId, commontypes.CoordinatorPortID, + ) + } + + // claim channel capability passed back by IBC module + if err := im.keeper.ClaimCapability( + ctx, chanCap, + host.ChannelCapabilityPath(portID, channelID), + ); err != nil { + return "", err + } + + // check connection hops, connection, and the client id (set on genesis) + if err := im.keeper.VerifyCoordinatorChain(ctx, connectionHops); err != nil { + return "", err + } + + return commontypes.Version, nil +} + +// OnChanOpenTry implements the IBCModule interface. It rejects attempts by +// the counterparty chain to open a channel here, since our spec requires +// that the channel is opened by this chain. +func (im IBCModule) OnChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, +) (string, error) { + im.keeper.Logger(ctx).Debug( + "OnChanOpenTry", + ) + return "", errorsmod.Wrap( + commontypes.ErrInvalidChannelFlow, + "channel handshake must be initiated by subscriber chain", + ) +} + +// OnChanOpenAck implements the IBCModule interface. It is ran after `OnChanOpenTry` +// is run on the counterparty chain. +func (im IBCModule) OnChanOpenAck( + ctx sdk.Context, + portID string, + channelID string, + _ string, // unused as per spec + counterpartyMetadata string, +) error { + im.keeper.Logger(ctx).Debug( + "OnChanOpenAck", + ) + + // ensure coordinator channel has not already been created + if coordinatorChannel, ok := im.keeper.GetCoordinatorChannel(ctx); ok { + return errorsmod.Wrapf(commontypes.ErrDuplicateChannel, + "coordinator channel: %s already established", coordinatorChannel) + } + + var md commontypes.HandshakeMetadata + // no k.cdc.MustUnmarshal available here, so we use this way. + if err := (&md).Unmarshal([]byte(counterpartyMetadata)); err != nil { + return errorsmod.Wrapf( + commontypes.ErrInvalidHandshakeMetadata, + "error unmarshalling ibc-ack metadata: \n%v; \nmetadata: %v", + err, counterpartyMetadata, + ) + } + + if md.Version != commontypes.Version { + return errorsmod.Wrapf( + commontypes.ErrInvalidVersion, + "invalid counterparty version: %s, expected %s", + md.Version, + commontypes.Version, + ) + } + + // This address is not required to be supplied at the time of chain registration. + // Rather, it is set later by the coordinator chain. + im.keeper.SetCoordinatorFeePoolAddrStr(ctx, md.CoordinatorFeePoolAddr) + + /////////////////////////////////////////////////// + // Initialize distribution token transfer channel + + // First check if an existing transfer channel already exists. + transChannelID := im.keeper.GetDistributionTransmissionChannel(ctx) + if found := im.keeper.TransferChannelExists(ctx, transChannelID); found { + return nil + } + + // NOTE The handshake for this channel is handled by the ibc-go/transfer + // module. If the transfer-channel fails here (unlikely) then the transfer + // channel should be manually created and parameters set accordingly. + + // reuse the connection hops for this channel for the + // transfer channel being created. + connHops, err := im.keeper.GetConnectionHops(ctx, portID, channelID) + if err != nil { + return err + } + + distrTransferMsg := channeltypes.NewMsgChannelOpenInit( + transfertypes.PortID, + transfertypes.Version, + channeltypes.UNORDERED, + connHops, + transfertypes.PortID, + "", // signer unused + ) + + resp, err := im.keeper.ChannelOpenInit(ctx, distrTransferMsg) + if err != nil { + return err + } + im.keeper.SetDistributionTransmissionChannel(ctx, resp.ChannelId) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeFeeTransferChannelOpened, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(channeltypes.AttributeKeyChannelID, channelID), + sdk.NewAttribute(channeltypes.AttributeKeyPortID, types.PortID), + ), + ) + + return nil +} + +// OnChanOpenConfirm implements the IBCModule interface +func (im IBCModule) OnChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + im.keeper.Logger(ctx).Debug( + "OnChanOpenConfirm", + ) + + return errorsmod.Wrap( + commontypes.ErrInvalidChannelFlow, + "channel handshake must be initiated by subscriber chain", + ) +} + +// OnChanCloseInit implements the IBCModule interface +func (im IBCModule) OnChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + im.keeper.Logger(ctx).Debug( + "OnChanCloseInit", + ) + + // allow relayers to close duplicate OPEN channels, if the coordinator channel has already + // been established + if coordinatorChannel, ok := im.keeper.GetCoordinatorChannel(ctx); ok && + coordinatorChannel != channelID { + return nil + } + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") +} + +// OnChanCloseConfirm implements the IBCModule interface +func (im IBCModule) OnChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + im.keeper.Logger(ctx).Debug( + "OnChanCloseConfirm", + ) + return nil +} + +// OnRecvPacket implements the IBCModule interface +func (im IBCModule) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + _ sdk.AccAddress, +) ibcexported.Acknowledgement { + im.keeper.Logger(ctx).Debug( + "OnRecvPacket", + ) + var ( + ack ibcexported.Acknowledgement + data commontypes.ValidatorSetChangePacketData + ) + if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { + errAck := commontypes.NewErrorAcknowledgementWithLog( + ctx, fmt.Errorf("cannot unmarshal packet data"), + ) + ack = &errAck + } else { + im.keeper.Logger(ctx).Debug( + "OnRecvPacket", + "packet data", data, + ) + ack = im.keeper.OnRecvVSCPacket(ctx, packet, data) + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypePacket, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(commontypes.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack != nil)), + ), + ) + + return ack +} + +// OnAcknowledgementPacket implements the IBCModule interface +func (im IBCModule) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + im.keeper.Logger(ctx).Debug( + "OnAcknowledgementPacket", + ) + var ack channeltypes.Acknowledgement + if err := commontypes.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { + return errorsmod.Wrapf( + sdkerrors.ErrUnknownRequest, + "cannot unmarshal subscriber packet acknowledgement: %v", + err, + ) + } + + if err := im.keeper.OnAcknowledgementPacket(ctx, packet, ack); err != nil { + return err + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypePacket, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(commontypes.AttributeKeyAck, ack.String()), + ), + ) + switch resp := ack.Response.(type) { + case *channeltypes.Acknowledgement_Result: + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypePacket, + sdk.NewAttribute(commontypes.AttributeKeyAckSuccess, string(resp.Result)), + ), + ) + case *channeltypes.Acknowledgement_Error: + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypePacket, + sdk.NewAttribute(commontypes.AttributeKeyAckError, resp.Error), + ), + ) + } + return nil +} + +// OnTimeoutPacket implements the IBCModule interface +func (im IBCModule) OnTimeoutPacket( + ctx sdk.Context, + modulePacket channeltypes.Packet, + relayer sdk.AccAddress, +) error { + im.keeper.Logger(ctx).Debug( + "OnTimeoutPacket", + ) + ctx.EventManager().EmitEvent( + sdk.NewEvent( + commontypes.EventTypeTimeout, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + ), + ) + + return nil +} diff --git a/x/appchain/subscriber/types/errors.go b/x/appchain/subscriber/types/errors.go new file mode 100644 index 000000000..7bc9189a4 --- /dev/null +++ b/x/appchain/subscriber/types/errors.go @@ -0,0 +1,10 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" +) + +// x/subscriber module sentinel errors +var ( + ErrNoProposerChannelID = errorsmod.Register(ModuleName, 2, "no established channel") +) diff --git a/x/appchain/subscriber/types/events.go b/x/appchain/subscriber/types/events.go new file mode 100644 index 000000000..0363af2f1 --- /dev/null +++ b/x/appchain/subscriber/types/events.go @@ -0,0 +1,5 @@ +package types + +const ( + EventTypeFeeTransferChannelOpened = "fee_transfer_channel_opened" +) diff --git a/x/appchain/subscriber/types/genesis.pb.go b/x/appchain/subscriber/types/genesis.pb.go index c52234281..7a456cef0 100644 --- a/x/appchain/subscriber/types/genesis.pb.go +++ b/x/appchain/subscriber/types/genesis.pb.go @@ -8,15 +8,19 @@ import ( types "github.com/ExocoreNetwork/exocore/x/appchain/common/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -100,8 +104,66 @@ func (m *GenesisState) GetCoordinatorChannelID() string { return "" } +// MaturingVSCPacket represents a vsc packet that is maturing internal to the +// subscriber module, where it has not yet relayed a VSCMatured packet back. +// While it is technically feasible to store this just as a key in the state, +// keeping it as a separate type allows exporting the genesis data. +// The key used is prefix + time + vscId. +type MaturingVSCPacket struct { + ID uint64 `protobuf:"varint,1,opt,name=vscId,proto3" json:"vscId,omitempty"` + MaturityTime time.Time `protobuf:"bytes,2,opt,name=maturity_time,json=maturityTime,proto3,stdtime" json:"maturity_time"` +} + +func (m *MaturingVSCPacket) Reset() { *m = MaturingVSCPacket{} } +func (m *MaturingVSCPacket) String() string { return proto.CompactTextString(m) } +func (*MaturingVSCPacket) ProtoMessage() {} +func (*MaturingVSCPacket) Descriptor() ([]byte, []int) { + return fileDescriptor_f608de439fd2c5db, []int{1} +} +func (m *MaturingVSCPacket) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MaturingVSCPacket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MaturingVSCPacket.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MaturingVSCPacket) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaturingVSCPacket.Merge(m, src) +} +func (m *MaturingVSCPacket) XXX_Size() int { + return m.Size() +} +func (m *MaturingVSCPacket) XXX_DiscardUnknown() { + xxx_messageInfo_MaturingVSCPacket.DiscardUnknown(m) +} + +var xxx_messageInfo_MaturingVSCPacket proto.InternalMessageInfo + +func (m *MaturingVSCPacket) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *MaturingVSCPacket) GetMaturityTime() time.Time { + if m != nil { + return m.MaturityTime + } + return time.Time{} +} + func init() { proto.RegisterType((*GenesisState)(nil), "exocore.appchain.subscriber.v1.GenesisState") + proto.RegisterType((*MaturingVSCPacket)(nil), "exocore.appchain.subscriber.v1.MaturingVSCPacket") } func init() { @@ -109,29 +171,35 @@ func init() { } var fileDescriptor_f608de439fd2c5db = []byte{ - // 340 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0xd2, 0xbf, 0x4f, 0xc2, 0x40, - 0x14, 0x07, 0xf0, 0x16, 0x09, 0x89, 0xc5, 0xa9, 0xa0, 0x36, 0x0c, 0x07, 0x71, 0x91, 0x44, 0xd2, - 0x0b, 0x3a, 0xbb, 0x00, 0xc6, 0xa0, 0x09, 0x31, 0x30, 0x98, 0xb8, 0x90, 0xeb, 0xf5, 0x2c, 0x17, - 0xe1, 0x5e, 0x73, 0x3d, 0x10, 0xff, 0x0b, 0xff, 0x2c, 0x06, 0x07, 0x46, 0x27, 0x62, 0xca, 0x3f, - 0x62, 0xfa, 0x03, 0xa9, 0xa9, 0x71, 0x7b, 0x7d, 0xfd, 0xf6, 0xd3, 0xd7, 0xbe, 0x33, 0x5a, 0x6c, - 0x09, 0x14, 0x24, 0xc3, 0xc4, 0xf7, 0xe9, 0x84, 0x70, 0x81, 0x83, 0xb9, 0x13, 0x50, 0xc9, 0x1d, - 0x26, 0xf1, 0xa2, 0x8d, 0x3d, 0x26, 0x58, 0xc0, 0x03, 0xdb, 0x97, 0xa0, 0xc0, 0x44, 0x69, 0xda, - 0xde, 0xa5, 0xed, 0x7d, 0xda, 0x5e, 0xb4, 0x6b, 0xe7, 0x39, 0x8d, 0xc2, 0x6c, 0x06, 0x22, 0x92, - 0x92, 0x2a, 0x81, 0x6a, 0x55, 0x0f, 0x3c, 0x88, 0x4b, 0x1c, 0x55, 0x49, 0xf7, 0xec, 0xa3, 0x60, - 0x1c, 0xdd, 0x26, 0x2f, 0x1c, 0x29, 0xa2, 0x98, 0x79, 0x67, 0x94, 0x7c, 0x22, 0xc9, 0x2c, 0xb0, - 0xf4, 0x86, 0xde, 0x2c, 0x5f, 0xb6, 0xec, 0xdc, 0x00, 0x29, 0xbb, 0x68, 0xdb, 0xa3, 0x9f, 0x51, - 0x1e, 0xe2, 0x67, 0x3a, 0xc5, 0xd5, 0xa6, 0xae, 0x0d, 0x53, 0xc1, 0x1c, 0x19, 0x65, 0x0a, 0x20, - 0x5d, 0x2e, 0x88, 0x02, 0x69, 0x15, 0x62, 0xf0, 0xe2, 0x3f, 0xb0, 0xbb, 0x8f, 0xf7, 0xc5, 0x33, - 0xa4, 0x5e, 0x56, 0x31, 0xef, 0x8d, 0xe3, 0xcc, 0xe5, 0x98, 0x4e, 0x39, 0x13, 0x6a, 0xcc, 0x5d, - 0xeb, 0xa0, 0xa1, 0x37, 0x0f, 0x3b, 0xa7, 0xe1, 0xa6, 0x5e, 0xc9, 0x30, 0xdd, 0xf8, 0x7e, 0xbf, - 0x37, 0xac, 0xd0, 0x5c, 0xd3, 0x35, 0x07, 0xc6, 0xc9, 0x2f, 0x6c, 0x42, 0x84, 0x60, 0xd3, 0x48, - 0x2b, 0xc6, 0x9a, 0x15, 0x6e, 0xea, 0xd5, 0xac, 0x96, 0x04, 0xfa, 0xbd, 0x61, 0x95, 0xe6, 0xbb, - 0x6e, 0xe7, 0x71, 0x15, 0x22, 0x7d, 0x1d, 0x22, 0xfd, 0x2b, 0x44, 0xfa, 0xfb, 0x16, 0x69, 0xeb, - 0x2d, 0xd2, 0x3e, 0xb7, 0x48, 0x7b, 0xba, 0xf6, 0xb8, 0x9a, 0xcc, 0x9d, 0xe8, 0x5b, 0xf1, 0x4d, - 0xf2, 0x03, 0x06, 0x4c, 0xbd, 0x82, 0x7c, 0xc1, 0xbb, 0x0d, 0x2e, 0xff, 0x3c, 0x11, 0xea, 0xcd, - 0x67, 0x81, 0x53, 0x8a, 0xd7, 0x75, 0xf5, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x07, 0x9b, 0x62, 0x88, - 0x3d, 0x02, 0x00, 0x00, + // 439 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0xc7, 0x9b, 0x52, 0x2a, 0xf0, 0xc6, 0x81, 0xac, 0x40, 0x55, 0xa1, 0x64, 0xda, 0x85, 0x49, + 0x4c, 0xb6, 0x0a, 0x67, 0x2e, 0x69, 0x11, 0x0a, 0x88, 0x69, 0x4a, 0x11, 0x48, 0x5c, 0x2a, 0xc7, + 0xf1, 0x52, 0x6b, 0x8d, 0x1d, 0xd9, 0x6e, 0xd9, 0x24, 0x3e, 0xc4, 0x3e, 0xd6, 0x0e, 0x1c, 0x76, + 0xe4, 0x54, 0x50, 0xfa, 0x45, 0x50, 0xec, 0x84, 0x06, 0x05, 0xed, 0xf6, 0xfc, 0xfc, 0x7f, 0x3f, + 0x3f, 0xfd, 0xff, 0x06, 0x27, 0xf4, 0x52, 0x10, 0x21, 0x29, 0xc2, 0x79, 0x4e, 0x16, 0x98, 0x71, + 0xa4, 0x56, 0xb1, 0x22, 0x92, 0xc5, 0x54, 0xa2, 0xf5, 0x18, 0xa5, 0x94, 0x53, 0xc5, 0x14, 0xcc, + 0xa5, 0xd0, 0xc2, 0xf5, 0x2a, 0x35, 0xac, 0xd5, 0x70, 0xa7, 0x86, 0xeb, 0xf1, 0xe8, 0x45, 0x8b, + 0x46, 0x44, 0x96, 0x09, 0x5e, 0x92, 0x6c, 0x65, 0x41, 0xa3, 0x41, 0x2a, 0x52, 0x61, 0x4a, 0x54, + 0x56, 0x55, 0xd7, 0x4f, 0x85, 0x48, 0x97, 0x14, 0x99, 0x53, 0xbc, 0x3a, 0x47, 0x9a, 0x65, 0x54, + 0x69, 0x9c, 0xe5, 0x56, 0x70, 0xf4, 0xa3, 0x0b, 0xf6, 0xdf, 0xd9, 0x8d, 0x66, 0x1a, 0x6b, 0xea, + 0xbe, 0x07, 0xfd, 0x1c, 0x4b, 0x9c, 0xa9, 0xa1, 0x73, 0xe8, 0x1c, 0xef, 0xbd, 0x3a, 0x81, 0xad, + 0x0d, 0xab, 0x77, 0xd7, 0x63, 0x38, 0xfb, 0xbb, 0xeb, 0x99, 0x99, 0x09, 0x7a, 0x37, 0x1b, 0xbf, + 0x13, 0x55, 0x04, 0x77, 0x06, 0xf6, 0x88, 0x10, 0x32, 0x61, 0x1c, 0x6b, 0x21, 0x87, 0x5d, 0x03, + 0x7c, 0x79, 0x17, 0x70, 0xb2, 0x93, 0x87, 0xfc, 0x5c, 0x54, 0xbc, 0x26, 0xc5, 0xfd, 0x00, 0x9e, + 0x34, 0x8e, 0x73, 0xb2, 0x64, 0x94, 0xeb, 0x39, 0x4b, 0x86, 0xf7, 0x0e, 0x9d, 0xe3, 0x87, 0xc1, + 0xb3, 0x62, 0xe3, 0x1f, 0x34, 0x30, 0x13, 0x73, 0x1f, 0x4e, 0xa3, 0x03, 0xd2, 0x6a, 0x26, 0xee, + 0x29, 0x78, 0xfa, 0x0f, 0x6c, 0x81, 0x39, 0xa7, 0xcb, 0x92, 0xd6, 0x33, 0xb4, 0x61, 0xb1, 0xf1, + 0x07, 0x4d, 0x9a, 0x15, 0x84, 0xd3, 0x68, 0x40, 0xda, 0xdd, 0xe4, 0xe8, 0x3b, 0x78, 0xfc, 0x11, + 0xeb, 0x95, 0x64, 0x3c, 0xfd, 0x3c, 0x9b, 0x9c, 0x61, 0x72, 0x41, 0xb5, 0xfb, 0x1c, 0xdc, 0x5f, + 0x2b, 0x12, 0x26, 0xc6, 0xd1, 0x5e, 0xd0, 0x2f, 0x36, 0x7e, 0x37, 0x9c, 0x46, 0xb6, 0xe9, 0x86, + 0xe0, 0x51, 0x66, 0x46, 0xf4, 0xd5, 0xbc, 0x4c, 0xa7, 0xb2, 0x69, 0x04, 0x6d, 0x74, 0xb0, 0x8e, + 0x0e, 0x7e, 0xaa, 0xa3, 0x0b, 0x1e, 0x94, 0xae, 0x5c, 0xff, 0xf2, 0x9d, 0x68, 0xbf, 0x1e, 0x2d, + 0x2f, 0x83, 0x2f, 0x37, 0x85, 0xe7, 0xdc, 0x16, 0x9e, 0xf3, 0xbb, 0xf0, 0x9c, 0xeb, 0xad, 0xd7, + 0xb9, 0xdd, 0x7a, 0x9d, 0x9f, 0x5b, 0xaf, 0xf3, 0xf5, 0x4d, 0xca, 0xf4, 0x62, 0x15, 0x97, 0x4e, + 0xa3, 0xb7, 0xd6, 0xfe, 0x53, 0xaa, 0xbf, 0x09, 0x79, 0x81, 0xea, 0x0f, 0x76, 0xf9, 0xdf, 0x0f, + 0xab, 0xaf, 0x72, 0xaa, 0xe2, 0xbe, 0x59, 0xe2, 0xf5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x62, + 0x15, 0x51, 0xd4, 0xdc, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -191,6 +259,42 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *MaturingVSCPacket) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MaturingVSCPacket) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MaturingVSCPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n3, err3 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.MaturityTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.MaturityTime):]) + if err3 != nil { + return 0, err3 + } + i -= n3 + i = encodeVarintGenesis(dAtA, i, uint64(n3)) + i-- + dAtA[i] = 0x12 + if m.ID != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.ID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -223,6 +327,20 @@ func (m *GenesisState) Size() (n int) { return n } +func (m *MaturingVSCPacket) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ID != 0 { + n += 1 + sovGenesis(uint64(m.ID)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.MaturityTime) + n += 1 + l + sovGenesis(uint64(l)) + return n +} + func sovGenesis(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -409,6 +527,108 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } return nil } +func (m *MaturingVSCPacket) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MaturingVSCPacket: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MaturingVSCPacket: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaturityTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.MaturityTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipGenesis(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/appchain/subscriber/types/keys.go b/x/appchain/subscriber/types/keys.go index f8178090f..68c7742fd 100644 --- a/x/appchain/subscriber/types/keys.go +++ b/x/appchain/subscriber/types/keys.go @@ -1,6 +1,9 @@ package types import ( + time "time" + + "github.com/ExocoreNetwork/exocore/utils" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -45,6 +48,14 @@ const ( ValsetUpdateIDBytePrefix // OmniChainValidatorBytePrefix is the prefix for the omni chain validator key OmniChainValidatorBytePrefix + // CoordinatorChannelBytePrefix is the prefix for the coordinator channel key + CoordinatorChannelBytePrefix + // PendingChangesBytePrefix is the prefix for the pending changes key + PendingChangesBytePrefix + // PacketMaturityTimeBytePrefix is the prefix for the packet maturity time key + PacketMaturityTimeBytePrefix + // OutstandingDowntimeBytePrefix is the prefix for the outstanding downtime key + OutstandingDowntimeBytePrefix ) // ParamsKey returns the key for the params @@ -74,3 +85,28 @@ func ValsetUpdateIDKey(height int64) []byte { func OmniChainValidatorKey(address sdk.ConsAddress) []byte { return append([]byte{OmniChainValidatorBytePrefix}, address...) } + +// CoordinatorChannelKey returns the key for which the ibc channel id to the coordinator chain +// is stored. +func CoordinatorChannelKey() []byte { + return []byte{CoordinatorChannelBytePrefix} +} + +// PendingChangesKey returns the key for the pending changes +func PendingChangesKey() []byte { + return []byte{PendingChangesBytePrefix} +} + +// PacketMaturityTimeKey returns the key for the packet maturity time +func PacketMaturityTimeKey(vscID uint64, maturityTime time.Time) []byte { + return utils.AppendMany( + []byte{PacketMaturityTimeBytePrefix}, + sdk.FormatTimeBytes(maturityTime), + sdk.Uint64ToBigEndian(vscID), + ) +} + +// OutstandingDowntimeKey returns the key for the outstanding downtime +func OutstandingDowntimeKey(consAddress sdk.ConsAddress) []byte { + return append([]byte{OutstandingDowntimeBytePrefix}, consAddress.Bytes()...) +} From e2b541dce68768d2ee37807c0af798ad0d9b91d2 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:40:42 +0000 Subject: [PATCH 35/52] part 2 commit including handling pending is just validator set updates on both ends of the connection --- proto/exocore/appchain/common/v1/wire.proto | 84 +- .../appchain/coordinator/v1/coordinator.proto | 5 + .../appchain/subscriber/v1/genesis.proto | 4 +- .../appchain/subscriber/v1/subscriber.proto | 15 +- types/chain_id.go | 11 + utils/utils.go | 2 +- x/appchain/common/types/errors.go | 4 + x/appchain/common/types/types.go | 6 + x/appchain/common/types/wire.go | 30 + x/appchain/common/types/wire.pb.go | 916 +++++++++++++++++- x/appchain/coordinator/keeper/connection.go | 10 +- x/appchain/coordinator/keeper/height.go | 21 + x/appchain/coordinator/keeper/ibc_client.go | 8 +- .../coordinator/keeper/impl_epochs_hooks.go | 4 +- x/appchain/coordinator/keeper/keeper.go | 7 +- x/appchain/coordinator/keeper/relay.go | 182 ++++ x/appchain/coordinator/keeper/slash.go | 85 +- x/appchain/coordinator/keeper/timeout.go | 34 +- x/appchain/coordinator/module_ibc.go | 100 +- .../coordinator/types/coordinator.pb.go | 212 +++- x/appchain/coordinator/types/errors.go | 6 + .../coordinator/types/expected_keepers.go | 16 + x/appchain/coordinator/types/keys.go | 35 + x/appchain/subscriber/keeper/connection.go | 22 +- x/appchain/subscriber/keeper/keeper.go | 11 +- x/appchain/subscriber/keeper/validators.go | 45 +- x/appchain/subscriber/module_ibc.go | 30 +- x/appchain/subscriber/types/keys.go | 11 +- x/appchain/subscriber/types/subscriber.pb.go | 121 +-- x/appchain/subscriber/types/validator.go | 20 +- x/avs/keeper/avs.go | 3 +- x/avs/keeper/keeper.go | 3 +- x/avs/keeper/query.go | 3 +- x/avs/types/types.go | 13 - x/dogfood/keeper/abci.go | 4 +- x/dogfood/keeper/genesis.go | 2 +- x/dogfood/keeper/impl_delegation_hooks.go | 4 +- x/dogfood/keeper/impl_epochs_hooks_test.go | 6 +- x/dogfood/keeper/impl_operator_hooks.go | 6 +- x/dogfood/keeper/impl_sdk.go | 19 +- x/dogfood/keeper/opt_out_test.go | 4 +- x/dogfood/keeper/unbonding_test.go | 6 +- x/dogfood/keeper/validators.go | 8 +- x/operator/keeper/grpc_query.go | 10 +- x/operator/keeper/slash.go | 4 +- x/operator/keeper/slash_test.go | 3 +- x/operator/keeper/usd_value_test.go | 5 +- 47 files changed, 1808 insertions(+), 352 deletions(-) create mode 100644 x/appchain/common/types/wire.go create mode 100644 x/appchain/coordinator/keeper/height.go create mode 100644 x/appchain/coordinator/keeper/relay.go diff --git a/proto/exocore/appchain/common/v1/wire.proto b/proto/exocore/appchain/common/v1/wire.proto index 991a3650f..96bd36304 100644 --- a/proto/exocore/appchain/common/v1/wire.proto +++ b/proto/exocore/appchain/common/v1/wire.proto @@ -17,45 +17,57 @@ message HandshakeMetadata { string version = 2; } -// // This packet is sent from the subscriber chain to the coordinator chain -// // to request the slashing of a validator as a result of an infraction -// // committed on the subscriber chain. -// message SlashPacketData { -// tendermint.abci.Validator validator = 1 [ -// (gogoproto.nullable) = false, -// (gogoproto.moretags) = "yaml:\"validator\"" -// ]; -// // map to the infraction block height on the coordinator -// uint64 valset_update_id = 2; -// // tell if the slashing is for a downtime or a double-signing infraction -// cosmos.staking.v1beta1.Infraction infraction = 3; -// } - -// // This packet is sent from subsciber to coordinator to indicate that the validator set change -// // with the specified id has matured on the subscriber chain. This is used to know when to -// // prune some information on the coordinator. -// message VscMaturedPacketData { -// uint64 valset_update_id = 1; -// } - -// // Type of SubscriberPacketData -// enum SubscriberPacketDataType { -// option (gogoproto.goproto_enum_prefix) = false; +// SlashPacketData is sent from the subscriber chain to the coordinator chain +// to request the slashing of a validator as a result of an infraction committed +// on the subscriber chain. +message SlashPacketData { + // validator is the validator to be slashed + tendermint.abci.Validator validator = 1 [ + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"validator\"" + ]; + // valset_update_id is the id of the validator set change during which + // the infraction was committed + uint64 valset_update_id = 2 [ (gogoproto.customname) = "ValsetUpdateID" ]; + // infraction refers to the type of infraction committed + cosmos.staking.v1beta1.Infraction infraction = 3; +} -// SUBSCRIBER_PACKET_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "UnspecifiedPacket" ]; -// SUBSCRIBER_PACKET_TYPE_SLASH = 1 [ (gogoproto.enumvalue_customname) = "SlashPacket" ]; -// SUBSCRIBER_PACKET_TYPE_VSC_MATURED = 2 [ (gogoproto.enumvalue_customname) = "VscMaturedPacket" ];; -// } +// VscMaturedPacketData is sent from the subscriber chain to the coordinator chain +// to indicate that a VSC has matured and unbondings associated with that VSC +// can now be released. +message VscMaturedPacketData { + // valset_update_id is the id of the validator set change to mature. + uint64 valset_update_id = 1 [ (gogoproto.customname) = "ValsetUpdateID" ]; +} -// // Overall packet -// message SubscriberPacketData { -// SubscriberPacketDataType type = 1; +// SubscriberPacketData is the enum to identify the type of packet sent. +enum SubscriberPacketDataType { + option (gogoproto.goproto_enum_prefix) = false; + // SUBSCRIBER_PACKET_TYPE_UNSPECIFIED is the default value + SUBSCRIBER_PACKET_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "UnspecifiedPacket" ]; + // SUBSCRIBER_PACKET_TYPE_SLASH is the type of packet sent when a subscriber + // chain wants to request the slashing of a validator on the coordinator chain. + SUBSCRIBER_PACKET_TYPE_SLASH = 1 [ (gogoproto.enumvalue_customname) = "SlashPacket" ]; + // SUBSCRIBER_PACKET_TYPE_VSC_MATURED is the type of packet sent when a subscriber + // chain wants to indicate that a VSC has matured and unbondings associated with + // that VSC can now be released. + SUBSCRIBER_PACKET_TYPE_VSC_MATURED = 2 [ (gogoproto.enumvalue_customname) = "VscMaturedPacket" ];; +} -// oneof data { -// SlashPacketData slashPacketData = 2; -// VscMaturedPacketData vscMaturedPacketData = 3; -// } -// } +// SubscriberPacketData is a wrapped message that contains the type of packet +// and the data associated with that packet. +message SubscriberPacketData { + // type is the type of packet sent + SubscriberPacketDataType type = 1; + // data is the data associated with the packet + oneof data { + // slash_packet_data is the data associated with a SlashPacket + SlashPacketData slash_packet_data = 2; + // vsc_matured_packet_data is the data associated with a VscMaturedPacket + VscMaturedPacketData vsc_matured_packet_data = 3; + } +} // ValidatorSetChangePacketData is sent from the coordinator chain to the subscriber chain // containing the new validator set and the id of the validator set change. diff --git a/proto/exocore/appchain/coordinator/v1/coordinator.proto b/proto/exocore/appchain/coordinator/v1/coordinator.proto index feff10b5f..4b0a3e06e 100644 --- a/proto/exocore/appchain/coordinator/v1/coordinator.proto +++ b/proto/exocore/appchain/coordinator/v1/coordinator.proto @@ -21,3 +21,8 @@ message ChainIDs { repeated string list = 1; } +// ConsensusAddresses is a list of consensus addresses. +message ConsensusAddresses { + // list is the list of consensus addresses. + repeated bytes list = 1; +} \ No newline at end of file diff --git a/proto/exocore/appchain/subscriber/v1/genesis.proto b/proto/exocore/appchain/subscriber/v1/genesis.proto index cb7fd887b..07fb8384b 100644 --- a/proto/exocore/appchain/subscriber/v1/genesis.proto +++ b/proto/exocore/appchain/subscriber/v1/genesis.proto @@ -30,7 +30,9 @@ message GenesisState { // keeping it as a separate type allows exporting the genesis data. // The key used is prefix + time + vscId. message MaturingVSCPacket { - uint64 vscId = 1 [ (gogoproto.customname) = "ID" ]; + // vsc_id is the id of the VSC that is maturing. + uint64 vsc_id = 1 [ (gogoproto.customname) = "ID" ]; + // maturity_time is the time at which the VSC will mature. google.protobuf.Timestamp maturity_time = 2 [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; } \ No newline at end of file diff --git a/proto/exocore/appchain/subscriber/v1/subscriber.proto b/proto/exocore/appchain/subscriber/v1/subscriber.proto index f4467cc45..673cb21bd 100644 --- a/proto/exocore/appchain/subscriber/v1/subscriber.proto +++ b/proto/exocore/appchain/subscriber/v1/subscriber.proto @@ -2,19 +2,22 @@ syntax = "proto3"; package exocore.appchain.subscriber.v1; -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; -message OmniChainValidator { - // The address is derived from the consenus key. It has no relation with the operator +// SubscriberChainValidator is a validator structure on the subscriber chain. +// The name is verbose intentionally. +message SubscriberChainValidator { + // address, as derived from the consensus key. No correlation with the operator // address on Exocore. - bytes address = 1; - // Last known + bytes cons_address = 1; + // power is the vote power of the validator int64 power = 2; // pubkey is the consensus public key of the validator, as a Protobuf Any. + // this type is chosen to match the x/staking/validator type. google.protobuf.Any pubkey = 3 [ (cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", (gogoproto.moretags) = "yaml:\"consensus_pubkey\"" diff --git a/types/chain_id.go b/types/chain_id.go index e8bf2b4c0..323918c0f 100644 --- a/types/chain_id.go +++ b/types/chain_id.go @@ -7,6 +7,7 @@ import ( "strings" errorsmod "cosmossdk.io/errors" + ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) var ( @@ -53,3 +54,13 @@ func ParseChainID(chainID string) (*big.Int, error) { return chainIDInt, nil } + +// ChainIDWithoutRevision returns the chainID without the revision number. +// For example, "exocoretestnet_233-1" returns "exocoretestnet_233". +func ChainIDWithoutRevision(chainID string) string { + if !ibcclienttypes.IsRevisionFormat(chainID) { + return chainID + } + splitStr := strings.Split(chainID, "-") + return splitStr[0] +} diff --git a/utils/utils.go b/utils/utils.go index 94dc0fe7c..c9f3e87ba 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -171,7 +171,7 @@ func AccumulateChanges( } // convert to list - var out []abci.ValidatorUpdate + out := make([]abci.ValidatorUpdate, 0, len(m)) for _, update := range m { out = append(out, update) } diff --git a/x/appchain/common/types/errors.go b/x/appchain/common/types/errors.go index feb9e4e65..4031161ce 100644 --- a/x/appchain/common/types/errors.go +++ b/x/appchain/common/types/errors.go @@ -29,4 +29,8 @@ var ( ModuleName, 7, "client not found", ) + ErrInvalidPacketData = errorsmod.Register( + ModuleName, 8, + "invalid packet data (but successfully unmarshalled)", + ) ) diff --git a/x/appchain/common/types/types.go b/x/appchain/common/types/types.go index 025040981..6b5466099 100644 --- a/x/appchain/common/types/types.go +++ b/x/appchain/common/types/types.go @@ -10,3 +10,9 @@ func NewErrorAcknowledgementWithLog(ctx sdk.Context, err error) channeltypes.Ack ctx.Logger().Error("IBC ErrorAcknowledgement constructed", "error", err) return channeltypes.NewErrorAcknowledgement(err) } + +// NewResultAcknowledgementWithLog creates a result acknowledgement with a log message. +func NewResultAcknowledgementWithLog(ctx sdk.Context, res []byte) channeltypes.Acknowledgement { + ctx.Logger().Info("IBC ResultAcknowledgement constructed", "res", res) + return channeltypes.NewResultAcknowledgement(res) +} diff --git a/x/appchain/common/types/wire.go b/x/appchain/common/types/wire.go new file mode 100644 index 000000000..bef4e3aac --- /dev/null +++ b/x/appchain/common/types/wire.go @@ -0,0 +1,30 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// PacketAckResult is the acknowledgment result of a packet. +type PacketAckResult []byte + +// SlashPacketHandledResult is the success acknowledgment result of a slash packet. +var SlashPacketHandledResult = PacketAckResult([]byte{byte(2)}) + +func (vdt SlashPacketData) Validate() error { + // vdt.Validator.Address must be a consensus address + if err := sdk.VerifyAddressFormat(vdt.Validator.Address); err != nil { + return ErrInvalidPacketData.Wrapf("invalid validator: %s", err.Error()) + } + // vdt.Validator.Power must be positive + if vdt.Validator.Power == 0 { + return ErrInvalidPacketData.Wrap("validator power cannot be zero") + } + // ValsetUpdateId can be zero for the first validator set, so we don't validate it here. + if vdt.Infraction != stakingtypes.Infraction_INFRACTION_DOWNTIME { + // only downtime infractions are supported at this time + return ErrInvalidPacketData.Wrapf("invalid infraction type: %s", vdt.Infraction.String()) + } + + return nil +} diff --git a/x/appchain/common/types/wire.pb.go b/x/appchain/common/types/wire.pb.go index ac0580928..0a95ba741 100644 --- a/x/appchain/common/types/wire.pb.go +++ b/x/appchain/common/types/wire.pb.go @@ -6,7 +6,7 @@ package types import ( fmt "fmt" types "github.com/cometbft/cometbft/abci/types" - _ "github.com/cosmos/cosmos-sdk/x/staking/types" + types1 "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -25,6 +25,41 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// SubscriberPacketData is the enum to identify the type of packet sent. +type SubscriberPacketDataType int32 + +const ( + // SUBSCRIBER_PACKET_TYPE_UNSPECIFIED is the default value + UnspecifiedPacket SubscriberPacketDataType = 0 + // SUBSCRIBER_PACKET_TYPE_SLASH is the type of packet sent when a subscriber + // chain wants to request the slashing of a validator on the coordinator chain. + SlashPacket SubscriberPacketDataType = 1 + // SUBSCRIBER_PACKET_TYPE_VSC_MATURED is the type of packet sent when a subscriber + // chain wants to indicate that a VSC has matured and unbondings associated with + // that VSC can now be released. + VscMaturedPacket SubscriberPacketDataType = 2 +) + +var SubscriberPacketDataType_name = map[int32]string{ + 0: "SUBSCRIBER_PACKET_TYPE_UNSPECIFIED", + 1: "SUBSCRIBER_PACKET_TYPE_SLASH", + 2: "SUBSCRIBER_PACKET_TYPE_VSC_MATURED", +} + +var SubscriberPacketDataType_value = map[string]int32{ + "SUBSCRIBER_PACKET_TYPE_UNSPECIFIED": 0, + "SUBSCRIBER_PACKET_TYPE_SLASH": 1, + "SUBSCRIBER_PACKET_TYPE_VSC_MATURED": 2, +} + +func (x SubscriberPacketDataType) String() string { + return proto.EnumName(SubscriberPacketDataType_name, int32(x)) +} + +func (SubscriberPacketDataType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_646142158918d547, []int{0} +} + type HandshakeMetadata struct { // This address is where the subscriber chain will send the fees proportionally CoordinatorFeePoolAddr string `protobuf:"bytes,1,opt,name=coordinator_fee_pool_addr,json=coordinatorFeePoolAddr,proto3" json:"coordinator_fee_pool_addr,omitempty"` @@ -78,6 +113,219 @@ func (m *HandshakeMetadata) GetVersion() string { return "" } +// SlashPacketData is sent from the subscriber chain to the coordinator chain +// to request the slashing of a validator as a result of an infraction committed +// on the subscriber chain. +type SlashPacketData struct { + // validator is the validator to be slashed + Validator types.Validator `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator" yaml:"validator"` + // valset_update_id is the id of the validator set change during which + // the infraction was committed + ValsetUpdateID uint64 `protobuf:"varint,2,opt,name=valset_update_id,json=valsetUpdateId,proto3" json:"valset_update_id,omitempty"` + // infraction refers to the type of infraction committed + Infraction types1.Infraction `protobuf:"varint,3,opt,name=infraction,proto3,enum=cosmos.staking.v1beta1.Infraction" json:"infraction,omitempty"` +} + +func (m *SlashPacketData) Reset() { *m = SlashPacketData{} } +func (m *SlashPacketData) String() string { return proto.CompactTextString(m) } +func (*SlashPacketData) ProtoMessage() {} +func (*SlashPacketData) Descriptor() ([]byte, []int) { + return fileDescriptor_646142158918d547, []int{1} +} +func (m *SlashPacketData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SlashPacketData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SlashPacketData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SlashPacketData) XXX_Merge(src proto.Message) { + xxx_messageInfo_SlashPacketData.Merge(m, src) +} +func (m *SlashPacketData) XXX_Size() int { + return m.Size() +} +func (m *SlashPacketData) XXX_DiscardUnknown() { + xxx_messageInfo_SlashPacketData.DiscardUnknown(m) +} + +var xxx_messageInfo_SlashPacketData proto.InternalMessageInfo + +func (m *SlashPacketData) GetValidator() types.Validator { + if m != nil { + return m.Validator + } + return types.Validator{} +} + +func (m *SlashPacketData) GetValsetUpdateID() uint64 { + if m != nil { + return m.ValsetUpdateID + } + return 0 +} + +func (m *SlashPacketData) GetInfraction() types1.Infraction { + if m != nil { + return m.Infraction + } + return types1.Infraction_INFRACTION_UNSPECIFIED +} + +// VscMaturedPacketData is sent from the subscriber chain to the coordinator chain +// to indicate that a VSC has matured and unbondings associated with that VSC +// can now be released. +type VscMaturedPacketData struct { + // valset_update_id is the id of the validator set change to mature. + ValsetUpdateID uint64 `protobuf:"varint,1,opt,name=valset_update_id,json=valsetUpdateId,proto3" json:"valset_update_id,omitempty"` +} + +func (m *VscMaturedPacketData) Reset() { *m = VscMaturedPacketData{} } +func (m *VscMaturedPacketData) String() string { return proto.CompactTextString(m) } +func (*VscMaturedPacketData) ProtoMessage() {} +func (*VscMaturedPacketData) Descriptor() ([]byte, []int) { + return fileDescriptor_646142158918d547, []int{2} +} +func (m *VscMaturedPacketData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VscMaturedPacketData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VscMaturedPacketData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *VscMaturedPacketData) XXX_Merge(src proto.Message) { + xxx_messageInfo_VscMaturedPacketData.Merge(m, src) +} +func (m *VscMaturedPacketData) XXX_Size() int { + return m.Size() +} +func (m *VscMaturedPacketData) XXX_DiscardUnknown() { + xxx_messageInfo_VscMaturedPacketData.DiscardUnknown(m) +} + +var xxx_messageInfo_VscMaturedPacketData proto.InternalMessageInfo + +func (m *VscMaturedPacketData) GetValsetUpdateID() uint64 { + if m != nil { + return m.ValsetUpdateID + } + return 0 +} + +// SubscriberPacketData is a wrapped message that contains the type of packet +// and the data associated with that packet. +type SubscriberPacketData struct { + // type is the type of packet sent + Type SubscriberPacketDataType `protobuf:"varint,1,opt,name=type,proto3,enum=exocore.appchain.common.v1.SubscriberPacketDataType" json:"type,omitempty"` + // data is the data associated with the packet + // + // Types that are valid to be assigned to Data: + // *SubscriberPacketData_SlashPacketData + // *SubscriberPacketData_VscMaturedPacketData + Data isSubscriberPacketData_Data `protobuf_oneof:"data"` +} + +func (m *SubscriberPacketData) Reset() { *m = SubscriberPacketData{} } +func (m *SubscriberPacketData) String() string { return proto.CompactTextString(m) } +func (*SubscriberPacketData) ProtoMessage() {} +func (*SubscriberPacketData) Descriptor() ([]byte, []int) { + return fileDescriptor_646142158918d547, []int{3} +} +func (m *SubscriberPacketData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SubscriberPacketData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SubscriberPacketData.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SubscriberPacketData) XXX_Merge(src proto.Message) { + xxx_messageInfo_SubscriberPacketData.Merge(m, src) +} +func (m *SubscriberPacketData) XXX_Size() int { + return m.Size() +} +func (m *SubscriberPacketData) XXX_DiscardUnknown() { + xxx_messageInfo_SubscriberPacketData.DiscardUnknown(m) +} + +var xxx_messageInfo_SubscriberPacketData proto.InternalMessageInfo + +type isSubscriberPacketData_Data interface { + isSubscriberPacketData_Data() + MarshalTo([]byte) (int, error) + Size() int +} + +type SubscriberPacketData_SlashPacketData struct { + SlashPacketData *SlashPacketData `protobuf:"bytes,2,opt,name=slash_packet_data,json=slashPacketData,proto3,oneof" json:"slash_packet_data,omitempty"` +} +type SubscriberPacketData_VscMaturedPacketData struct { + VscMaturedPacketData *VscMaturedPacketData `protobuf:"bytes,3,opt,name=vsc_matured_packet_data,json=vscMaturedPacketData,proto3,oneof" json:"vsc_matured_packet_data,omitempty"` +} + +func (*SubscriberPacketData_SlashPacketData) isSubscriberPacketData_Data() {} +func (*SubscriberPacketData_VscMaturedPacketData) isSubscriberPacketData_Data() {} + +func (m *SubscriberPacketData) GetData() isSubscriberPacketData_Data { + if m != nil { + return m.Data + } + return nil +} + +func (m *SubscriberPacketData) GetType() SubscriberPacketDataType { + if m != nil { + return m.Type + } + return UnspecifiedPacket +} + +func (m *SubscriberPacketData) GetSlashPacketData() *SlashPacketData { + if x, ok := m.GetData().(*SubscriberPacketData_SlashPacketData); ok { + return x.SlashPacketData + } + return nil +} + +func (m *SubscriberPacketData) GetVscMaturedPacketData() *VscMaturedPacketData { + if x, ok := m.GetData().(*SubscriberPacketData_VscMaturedPacketData); ok { + return x.VscMaturedPacketData + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*SubscriberPacketData) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*SubscriberPacketData_SlashPacketData)(nil), + (*SubscriberPacketData_VscMaturedPacketData)(nil), + } +} + // ValidatorSetChangePacketData is sent from the coordinator chain to the subscriber chain // containing the new validator set and the id of the validator set change. type ValidatorSetChangePacketData struct { @@ -94,7 +342,7 @@ func (m *ValidatorSetChangePacketData) Reset() { *m = ValidatorSetChange func (m *ValidatorSetChangePacketData) String() string { return proto.CompactTextString(m) } func (*ValidatorSetChangePacketData) ProtoMessage() {} func (*ValidatorSetChangePacketData) Descriptor() ([]byte, []int) { - return fileDescriptor_646142158918d547, []int{1} + return fileDescriptor_646142158918d547, []int{4} } func (m *ValidatorSetChangePacketData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -145,7 +393,11 @@ func (m *ValidatorSetChangePacketData) GetSlashAcks() []string { } func init() { + proto.RegisterEnum("exocore.appchain.common.v1.SubscriberPacketDataType", SubscriberPacketDataType_name, SubscriberPacketDataType_value) proto.RegisterType((*HandshakeMetadata)(nil), "exocore.appchain.common.v1.HandshakeMetadata") + proto.RegisterType((*SlashPacketData)(nil), "exocore.appchain.common.v1.SlashPacketData") + proto.RegisterType((*VscMaturedPacketData)(nil), "exocore.appchain.common.v1.VscMaturedPacketData") + proto.RegisterType((*SubscriberPacketData)(nil), "exocore.appchain.common.v1.SubscriberPacketData") proto.RegisterType((*ValidatorSetChangePacketData)(nil), "exocore.appchain.common.v1.ValidatorSetChangePacketData") } @@ -154,34 +406,53 @@ func init() { } var fileDescriptor_646142158918d547 = []byte{ - // 420 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0x4f, 0x6f, 0xd3, 0x4c, - 0x10, 0xc6, 0xe3, 0x37, 0xaf, 0x40, 0x59, 0xa4, 0x8a, 0x5a, 0x08, 0x99, 0x00, 0x8e, 0x15, 0x81, - 0x94, 0x93, 0x57, 0x81, 0x53, 0x11, 0x97, 0x86, 0x82, 0xe0, 0x00, 0xaa, 0x52, 0xd1, 0x03, 0x17, - 0x6b, 0xb2, 0x3b, 0xd8, 0x2b, 0xdb, 0x3b, 0xd6, 0xee, 0xd6, 0x6d, 0xbf, 0x05, 0x1f, 0xab, 0xc7, - 0x1e, 0x39, 0x45, 0x28, 0xb9, 0x72, 0xe2, 0x13, 0x20, 0xdb, 0x31, 0x14, 0xf5, 0x36, 0x7f, 0x7e, - 0xf3, 0xec, 0x8e, 0x9e, 0x61, 0xcf, 0xf1, 0x82, 0x04, 0x19, 0xe4, 0x50, 0x55, 0x22, 0x03, 0xa5, - 0xb9, 0xa0, 0xb2, 0x24, 0xcd, 0xeb, 0x39, 0x3f, 0x57, 0x06, 0xe3, 0xca, 0x90, 0x23, 0x7f, 0xbc, - 0xc3, 0xe2, 0x1e, 0x8b, 0x3b, 0x2c, 0xae, 0xe7, 0xe3, 0x67, 0x82, 0x6c, 0x49, 0x96, 0x5b, 0x07, - 0xb9, 0xd2, 0x29, 0xaf, 0xe7, 0x2b, 0x74, 0x30, 0xef, 0xf3, 0x4e, 0x61, 0xfc, 0x20, 0xa5, 0x94, - 0xda, 0x90, 0x37, 0xd1, 0xae, 0xfa, 0xd8, 0xa1, 0x96, 0x68, 0x4a, 0xa5, 0x1d, 0x87, 0x95, 0x50, - 0xdc, 0x5d, 0x56, 0x68, 0xbb, 0xe6, 0x34, 0x63, 0xfb, 0xef, 0x41, 0x4b, 0x9b, 0x41, 0x8e, 0x1f, - 0xd1, 0x81, 0x04, 0x07, 0xfe, 0x01, 0x7b, 0x24, 0x88, 0x8c, 0x54, 0x1a, 0x1c, 0x99, 0xe4, 0x2b, - 0x62, 0x52, 0x11, 0x15, 0x09, 0x48, 0x69, 0x02, 0x2f, 0xf2, 0x66, 0xa3, 0xe5, 0xc3, 0x1b, 0xc0, - 0x3b, 0xc4, 0x63, 0xa2, 0xe2, 0x50, 0x4a, 0xe3, 0x07, 0xec, 0x6e, 0x8d, 0xc6, 0x2a, 0xd2, 0xc1, - 0x7f, 0x2d, 0xd8, 0xa7, 0xd3, 0x9f, 0x1e, 0x7b, 0x72, 0x0a, 0x85, 0x92, 0xcd, 0xc8, 0x09, 0xba, - 0x37, 0x19, 0xe8, 0x14, 0x8f, 0x41, 0xe4, 0xe8, 0x8e, 0x9a, 0x57, 0x89, 0xed, 0xd7, 0x7d, 0x3f, - 0x39, 0xab, 0x24, 0x38, 0xb4, 0x81, 0x17, 0x0d, 0x67, 0xf7, 0x5e, 0x44, 0xf1, 0xdf, 0x1d, 0xe2, - 0x66, 0x87, 0xf8, 0x8f, 0xd2, 0xe7, 0x16, 0x5c, 0x44, 0x57, 0xeb, 0xc9, 0xe0, 0xd7, 0x7a, 0x12, - 0x5c, 0x42, 0x59, 0xbc, 0x9a, 0xde, 0x12, 0x9a, 0x2e, 0xef, 0xd7, 0xff, 0x8e, 0x58, 0xff, 0x35, - 0x6b, 0x6a, 0x16, 0xdd, 0x0e, 0x4a, 0x94, 0x6c, 0x3f, 0xfd, 0xff, 0xc2, 0xdf, 0xac, 0x27, 0x7b, - 0xa7, 0x6d, 0xaf, 0x83, 0x3f, 0x1c, 0x2d, 0xf7, 0xea, 0x9b, 0xb9, 0xf4, 0x9f, 0x32, 0x66, 0x0b, - 0xb0, 0x59, 0x02, 0x22, 0xb7, 0xc1, 0x30, 0x1a, 0xce, 0x46, 0xcb, 0x51, 0x5b, 0x39, 0x14, 0xb9, - 0x5d, 0x9c, 0x5c, 0x6d, 0x42, 0xef, 0x7a, 0x13, 0x7a, 0x3f, 0x36, 0xa1, 0xf7, 0x6d, 0x1b, 0x0e, - 0xae, 0xb7, 0xe1, 0xe0, 0xfb, 0x36, 0x1c, 0x7c, 0x39, 0x48, 0x95, 0xcb, 0xce, 0x56, 0x8d, 0xbb, - 0xfc, 0x6d, 0x67, 0xf9, 0x27, 0x74, 0xe7, 0x64, 0x72, 0xde, 0x1f, 0xca, 0xc5, 0xad, 0x53, 0x69, - 0x3d, 0x5b, 0xdd, 0x69, 0x4d, 0x7b, 0xf9, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x29, 0x74, 0xa9, 0x8a, - 0x52, 0x02, 0x00, 0x00, + // 730 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x41, 0x6f, 0xda, 0x48, + 0x14, 0xb6, 0x03, 0xca, 0x8a, 0x41, 0x22, 0x60, 0xb1, 0xbb, 0x5e, 0x6f, 0x96, 0x58, 0xd6, 0xae, + 0x84, 0x76, 0x25, 0x7b, 0xa1, 0xbd, 0xa4, 0x4a, 0x0f, 0x18, 0x88, 0x40, 0x6d, 0x22, 0x64, 0x03, + 0x52, 0x7a, 0xb1, 0x06, 0x7b, 0x02, 0x23, 0xc0, 0x63, 0x79, 0x06, 0x27, 0xf9, 0x07, 0x55, 0x4e, + 0xfd, 0x03, 0x39, 0xf5, 0xde, 0xdf, 0x91, 0x63, 0x8e, 0x3d, 0x45, 0x15, 0x39, 0xf4, 0xd2, 0x53, + 0x7f, 0x41, 0x65, 0x1b, 0x13, 0x92, 0x42, 0x54, 0xa9, 0xb7, 0x99, 0x79, 0xef, 0x7d, 0xef, 0xcd, + 0xf7, 0x7d, 0x7a, 0xe0, 0x1f, 0x74, 0x4e, 0x6c, 0xe2, 0x23, 0x0d, 0x7a, 0x9e, 0x3d, 0x82, 0xd8, + 0xd5, 0x6c, 0x32, 0x9d, 0x12, 0x57, 0x0b, 0x2a, 0xda, 0x19, 0xf6, 0x91, 0xea, 0xf9, 0x84, 0x11, + 0x41, 0x5a, 0xa4, 0xa9, 0x49, 0x9a, 0x1a, 0xa7, 0xa9, 0x41, 0x45, 0xfa, 0xdb, 0x26, 0x74, 0x4a, + 0xa8, 0x46, 0x19, 0x1c, 0x63, 0x77, 0xa8, 0x05, 0x95, 0x01, 0x62, 0xb0, 0x92, 0xdc, 0x63, 0x04, + 0xa9, 0x38, 0x24, 0x43, 0x12, 0x1d, 0xb5, 0xf0, 0xb4, 0x78, 0xfd, 0x93, 0x21, 0xd7, 0x41, 0xfe, + 0x14, 0xbb, 0x4c, 0x83, 0x03, 0x1b, 0x6b, 0xec, 0xc2, 0x43, 0x34, 0x0e, 0x2a, 0x23, 0x50, 0x68, + 0x41, 0xd7, 0xa1, 0x23, 0x38, 0x46, 0x47, 0x88, 0x41, 0x07, 0x32, 0x28, 0xec, 0x83, 0x3f, 0x6c, + 0x42, 0x7c, 0x07, 0xbb, 0x90, 0x11, 0xdf, 0x3a, 0x45, 0xc8, 0xf2, 0x08, 0x99, 0x58, 0xd0, 0x71, + 0x7c, 0x91, 0x97, 0xf9, 0x72, 0xc6, 0xf8, 0x6d, 0x25, 0xe1, 0x10, 0xa1, 0x0e, 0x21, 0x93, 0x9a, + 0xe3, 0xf8, 0x82, 0x08, 0x7e, 0x09, 0x90, 0x4f, 0x31, 0x71, 0xc5, 0xad, 0x28, 0x31, 0xb9, 0x2a, + 0x9f, 0x79, 0xb0, 0x63, 0x4e, 0x20, 0x1d, 0x75, 0xa0, 0x3d, 0x46, 0xac, 0x11, 0x36, 0x32, 0x40, + 0x26, 0x80, 0x13, 0xec, 0x84, 0x28, 0x11, 0x70, 0xb6, 0x2a, 0xa9, 0xf7, 0xe3, 0xaa, 0xe1, 0xb8, + 0x6a, 0x3f, 0xc9, 0xd0, 0xc5, 0xeb, 0xdb, 0x3d, 0xee, 0xeb, 0xed, 0x5e, 0xfe, 0x02, 0x4e, 0x27, + 0x2f, 0x94, 0x65, 0xa9, 0x62, 0xdc, 0xc3, 0x08, 0x07, 0x20, 0x1f, 0xc0, 0x09, 0x45, 0xcc, 0x9a, + 0x79, 0x0e, 0x64, 0xc8, 0xc2, 0x4e, 0x34, 0x4a, 0x5a, 0x17, 0xe6, 0xb7, 0x7b, 0xb9, 0x7e, 0x14, + 0xeb, 0x45, 0xa1, 0x76, 0xc3, 0xc8, 0x05, 0xab, 0x77, 0x47, 0xd0, 0x01, 0xc0, 0xee, 0xa9, 0x0f, + 0x6d, 0x16, 0x7e, 0x21, 0x25, 0xf3, 0xe5, 0x5c, 0x55, 0x51, 0x63, 0xf6, 0xd5, 0x84, 0xed, 0x05, + 0xfb, 0x6a, 0x7b, 0x99, 0x69, 0xac, 0x54, 0x29, 0x5d, 0x50, 0xec, 0x53, 0xfb, 0x08, 0xb2, 0x99, + 0x8f, 0x9c, 0x95, 0xdf, 0xae, 0x9b, 0x8c, 0xff, 0xd1, 0xc9, 0x94, 0x0f, 0x5b, 0xa0, 0x68, 0xce, + 0x06, 0xd4, 0xf6, 0xf1, 0x00, 0xf9, 0x2b, 0xb0, 0x2d, 0x90, 0x0e, 0x15, 0x8d, 0xa0, 0x72, 0xd5, + 0xe7, 0xea, 0x66, 0x1b, 0xa9, 0xeb, 0xea, 0xbb, 0x17, 0x1e, 0x32, 0x22, 0x04, 0xe1, 0x04, 0x14, + 0x68, 0xa8, 0x90, 0xe5, 0x45, 0x51, 0x2b, 0x34, 0x43, 0xc4, 0x5d, 0xb6, 0xfa, 0xdf, 0x93, 0xb0, + 0x0f, 0x65, 0x6d, 0x71, 0xc6, 0x0e, 0x7d, 0xa4, 0x34, 0x06, 0xbf, 0x07, 0xd4, 0xb6, 0xa6, 0x31, + 0x29, 0x0f, 0x1a, 0xa4, 0xa2, 0x06, 0xff, 0x3f, 0xd5, 0x60, 0x1d, 0x9d, 0x2d, 0xce, 0x28, 0x06, + 0x6b, 0xde, 0xf5, 0x6d, 0x90, 0x0e, 0x71, 0x95, 0x2f, 0x3c, 0xd8, 0x5d, 0x7a, 0xc7, 0x44, 0xac, + 0x3e, 0x82, 0xee, 0x10, 0xad, 0xcc, 0x44, 0x40, 0x61, 0x69, 0x9b, 0x85, 0x24, 0x54, 0xe4, 0xe5, + 0x54, 0x39, 0x5b, 0x95, 0x37, 0xbb, 0x30, 0x16, 0x44, 0x97, 0x17, 0x5e, 0x14, 0x1f, 0x79, 0x31, + 0x01, 0x52, 0x8c, 0x7c, 0xf0, 0xb0, 0x84, 0xfe, 0xa4, 0x35, 0xff, 0x02, 0x20, 0x56, 0x07, 0xda, + 0x63, 0x2a, 0xa6, 0xe4, 0x54, 0x39, 0x63, 0x64, 0xa2, 0x97, 0x9a, 0x3d, 0xa6, 0xff, 0xde, 0xf0, + 0x40, 0xdc, 0xa4, 0xaf, 0xf0, 0x12, 0x28, 0x66, 0x4f, 0x37, 0xeb, 0x46, 0x5b, 0x6f, 0x1a, 0x56, + 0xa7, 0x56, 0x7f, 0xd5, 0xec, 0x5a, 0xdd, 0x93, 0x4e, 0xd3, 0xea, 0x1d, 0x9b, 0x9d, 0x66, 0xbd, + 0x7d, 0xd8, 0x6e, 0x36, 0xf2, 0x9c, 0xf4, 0xeb, 0xe5, 0x95, 0x5c, 0xe8, 0xb9, 0xd4, 0x43, 0x36, + 0x3e, 0xc5, 0x09, 0xad, 0x42, 0x05, 0xec, 0x6e, 0x28, 0x37, 0x5f, 0xd7, 0xcc, 0x56, 0x9e, 0x97, + 0x76, 0x2e, 0xaf, 0xe4, 0xec, 0x8a, 0x0f, 0x84, 0x83, 0x8d, 0x1d, 0xfb, 0x66, 0xdd, 0x3a, 0xaa, + 0x75, 0x7b, 0x46, 0xb3, 0x91, 0xdf, 0x92, 0x8a, 0x97, 0x57, 0x72, 0xfe, 0xb1, 0xbe, 0x52, 0xfa, + 0xed, 0xfb, 0x12, 0xa7, 0x9b, 0xd7, 0xf3, 0x12, 0x7f, 0x33, 0x2f, 0xf1, 0x9f, 0xe6, 0x25, 0xfe, + 0xdd, 0x5d, 0x89, 0xbb, 0xb9, 0x2b, 0x71, 0x1f, 0xef, 0x4a, 0xdc, 0x9b, 0xfd, 0x21, 0x66, 0xa3, + 0xd9, 0x20, 0xb4, 0x88, 0xd6, 0x8c, 0x7d, 0x73, 0x8c, 0xd8, 0x19, 0xf1, 0xc7, 0x5a, 0xb2, 0x6c, + 0xcf, 0xbf, 0x5b, 0xb7, 0xd1, 0xde, 0x1b, 0x6c, 0x47, 0x8b, 0xef, 0xd9, 0xb7, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x5b, 0xc8, 0x9b, 0x3f, 0x96, 0x05, 0x00, 0x00, } func (m *HandshakeMetadata) Marshal() (dAtA []byte, err error) { @@ -221,6 +492,156 @@ func (m *HandshakeMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SlashPacketData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SlashPacketData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SlashPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Infraction != 0 { + i = encodeVarintWire(dAtA, i, uint64(m.Infraction)) + i-- + dAtA[i] = 0x18 + } + if m.ValsetUpdateID != 0 { + i = encodeVarintWire(dAtA, i, uint64(m.ValsetUpdateID)) + i-- + dAtA[i] = 0x10 + } + { + size, err := m.Validator.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWire(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *VscMaturedPacketData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VscMaturedPacketData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VscMaturedPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ValsetUpdateID != 0 { + i = encodeVarintWire(dAtA, i, uint64(m.ValsetUpdateID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SubscriberPacketData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SubscriberPacketData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SubscriberPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Data != nil { + { + size := m.Data.Size() + i -= size + if _, err := m.Data.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.Type != 0 { + i = encodeVarintWire(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SubscriberPacketData_SlashPacketData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SubscriberPacketData_SlashPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.SlashPacketData != nil { + { + size, err := m.SlashPacketData.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWire(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *SubscriberPacketData_VscMaturedPacketData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SubscriberPacketData_VscMaturedPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.VscMaturedPacketData != nil { + { + size, err := m.VscMaturedPacketData.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWire(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} func (m *ValidatorSetChangePacketData) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -300,38 +721,106 @@ func (m *HandshakeMetadata) Size() (n int) { return n } -func (m *ValidatorSetChangePacketData) Size() (n int) { +func (m *SlashPacketData) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.ValidatorUpdates) > 0 { - for _, e := range m.ValidatorUpdates { - l = e.Size() - n += 1 + l + sovWire(uint64(l)) - } - } + l = m.Validator.Size() + n += 1 + l + sovWire(uint64(l)) if m.ValsetUpdateID != 0 { n += 1 + sovWire(uint64(m.ValsetUpdateID)) } - if len(m.SlashAcks) > 0 { - for _, s := range m.SlashAcks { - l = len(s) - n += 1 + l + sovWire(uint64(l)) - } + if m.Infraction != 0 { + n += 1 + sovWire(uint64(m.Infraction)) } return n } -func sovWire(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozWire(x uint64) (n int) { - return sovWire(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +func (m *VscMaturedPacketData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ValsetUpdateID != 0 { + n += 1 + sovWire(uint64(m.ValsetUpdateID)) + } + return n } -func (m *HandshakeMetadata) Unmarshal(dAtA []byte) error { - l := len(dAtA) + +func (m *SubscriberPacketData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != 0 { + n += 1 + sovWire(uint64(m.Type)) + } + if m.Data != nil { + n += m.Data.Size() + } + return n +} + +func (m *SubscriberPacketData_SlashPacketData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SlashPacketData != nil { + l = m.SlashPacketData.Size() + n += 1 + l + sovWire(uint64(l)) + } + return n +} +func (m *SubscriberPacketData_VscMaturedPacketData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.VscMaturedPacketData != nil { + l = m.VscMaturedPacketData.Size() + n += 1 + l + sovWire(uint64(l)) + } + return n +} +func (m *ValidatorSetChangePacketData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ValidatorUpdates) > 0 { + for _, e := range m.ValidatorUpdates { + l = e.Size() + n += 1 + l + sovWire(uint64(l)) + } + } + if m.ValsetUpdateID != 0 { + n += 1 + sovWire(uint64(m.ValsetUpdateID)) + } + if len(m.SlashAcks) > 0 { + for _, s := range m.SlashAcks { + l = len(s) + n += 1 + l + sovWire(uint64(l)) + } + } + return n +} + +func sovWire(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozWire(x uint64) (n int) { + return sovWire(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *HandshakeMetadata) Unmarshal(dAtA []byte) error { + l := len(dAtA) iNdEx := 0 for iNdEx < l { preIndex := iNdEx @@ -444,6 +933,335 @@ func (m *HandshakeMetadata) Unmarshal(dAtA []byte) error { } return nil } +func (m *SlashPacketData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SlashPacketData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SlashPacketData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWire + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWire + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Validator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValsetUpdateID", wireType) + } + m.ValsetUpdateID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValsetUpdateID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Infraction", wireType) + } + m.Infraction = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Infraction |= types1.Infraction(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipWire(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWire + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VscMaturedPacketData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VscMaturedPacketData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VscMaturedPacketData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValsetUpdateID", wireType) + } + m.ValsetUpdateID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValsetUpdateID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipWire(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWire + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SubscriberPacketData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubscriberPacketData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubscriberPacketData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= SubscriberPacketDataType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashPacketData", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWire + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWire + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SlashPacketData{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Data = &SubscriberPacketData_SlashPacketData{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VscMaturedPacketData", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWire + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWire + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWire + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &VscMaturedPacketData{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Data = &SubscriberPacketData_VscMaturedPacketData{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWire(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWire + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ValidatorSetChangePacketData) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/appchain/coordinator/keeper/connection.go b/x/appchain/coordinator/keeper/connection.go index e8a4668a5..0eba683e6 100644 --- a/x/appchain/coordinator/keeper/connection.go +++ b/x/appchain/coordinator/keeper/connection.go @@ -20,7 +20,7 @@ import ( // as well as the channel's presence. func (k Keeper) VerifySubscriberChain( ctx sdk.Context, - channelID string, + _ string, connectionHops []string, ) error { if len(connectionHops) != 1 { @@ -127,7 +127,13 @@ func (k Keeper) SetSubscriberChain(ctx sdk.Context, channelID string) error { // - set current block height for the subscriber chain initialization k.SetInitChainHeight(ctx, chainID, uint64(ctx.BlockHeight())) // remove init timeout timestamp - k.DeleteInitTimeoutTimestamp(ctx, chainID) + timeout, exists := k.GetChainInitTimeout(ctx, chainID) + if exists { + k.DeleteChainInitTimeout(ctx, chainID) + k.RemoveChainFromInitTimeout(ctx, timeout, chainID) + } else { + k.Logger(ctx).Error("timeout not found for chain", "chainID", chainID) + } // emit event on successful addition ctx.EventManager().EmitEvent( diff --git a/x/appchain/coordinator/keeper/height.go b/x/appchain/coordinator/keeper/height.go new file mode 100644 index 000000000..8740c57b0 --- /dev/null +++ b/x/appchain/coordinator/keeper/height.go @@ -0,0 +1,21 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// MapHeightToChainVscID stores the height corresponding to a chainID and vscID +func (k Keeper) MapHeightToChainVscID(ctx sdk.Context, chainID string, vscID uint64, height uint64) { + store := ctx.KVStore(k.storeKey) + key := types.HeightToChainVscIDKey(chainID, vscID) + store.Set(key, sdk.Uint64ToBigEndian(height)) +} + +// GetHeightForChainVscID gets the height corresponding to a chainID and vscID +func (k Keeper) GetHeightForChainVscID(ctx sdk.Context, chainID string, vscID uint64) uint64 { + store := ctx.KVStore(k.storeKey) + key := types.HeightToChainVscIDKey(chainID, vscID) + // if store.Has(key) is false will return a height of 0 + return sdk.BigEndianToUint64(store.Get(key)) +} diff --git a/x/appchain/coordinator/keeper/ibc_client.go b/x/appchain/coordinator/keeper/ibc_client.go index b4009e045..94e96da11 100644 --- a/x/appchain/coordinator/keeper/ibc_client.go +++ b/x/appchain/coordinator/keeper/ibc_client.go @@ -4,10 +4,10 @@ import ( "fmt" errorsmod "cosmossdk.io/errors" + exocoretypes "github.com/ExocoreNetwork/exocore/types" "github.com/ExocoreNetwork/exocore/utils" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -92,7 +92,10 @@ func (k Keeper) CreateClientForSubscriber( // assume we start with a value of 2 and we are giving 4 full epochs for initialization. // so when epoch 6 ends, the timeout ends. initTimeoutPeriod.EpochNumber += uint64(epochInfo.CurrentEpoch) + 1 + // lookup from timeout to chainID k.AppendChainToInitTimeout(ctx, initTimeoutPeriod, chainID) + // reverse lookup from chainID to timeout + k.SetChainInitTimeout(ctx, chainID, initTimeoutPeriod) k.Logger(ctx).Info( "subscriber chain registered (client created)", @@ -131,7 +134,7 @@ func (k Keeper) MakeSubscriberGenesis( params := k.GetParams(ctx) chainID := req.ChainID k.Logger(ctx).Info("Creating genesis state for subscriber chain", "chainID", chainID) - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(chainID) + chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(chainID) coordinatorUnbondingPeriod := k.stakingKeeper.UnbondingTime(ctx) // client state clientState := params.TemplateClient @@ -158,6 +161,7 @@ func (k Keeper) MakeSubscriberGenesis( err, chainID, ) } + // all consensus key related operations are indexed by chainIDWithoutRevision operators, keys := k.operatorKeeper.GetActiveOperatorsForChainID(ctx, chainIDWithoutRevision) powers, err := k.operatorKeeper.GetVotePowerForChainID( ctx, operators, chainIDWithoutRevision, diff --git a/x/appchain/coordinator/keeper/impl_epochs_hooks.go b/x/appchain/coordinator/keeper/impl_epochs_hooks.go index bd313cc80..26e4bc58f 100644 --- a/x/appchain/coordinator/keeper/impl_epochs_hooks.go +++ b/x/appchain/coordinator/keeper/impl_epochs_hooks.go @@ -1,7 +1,7 @@ package keeper import ( - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -42,7 +42,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( ) // clear the registered AVS. remember that this module stores // the chainID with the revision but the AVS module stores it without. - chainID := avstypes.ChainIDWithoutRevision(subscriber.ChainID) + chainID := exocoretypes.ChainIDWithoutRevision(subscriber.ChainID) // always guaranteed to exist _, addr := wrapper.keeper.avsKeeper.IsAVSByChainID(ctx, chainID) if err := wrapper.keeper.avsKeeper.DeleteAVSInfo(ctx, addr); err != nil { diff --git a/x/appchain/coordinator/keeper/keeper.go b/x/appchain/coordinator/keeper/keeper.go index 366ed1228..354bd1f35 100644 --- a/x/appchain/coordinator/keeper/keeper.go +++ b/x/appchain/coordinator/keeper/keeper.go @@ -25,6 +25,7 @@ type Keeper struct { scopedKeeper commontypes.ScopedKeeper channelKeeper commontypes.ChannelKeeper connectionKeeper commontypes.ConnectionKeeper + accountKeeper commontypes.AccountKeeper } // NewKeeper creates a new coordinator keeper. @@ -40,6 +41,7 @@ func NewKeeper( scopedKeeper commontypes.ScopedKeeper, channelKeeper commontypes.ChannelKeeper, connectionKeeper commontypes.ConnectionKeeper, + accountKeeper commontypes.AccountKeeper, ) Keeper { return Keeper{ cdc: cdc, @@ -53,6 +55,7 @@ func NewKeeper( scopedKeeper: scopedKeeper, channelKeeper: channelKeeper, connectionKeeper: connectionKeeper, + accountKeeper: accountKeeper, } } @@ -64,8 +67,8 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // BindPort defines a wrapper function for the port Keeper's function in // order to expose it to module's InitGenesis function func (k Keeper) BindPort(ctx sdk.Context, portID string) error { - cap := k.portKeeper.BindPort(ctx, portID) - return k.ClaimCapability(ctx, cap, host.PortPath(portID)) + capability := k.portKeeper.BindPort(ctx, portID) + return k.ClaimCapability(ctx, capability, host.PortPath(portID)) } // GetPort returns the portID for the IBC app module. Used in ExportGenesis diff --git a/x/appchain/coordinator/keeper/relay.go b/x/appchain/coordinator/keeper/relay.go new file mode 100644 index 000000000..4ee8bdb0b --- /dev/null +++ b/x/appchain/coordinator/keeper/relay.go @@ -0,0 +1,182 @@ +package keeper + +import ( + "fmt" + + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" +) + +// OnRecvSlashPacket processes a slashing packet upon its receipt from +// the subscriber chain. At this point, it only handles DOWNTIME infractions. +// TODO: Design and implement EQUIVOCATION slashing. +// The returned value is a byte slice containing the acknowledgment to send to +// the sender. Otherwise, it should be an error. +func (k Keeper) OnRecvSlashPacket( + ctx sdk.Context, packet channeltypes.Packet, data commontypes.SlashPacketData, +) ([]byte, error) { + chainID, found := k.GetChainForChannel(ctx, packet.DestinationChannel) + if !found { + k.Logger(ctx).Error( + "received slash packet for unknown channel", + "channel", packet.DestinationChannel, + ) + return nil, types.ErrUnknownSubscriberChannelID.Wrapf( + "slash packet on %s", packet.DestinationChannel, + ) + } + // stateless validation + if err := data.Validate(); err != nil { + return nil, commontypes.ErrInvalidPacketData.Wrapf( + "invalid slash packet: %s", err, + ) + } + // stateful validation + if err := k.ValidateSlashPacket(ctx, chainID, data); err != nil { + k.Logger(ctx).Error( + "invalid slash packet", + "error", err, + "chainID", chainID, + "vscID", data.ValsetUpdateID, + "consensus address", fmt.Sprintf("%x", data.Validator.Address), + "infraction type", data.Infraction, + ) + return nil, commontypes.ErrInvalidPacketData.Wrapf( + "invalid slash packet %s", err, + ) + } + // TODO: handle throttling of slash packets to ensure that malicious / misconfigured + // appchains don't spam the coordinator with slash packets to produce repeated + // slashing events. When throttling is implemented, indicate to the subscriber + // that a packet wasn't handled and should be retried later. + k.HandleSlashPacket(ctx, chainID, data) + k.Logger(ctx).Info( + "slash packet received and handled", + "chainID", chainID, + "consensus address", fmt.Sprintf("%x", data.Validator.Address), + "vscID", data.ValsetUpdateID, + "infractionType", data.Infraction, + ) + + // Return result ack that the packet was handled successfully + return commontypes.SlashPacketHandledResult, nil +} + +// OnRecvVscMaturedPacket handles a VscMatured packet and returns a no-op result ack. +func (k Keeper) OnRecvVscMaturedPacket( + ctx sdk.Context, + packet channeltypes.Packet, + data commontypes.VscMaturedPacketData, +) error { + // check that the channel is established, panic if not + chainID, found := k.GetChainForChannel(ctx, packet.DestinationChannel) + if !found { + // VSCMatured packet was sent on a channel different than any of the established + // channels; this should never happen + k.Logger(ctx).Error( + "VscMaturedPacket received on unknown channel", + "channelID", packet.DestinationChannel, + ) + return types.ErrUnknownSubscriberChannelID.Wrapf( + "vsc matured packet on %s", packet.DestinationChannel, + ) + } + + k.HandleVscMaturedPacket(ctx, chainID, data) + + k.Logger(ctx).Info( + "VscMaturedPacket handled", + "chainID", chainID, + "vscID", data.ValsetUpdateID, + ) + + return nil +} + +// HandleVscMaturedPacket handles a VscMatured packet. +func (k Keeper) HandleVscMaturedPacket( + sdk.Context, string, commontypes.VscMaturedPacketData, +) { + // records := k.GetUndelegationsToMature(ctx, chainID, data.ValsetUpdateID) + // // this is matured at EndBlock, because the delegation keeper only releases the funds + // // at EndBlock. it is pointless to mature any of these now. + // // do note that this is the reason that the EndBlocker of this module is triggered + // // before that of the undelegation module. + // k.AppendMaturedUndelegations(ctx, records) + // k.ClearUndelegationsToMature(ctx, chainID, data.ValsetUpdateID) + + // operators := k.GetOptOutsToFinish(ctx, chainID, data.ValsetUpdateID) + // k.AppendFinishedOptOutsForChainID(ctx, chainID, operators) + // k.ClearOptOutsToFinish(ctx, chainID, data.ValsetUpdateID) + + // // if there are any opt outs, the key can be removed. similarly, + // // if there are any key replacements, the old key should be pruned + // addrs := k.GetConsensusKeysToPrune(ctx, chainID, data.ValsetUpdateID) + // for _, addr := range addrs { + // // this is pruned immediately so that an operator may reuse the same key immediately + // k.Logger(ctx).Debug("pruning key", "addr", addr, "chainId", chainID) + // k.operatorKeeper.DeleteOperatorAddressForChainIDAndConsAddr(ctx, chainID, addr) + // } + // k.ClearConsensusKeysToPrune(ctx, chainID, data.ValsetUpdateID) +} + +// OnAcknowledgementPacket handles acknowledgments for sent VSC packets +func (k Keeper) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + ack channeltypes.Acknowledgement, +) error { + if err := ack.GetError(); err != "" { + k.Logger(ctx).Error( + "recv ErrorAcknowledgement", + "channelID", packet.SourceChannel, + "error", err, + ) + if chainID, ok := k.GetChainForChannel(ctx, packet.DestinationChannel); ok { + return k.StopSubscriberChain(ctx, chainID, false) + } + return types.ErrUnknownSubscriberChannelID.Wrapf( + "ack packet on %s", packet.DestinationChannel, + ) + } + return nil +} + +// OnTimeoutPacket aborts the transaction if no chain exists for the destination channel, +// otherwise it stops the chain +func (k Keeper) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet) error { + chainID, found := k.GetChainForChannel(ctx, packet.SourceChannel) + if !found { + k.Logger(ctx).Error( + "packet timeout, unknown channel", + "channelID", packet.SourceChannel, + ) + return types.ErrUnknownSubscriberChannelID.Wrapf( + "ack packet on %s", packet.DestinationChannel, + ) + } + // stop chain and release unbondings + k.Logger(ctx).Info( + "packet timeout, removing the consumer", + "chainID", chainID, + ) + return k.StopSubscriberChain(ctx, chainID, false) +} + +// StopSubscriberChain stops the subscriber chain and releases any unbondings. +// During the stoppage, it will prune any information that is no longer needed +// to save space. +// The closeChannel flag indicates whether the channel should be closed. +func (k Keeper) StopSubscriberChain( + ctx sdk.Context, chainID string, closeChannel bool, +) error { + k.Logger(ctx).Info( + "stopping subscriber chain", + "chainID", chainID, + "closeChannel", closeChannel, + ) + // not yet implemented + return nil +} diff --git a/x/appchain/coordinator/keeper/slash.go b/x/appchain/coordinator/keeper/slash.go index 5f4f6cb61..e84d476ef 100644 --- a/x/appchain/coordinator/keeper/slash.go +++ b/x/appchain/coordinator/keeper/slash.go @@ -3,12 +3,95 @@ package keeper import ( "time" + exocoretypes "github.com/ExocoreNetwork/exocore/types" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" types "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) -// TODO: this file should be in the x/avs keeper instead. +// ValidateSlashPacket validates a slashing packet. It checks that +// (1) the valset update id maps back to an Exocore height, and +// (2) the validator (cons) address maps back to an operator account address. +// The caller must perform stateless validation by themselves. +func (k Keeper) ValidateSlashPacket( + ctx sdk.Context, chainID string, data commontypes.SlashPacketData, +) error { + // the validator set is generated at each epoch and following each slash. even if the set + // does not change at each epoch, we send an empty update anyway since, otherwise, the + // subscriber could time out the coordinator. + if k.GetHeightForChainVscID(ctx, chainID, data.ValsetUpdateID) == 0 { + return commontypes.ErrInvalidPacketData.Wrapf( + "invalid chainID %s valsetUpdateID %d", chainID, data.ValsetUpdateID, + ) + } + // the second step is to find the operator account address against the consensus address + // of the validator. if the operator is not found, the slashing packet is invalid. + // note that this works even if the operator changes their consensus key, as long as the + // key hasn't yet been pruned from the operator module. + if found, _ := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( + ctx, chainID, sdk.ConsAddress(data.Validator.Address), + ); !found { + // don't bech32 encode it in the error since the appchain may have a different prefix + return commontypes.ErrInvalidPacketData.Wrapf( + "operator not found %x", data.Validator.Address, + ) + } + return nil +} + +// HandleSlashPacket handles a slashing packet. The caller must ensure that the slashing packet +// is valid before calling this function. The function forwards the slashing request to the +// operator module, which will trigger a slashing hook and thus a validator set update containing +// the slashing acknowledgment. +func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data commontypes.SlashPacketData) { + consAddress := sdk.ConsAddress(data.Validator.Address) + // never 0, since already validated + height := k.GetHeightForChainVscID(ctx, chainID, data.ValsetUpdateID) + // guaranteed to exist, since already validated + _, operatorAccAddress := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( + ctx, chainID, consAddress, + ) + slashProportion := k.GetSubSlashFractionDowntime(ctx, chainID) + // #nosec G703 // already validated + slashProportionDecimal, _ := sdk.NewDecFromStr(slashProportion) + jailDuration := k.GetSubDowntimeJailDuration(ctx, chainID) + chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(chainID) + _, avsAddress := k.avsKeeper.IsAVSByChainID(ctx, chainIDWithoutRevision) + // the slashing hook should trigger a validator set update for all affected AVSs. since the `chainID` is one of them + // we should make sure we are well set up for that update. we will include an ack of the slash packet in the next + // validator set update; record that here. + k.AppendSlashAck(ctx, chainID, consAddress) + k.operatorKeeper.ApplySlashForHeight( + ctx, operatorAccAddress, avsAddress.String(), height, + slashProportionDecimal, data.Infraction, jailDuration, + ) +} + +// AppendSlashAck appends a slashing acknowledgment for a chain, to be sent in the next validator set update. +func (k Keeper) AppendSlashAck(ctx sdk.Context, chainID string, consAddress sdk.ConsAddress) { + prev := k.GetSlashAcks(ctx, chainID) + prev.List = append(prev.List, consAddress) + k.SetSlashAcks(ctx, chainID, prev) +} + +// GetSlashAcks gets the slashing acknowledgments for a chain, to be sent in the next validator set update. +func (k Keeper) GetSlashAcks(ctx sdk.Context, chainID string) types.ConsensusAddresses { + store := ctx.KVStore(k.storeKey) + var consAddresses types.ConsensusAddresses + key := types.SlashAcksKey(chainID) + value := store.Get(key) + k.cdc.MustUnmarshal(value, &consAddresses) + return consAddresses +} + +// SetSlashAcks sets the slashing acknowledgments for a chain, to be sent in the next validator set update. +func (k Keeper) SetSlashAcks(ctx sdk.Context, chainID string, consAddresses types.ConsensusAddresses) { + store := ctx.KVStore(k.storeKey) + key := types.SlashAcksKey(chainID) + store.Set(key, k.cdc.MustMarshal(&consAddresses)) +} +// TODO: these fields should be in the AVS keeper instead. // SetSubSlashFractionDowntime sets the sub slash fraction downtime for a chain func (k Keeper) SetSubSlashFractionDowntime(ctx sdk.Context, chainID string, fraction string) { store := ctx.KVStore(k.storeKey) diff --git a/x/appchain/coordinator/keeper/timeout.go b/x/appchain/coordinator/keeper/timeout.go index d0a764a91..53157388c 100644 --- a/x/appchain/coordinator/keeper/timeout.go +++ b/x/appchain/coordinator/keeper/timeout.go @@ -33,6 +33,10 @@ func (k Keeper) SetChainsToInitTimeout( ctx sdk.Context, epoch epochstypes.Epoch, chains types.ChainIDs, ) { store := ctx.KVStore(k.storeKey) + if len(chains.List) == 0 { + store.Delete(types.InitTimeoutEpochKey(epoch)) + return + } bz := k.cdc.MustMarshal(&chains) store.Set(types.InitTimeoutEpochKey(epoch), bz) } @@ -52,11 +56,31 @@ func (k Keeper) RemoveChainFromInitTimeout( k.SetChainsToInitTimeout(ctx, epoch, prev) } -// ClearChainsToInitTimeout clears the list of chains which will timeout (if not initialized by then) -// at the end of the epoch. -func (k Keeper) ClearChainsToInitTimeout( - ctx sdk.Context, epoch epochstypes.Epoch, +// SetChainInitTimeout stores a lookup from chain to the epoch by the end of which +// it must be initialized. +func (k Keeper) SetChainInitTimeout( + ctx sdk.Context, chainID string, epoch epochstypes.Epoch, ) { store := ctx.KVStore(k.storeKey) - store.Delete(types.InitTimeoutEpochKey(epoch)) + store.Set(types.ChainInitTimeoutKey(chainID), k.cdc.MustMarshal(&epoch)) +} + +// GetChainInitTimeout returns the epoch by the end of which the chain must be initialized. +func (k Keeper) GetChainInitTimeout( + ctx sdk.Context, chainID string, +) (epoch epochstypes.Epoch, found bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ChainInitTimeoutKey(chainID)) + if bz == nil { + return epoch, false + } + k.cdc.MustUnmarshal(bz, &epoch) + return epoch, true +} + +// DeleteChainInitTimeout deletes the lookup from chain to the epoch by the end of which +// it must be initialized. +func (k Keeper) DeleteChainInitTimeout(ctx sdk.Context, chainID string) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.ChainInitTimeoutKey(chainID)) } diff --git a/x/appchain/coordinator/module_ibc.go b/x/appchain/coordinator/module_ibc.go index 1a0a09719..7496bdfe9 100644 --- a/x/appchain/coordinator/module_ibc.go +++ b/x/appchain/coordinator/module_ibc.go @@ -34,12 +34,12 @@ func NewIBCModule(k keeper.Keeper) IBCModule { // OnChanOpenInit implements the IBCModule interface func (im IBCModule) OnChanOpenInit( ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portId string, - channelId string, - chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, + _ channeltypes.Order, + _ []string, + _ string, + _ string, + _ *capabilitytypes.Capability, + _ channeltypes.Counterparty, version string, ) (string, error) { im.keeper.Logger(ctx).Debug( @@ -117,24 +117,20 @@ func (im IBCModule) OnChanOpenTry( CoordinatorFeePoolAddr: im.keeper.GetSubscriberRewardsPoolAddressStr(ctx), Version: commontypes.Version, } - // no k.cdc here so use this - mdBz, err := (&md).Marshal() - if err != nil { - return "", errorsmod.Wrapf(commontypes.ErrInvalidHandshakeMetadata, - "error marshalling ibc-try metadata: %v", err) - } + // we can use `MustMarshal` for data that we create + mdBz := commontypes.ModuleCdc.MustMarshal(&md) return string(mdBz), nil } // OnChanOpenAck implements the IBCModule interface func (im IBCModule) OnChanOpenAck( ctx sdk.Context, - portId, - channelId string, - _, - counterpartyVersion string, + _ string, + _ string, + _ string, + _ string, ) error { - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnChanOpenAck", ) return errorsmod.Wrap( @@ -145,14 +141,12 @@ func (im IBCModule) OnChanOpenAck( // OnChanOpenConfirm implements the IBCModule interface func (im IBCModule) OnChanOpenConfirm( - ctx sdk.Context, - portId string, - channelId string, + ctx sdk.Context, _ string, dstChannelID string, ) error { - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnChanOpenConfirm", ) - err := im.keeper.SetSubscriberChain(ctx, channelId) + err := im.keeper.SetSubscriberChain(ctx, dstChannelID) if err != nil { return err } @@ -161,11 +155,9 @@ func (im IBCModule) OnChanOpenConfirm( // OnChanCloseInit implements the IBCModule interface func (im IBCModule) OnChanCloseInit( - ctx sdk.Context, - portId string, - channelId string, + ctx sdk.Context, _ string, _ string, ) error { - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnChanCloseInit", ) // Disallow user-initiated channel closing for channels @@ -174,11 +166,9 @@ func (im IBCModule) OnChanCloseInit( // OnChanCloseConfirm implements the IBCModule interface func (im IBCModule) OnChanCloseConfirm( - ctx sdk.Context, - portId, - channelId string, + ctx sdk.Context, _ string, _ string, ) error { - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnChanCloseConfirm", ) return nil @@ -186,40 +176,56 @@ func (im IBCModule) OnChanCloseConfirm( // OnRecvPacket implements the IBCModule interface func (im IBCModule) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - _ sdk.AccAddress, + ctx sdk.Context, packet channeltypes.Packet, _ sdk.AccAddress, ) ibcexported.Acknowledgement { - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnRecvPacket", ) + var ( ack ibcexported.Acknowledgement data commontypes.SubscriberPacketData + err error + res []byte ) - if err := commontypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { - errAck := utils.NewErrorAcknowledgementWithLog(ctx, err) - ack = &errAck + // (1) Since this is a packet originating from the subscriber, we cannot use MustUnmarshal, + // because such packets are not guaranteed to be correctly formed. + // (2) When the subscriber chain marshals the data, it should use MarshalJSON. + if unmarshalErr := commontypes.ModuleCdc.UnmarshalJSON( + packet.GetData(), &data, + ); unmarshalErr != nil { + im.keeper.Logger(ctx).Error( + "cannot unmarshal subscriber packet data", + "error", unmarshalErr, + ) + err = sdkerrors.ErrInvalidType.Wrapf( + "cannot unmarshal coordinator packet data: %s", unmarshalErr, + ) } else { switch data.Type { case commontypes.SlashPacket: - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnRecvSlashPacket", "packet data", data, ) - ack = im.keeper.OnRecvSlashPacket(ctx, packet, *data.GetSlashPacketData()) + res, err = im.keeper.OnRecvSlashPacket(ctx, packet, *data.GetSlashPacketData()) case commontypes.VscMaturedPacket: - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnRecvVscMaturedPacket", "packet data", data, ) - ack = im.keeper.OnRecvVscMaturedPacket(ctx, packet, *data.GetVscMaturedPacketData()) + // no need to send an ack for this packet type + err = im.keeper.OnRecvVscMaturedPacket(ctx, packet, *data.GetVscMaturedPacketData()) default: - errAck := utils.NewErrorAcknowledgementWithLog(ctx, fmt.Errorf("unknown packet type: %s", data.Type)) - ack = &errAck + err = sdkerrors.ErrInvalidType.Wrapf("unknown packet type: %s", data.Type) } } + if err != nil { + ack = commontypes.NewErrorAcknowledgementWithLog(ctx, err) + } else if res != nil { + ack = commontypes.NewResultAcknowledgementWithLog(ctx, res) + } ctx.EventManager().EmitEvent( sdk.NewEvent( @@ -239,15 +245,15 @@ func (im IBCModule) OnAcknowledgementPacket( acknowledgement []byte, _ sdk.AccAddress, ) error { - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnAcknowledgementPacket", ) + // same as before, this packet is sent by the subscriber, so we cannot use MustUnmarshal var ack channeltypes.Acknowledgement if err := commontypes.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { return errorsmod.Wrapf( sdkerrors.ErrUnknownRequest, - "cannot unmarshal coordinator packet acknowledgement: %v", - err, + "cannot unmarshal packet acknowledgement: %s", err, ) } @@ -289,7 +295,7 @@ func (im IBCModule) OnTimeoutPacket( packet channeltypes.Packet, _ sdk.AccAddress, ) error { - im.keeper.Logger(ctx).Error( + im.keeper.Logger(ctx).Debug( "OnTimeoutPacket", ) if err := im.keeper.OnTimeoutPacket(ctx, packet); err != nil { diff --git a/x/appchain/coordinator/types/coordinator.pb.go b/x/appchain/coordinator/types/coordinator.pb.go index ba10cad72..433406ead 100644 --- a/x/appchain/coordinator/types/coordinator.pb.go +++ b/x/appchain/coordinator/types/coordinator.pb.go @@ -116,9 +116,56 @@ func (m *ChainIDs) GetList() []string { return nil } +// ConsensusAddresses is a list of consensus addresses. +type ConsensusAddresses struct { + // list is the list of consensus addresses. + List [][]byte `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` +} + +func (m *ConsensusAddresses) Reset() { *m = ConsensusAddresses{} } +func (m *ConsensusAddresses) String() string { return proto.CompactTextString(m) } +func (*ConsensusAddresses) ProtoMessage() {} +func (*ConsensusAddresses) Descriptor() ([]byte, []int) { + return fileDescriptor_fb7bb04617dc0e61, []int{2} +} +func (m *ConsensusAddresses) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConsensusAddresses) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConsensusAddresses.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ConsensusAddresses) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConsensusAddresses.Merge(m, src) +} +func (m *ConsensusAddresses) XXX_Size() int { + return m.Size() +} +func (m *ConsensusAddresses) XXX_DiscardUnknown() { + xxx_messageInfo_ConsensusAddresses.DiscardUnknown(m) +} + +var xxx_messageInfo_ConsensusAddresses proto.InternalMessageInfo + +func (m *ConsensusAddresses) GetList() [][]byte { + if m != nil { + return m.List + } + return nil +} + func init() { proto.RegisterType((*PendingSubscriberChainRequests)(nil), "exocore.appchain.coordinator.v1.PendingSubscriberChainRequests") proto.RegisterType((*ChainIDs)(nil), "exocore.appchain.coordinator.v1.ChainIDs") + proto.RegisterType((*ConsensusAddresses)(nil), "exocore.appchain.coordinator.v1.ConsensusAddresses") } func init() { @@ -126,23 +173,25 @@ func init() { } var fileDescriptor_fb7bb04617dc0e61 = []byte{ - // 254 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0x4c, 0xad, 0xc8, 0x4f, - 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0x48, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x4f, 0xce, 0xcf, - 0x2f, 0x4a, 0xc9, 0xcc, 0x4b, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0x44, 0xe6, 0xea, 0x15, 0x14, - 0xe5, 0x97, 0xe4, 0x0b, 0xc9, 0x43, 0xb5, 0xe8, 0xc1, 0xb4, 0xe8, 0x21, 0xab, 0x29, 0x33, 0x94, - 0xd2, 0x20, 0x64, 0x66, 0x49, 0x05, 0xc4, 0x28, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0x30, 0x53, - 0x1f, 0xc4, 0x82, 0x88, 0x2a, 0x55, 0x73, 0xc9, 0x05, 0xa4, 0xe6, 0xa5, 0x64, 0xe6, 0xa5, 0x07, - 0x97, 0x26, 0x15, 0x27, 0x17, 0x65, 0x26, 0xa5, 0x16, 0x39, 0x83, 0xcc, 0x09, 0x4a, 0x2d, 0x2c, - 0x4d, 0x2d, 0x2e, 0x29, 0x16, 0x8a, 0xe4, 0x62, 0xc9, 0xc9, 0x2c, 0x2e, 0x91, 0x60, 0x54, 0x60, - 0xd6, 0xe0, 0x36, 0xb2, 0xd7, 0x23, 0xe0, 0x22, 0xbd, 0xa0, 0xd4, 0xf4, 0xcc, 0xe2, 0x92, 0xd4, - 0x22, 0xec, 0xe6, 0x39, 0xb1, 0x9c, 0xb8, 0x27, 0xcf, 0x10, 0x04, 0x36, 0x52, 0x49, 0x8e, 0x8b, - 0x03, 0x2c, 0xe7, 0xe9, 0x52, 0x2c, 0x24, 0x84, 0x64, 0x0d, 0x27, 0x44, 0xde, 0x29, 0xe2, 0xc4, - 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, - 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xec, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, - 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x5d, 0x21, 0x0e, 0xf2, 0x4b, 0x2d, 0x29, 0xcf, 0x2f, 0xca, 0xd6, - 0x87, 0x05, 0x48, 0x05, 0xf6, 0x20, 0x29, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0xfb, 0xde, - 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x4d, 0xb2, 0xe2, 0x02, 0x93, 0x01, 0x00, 0x00, + // 278 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x90, 0x31, 0x4f, 0xc3, 0x30, + 0x10, 0x85, 0x13, 0x51, 0x21, 0x08, 0x4c, 0x11, 0x03, 0xea, 0xe0, 0xa2, 0x4e, 0x9d, 0x6c, 0x05, + 0x76, 0x10, 0x2d, 0x0c, 0x2c, 0x08, 0x85, 0x05, 0xd8, 0x12, 0xe7, 0xe4, 0x5a, 0x80, 0x2f, 0xf8, + 0x9c, 0x12, 0xc4, 0x9f, 0xe0, 0x67, 0x75, 0xec, 0xc8, 0x84, 0x50, 0xf2, 0x47, 0x50, 0x93, 0x56, + 0x0a, 0x52, 0xa5, 0x6e, 0x67, 0xdf, 0x7b, 0xdf, 0x3d, 0xbd, 0x20, 0x82, 0x12, 0x25, 0x5a, 0x10, + 0x49, 0x9e, 0xcb, 0x69, 0xa2, 0x8d, 0x90, 0x88, 0x36, 0xd3, 0x26, 0x71, 0x68, 0xc5, 0x2c, 0xea, + 0x3e, 0x79, 0x6e, 0xd1, 0x61, 0x38, 0x58, 0x59, 0xf8, 0xda, 0xc2, 0xbb, 0x9a, 0x59, 0xd4, 0x1f, + 0x6d, 0x63, 0xba, 0xb2, 0x45, 0xf5, 0x8f, 0x14, 0x2a, 0x6c, 0x46, 0xb1, 0x9c, 0xda, 0xdf, 0xe1, + 0x67, 0xc0, 0xee, 0xc0, 0x64, 0xda, 0xa8, 0xfb, 0x22, 0x25, 0x69, 0x75, 0x0a, 0x76, 0xb2, 0xe4, + 0xc4, 0xf0, 0x56, 0x00, 0x39, 0x0a, 0x1f, 0x83, 0xde, 0x8b, 0x26, 0x77, 0xec, 0x9f, 0xec, 0x8c, + 0x0e, 0x4e, 0x2f, 0xf8, 0x96, 0x44, 0x3c, 0x06, 0xa5, 0xc9, 0x81, 0xdd, 0xcc, 0x1b, 0xf7, 0xe6, + 0x3f, 0x03, 0x2f, 0x6e, 0x90, 0x43, 0x16, 0xec, 0x35, 0xbb, 0x9b, 0x2b, 0x0a, 0xc3, 0xce, 0x99, + 0xfd, 0xd5, 0x7e, 0x14, 0x84, 0x13, 0x34, 0x04, 0x86, 0x0a, 0xba, 0xcc, 0x32, 0x0b, 0x44, 0xf0, + 0x5f, 0x79, 0xd8, 0x2a, 0xc7, 0x0f, 0xf3, 0x8a, 0xf9, 0x8b, 0x8a, 0xf9, 0xbf, 0x15, 0xf3, 0xbf, + 0x6a, 0xe6, 0x2d, 0x6a, 0xe6, 0x7d, 0xd7, 0xcc, 0x7b, 0x3a, 0x57, 0xda, 0x4d, 0x8b, 0x94, 0x4b, + 0x7c, 0x15, 0xd7, 0x6d, 0xf4, 0x5b, 0x70, 0xef, 0x68, 0x9f, 0xc5, 0xba, 0xba, 0x72, 0x73, 0x79, + 0xee, 0x23, 0x07, 0x4a, 0x77, 0x9b, 0x9e, 0xce, 0xfe, 0x02, 0x00, 0x00, 0xff, 0xff, 0x12, 0xc7, + 0x0f, 0x6b, 0xbd, 0x01, 0x00, 0x00, } func (m *PendingSubscriberChainRequests) Marshal() (dAtA []byte, err error) { @@ -214,6 +263,38 @@ func (m *ChainIDs) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ConsensusAddresses) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConsensusAddresses) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConsensusAddresses) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.List) > 0 { + for iNdEx := len(m.List) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.List[iNdEx]) + copy(dAtA[i:], m.List[iNdEx]) + i = encodeVarintCoordinator(dAtA, i, uint64(len(m.List[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintCoordinator(dAtA []byte, offset int, v uint64) int { offset -= sovCoordinator(v) base := offset @@ -255,6 +336,21 @@ func (m *ChainIDs) Size() (n int) { return n } +func (m *ConsensusAddresses) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.List) > 0 { + for _, b := range m.List { + l = len(b) + n += 1 + l + sovCoordinator(uint64(l)) + } + } + return n +} + func sovCoordinator(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -427,6 +523,88 @@ func (m *ChainIDs) Unmarshal(dAtA []byte) error { } return nil } +func (m *ConsensusAddresses) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConsensusAddresses: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConsensusAddresses: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field List", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCoordinator + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCoordinator + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.List = append(m.List, make([]byte, postIndex-iNdEx)) + copy(m.List[len(m.List)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCoordinator(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCoordinator + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipCoordinator(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/appchain/coordinator/types/errors.go b/x/appchain/coordinator/types/errors.go index bef248121..40b8b7a44 100644 --- a/x/appchain/coordinator/types/errors.go +++ b/x/appchain/coordinator/types/errors.go @@ -10,6 +10,7 @@ const ( errCodeDuplicateSubChain errCodeNoOperators errCodeInvalidSubscriberClient + errCodeUnknownSubscriberChannelID ) var ( @@ -36,4 +37,9 @@ var ( ErrInvalidSubscriberClient = errorsmod.Register( ModuleName, errCodeInvalidSubscriberClient, "invalid subscriber client", ) + // ErrUnknownSubscriberChannelID is the error returned when the channel ID + // corresponding to a message from the subscriber chain is unknown + ErrUnknownSubscriberChannelID = errorsmod.Register( + ModuleName, errCodeUnknownSubscriberChannelID, "unknown subscriber channel ID", + ) ) diff --git a/x/appchain/coordinator/types/expected_keepers.go b/x/appchain/coordinator/types/expected_keepers.go index 4f2ae94be..9316adb6b 100644 --- a/x/appchain/coordinator/types/expected_keepers.go +++ b/x/appchain/coordinator/types/expected_keepers.go @@ -7,6 +7,7 @@ import ( avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/ethereum/go-ethereum/common" ) @@ -31,4 +32,19 @@ type StakingKeeper interface { type OperatorKeeper interface { GetActiveOperatorsForChainID(sdk.Context, string) ([]sdk.AccAddress, []types.WrappedConsKey) GetVotePowerForChainID(sdk.Context, []sdk.AccAddress, string) ([]int64, error) + GetOperatorAddressForChainIDAndConsAddr( + sdk.Context, string, sdk.ConsAddress, + ) (bool, sdk.AccAddress) + DeleteOperatorAddressForChainIDAndConsAddr( + ctx sdk.Context, chainID string, consAddr sdk.ConsAddress, + ) + // compared to slashing forwarded by Tendermint, this function doesn't have the vote power parameter. + // instead it contains the avs address for which the slashing is being executed. the interface is + // subject to change during implementation. It should check that the validator isn't permanently + // kicked, and it should jail the validator for the provided duration. + ApplySlashForHeight( + ctx sdk.Context, operatorAccAddress sdk.AccAddress, avsAddress string, + height uint64, fraction sdk.Dec, infraction stakingtypes.Infraction, + jailDuration time.Duration, + ) } diff --git a/x/appchain/coordinator/types/keys.go b/x/appchain/coordinator/types/keys.go index 12165f426..925271c11 100644 --- a/x/appchain/coordinator/types/keys.go +++ b/x/appchain/coordinator/types/keys.go @@ -54,6 +54,14 @@ const ( ChannelForChainBytePrefix // ChainForChannelBytePrefix is the prefix for the chain for channel key ChainForChannelBytePrefix + // ChainInitTimeoutBytePrefix is the prefix for the chain init timeout key + ChainInitTimeoutBytePrefix + // InitChainHeightBytePrefix is the prefix for the init chain height key + InitChainHeightBytePrefix + // HeightToChainVscIDBytePrefix is the prefix for the height to chain id + vsc id key + HeightToChainVscIDBytePrefix + // SlashAcksBytePrefix is the prefix for the slashing acks key + SlashAcksBytePrefix ) // ParamsKey returns the key under which the coordinator module's parameters are stored. @@ -126,3 +134,30 @@ func ChannelForChainKey(chainID string) []byte { func ChainForChannelKey(channelID string) []byte { return append([]byte{ChainForChannelBytePrefix}, []byte(channelID)...) } + +// ChainInitTimeoutKey returns the key for the chain init timeout +func ChainInitTimeoutKey(chainID string) []byte { + return append([]byte{ChainInitTimeoutBytePrefix}, []byte(chainID)...) +} + +// InitChainHeightKey returns the key for the init chain height +func InitChainHeightKey(chainID string) []byte { + return append([]byte{InitChainHeightBytePrefix}, []byte(chainID)...) +} + +// HeightToChainVscIDKey returns the key for the height to chain id + vsc id +func HeightToChainVscIDKey(chainID string, vscID uint64) []byte { + return utils.AppendMany( + []byte{HeightToChainVscIDBytePrefix}, + []byte(chainID), + sdk.Uint64ToBigEndian(vscID), + ) +} + +// SlashAcksKey returns the key for the slashing acks +func SlashAcksKey(chainID string) []byte { + return append( + []byte{SlashAcksBytePrefix}, + []byte(chainID)..., + ) +} diff --git a/x/appchain/subscriber/keeper/connection.go b/x/appchain/subscriber/keeper/connection.go index 29d2237a1..5a3021719 100644 --- a/x/appchain/subscriber/keeper/connection.go +++ b/x/appchain/subscriber/keeper/connection.go @@ -27,19 +27,19 @@ func (k Keeper) GetCoordinatorClientID(ctx sdk.Context) (string, bool) { } // SetCoordinatorChannel sets the channelId for the channel to the coordinator. -func (k Keeper) SetCoordinatorChannel(ctx sdk.Context, channelId string) { +func (k Keeper) SetCoordinatorChannel(ctx sdk.Context, channelID string) { store := ctx.KVStore(k.storeKey) - store.Set(types.CoordinatorChannelKey(), []byte(channelId)) + store.Set(types.CoordinatorChannelKey(), []byte(channelID)) } // GetCoordinatorChannel gets the channelId for the channel to the coordinator. func (k Keeper) GetCoordinatorChannel(ctx sdk.Context) (string, bool) { store := ctx.KVStore(k.storeKey) - channelIdBytes := store.Get(types.CoordinatorChannelKey()) - if len(channelIdBytes) == 0 { + bz := store.Get(types.CoordinatorChannelKey()) + if len(bz) == 0 { return "", false } - return string(channelIdBytes), true + return string(bz), true } // DeleteCoordinatorChannel deletes the channelId for the channel to the coordinator. @@ -56,29 +56,29 @@ func (k Keeper) VerifyCoordinatorChain(ctx sdk.Context, connectionHops []string) "must have direct connection to coordinator chain", ) } - connectionId := connectionHops[0] - conn, ok := k.connectionKeeper.GetConnection(ctx, connectionId) + connectionID := connectionHops[0] + conn, ok := k.connectionKeeper.GetConnection(ctx, connectionID) if !ok { return errorsmod.Wrapf( conntypes.ErrConnectionNotFound, "connection not found for connection Id: %s", - connectionId, + connectionID, ) } // Verify that client id is expected clientId - expectedClientId, ok := k.GetCoordinatorClientID(ctx) + expectedClientID, ok := k.GetCoordinatorClientID(ctx) if !ok { return errorsmod.Wrapf( clienttypes.ErrInvalidClient, "could not find coordinator client id", ) } - if expectedClientId != conn.ClientId { + if expectedClientID != conn.ClientId { return errorsmod.Wrapf( clienttypes.ErrInvalidClient, "invalid client: %s, channel must be built on top of client: %s", conn.ClientId, - expectedClientId, + expectedClientID, ) } diff --git a/x/appchain/subscriber/keeper/keeper.go b/x/appchain/subscriber/keeper/keeper.go index 6b2f6ab7d..1bb985d95 100644 --- a/x/appchain/subscriber/keeper/keeper.go +++ b/x/appchain/subscriber/keeper/keeper.go @@ -44,6 +44,7 @@ func NewKeeper( clientKeeper: clientKeeper, connectionKeeper: connectionKeeper, channelKeeper: channelKeeper, + ibcCoreKeeper: ibcCoreKeeper, } } @@ -73,8 +74,8 @@ func (k Keeper) IsBound(ctx sdk.Context, portID string) bool { // BindPort defines a wrapper function for the port Keeper's function in // order to expose it to module's InitGenesis function func (k Keeper) BindPort(ctx sdk.Context, portID string) error { - cap := k.portKeeper.BindPort(ctx, portID) - return k.ClaimCapability(ctx, cap, host.PortPath(portID)) + capability := k.portKeeper.BindPort(ctx, portID) + return k.ClaimCapability(ctx, capability, host.PortPath(portID)) } // ClaimCapability allows the IBC app module to claim a capability that core IBC @@ -115,15 +116,15 @@ func (k Keeper) SetPendingChanges( // SetPacketMaturityTime sets the maturity time for a given received VSC packet id func (k Keeper) SetPacketMaturityTime( - ctx sdk.Context, vscId uint64, maturityTime time.Time, + ctx sdk.Context, vscID uint64, maturityTime time.Time, ) { store := ctx.KVStore(k.storeKey) maturingVSCPacket := &types.MaturingVSCPacket{ - ID: vscId, + ID: vscID, MaturityTime: maturityTime, } store.Set( - types.PacketMaturityTimeKey(vscId, maturityTime), + types.PacketMaturityTimeKey(vscID, maturityTime), k.cdc.MustMarshal(maturingVSCPacket), ) } diff --git a/x/appchain/subscriber/keeper/validators.go b/x/appchain/subscriber/keeper/validators.go index d27e960b2..3c247fb35 100644 --- a/x/appchain/subscriber/keeper/validators.go +++ b/x/appchain/subscriber/keeper/validators.go @@ -43,7 +43,8 @@ func (k Keeper) ApplyValidatorChanges( ) []abci.ValidatorUpdate { ret := make([]abci.ValidatorUpdate, 0, len(changes)) logger := k.Logger(ctx) - for _, change := range changes { + for i := range changes { + change := changes[i] // avoid implicit memory aliasing wrappedKey := exocoretypes.NewWrappedConsKeyFromTmProtoKey(&change.PubKey) if wrappedKey == nil { // an error in deserializing the key would indicate that the coordinator @@ -52,20 +53,20 @@ func (k Keeper) ApplyValidatorChanges( panic(fmt.Sprintf("invalid pubkey %s", change.PubKey)) } consAddress := wrappedKey.ToConsAddr() - val, found := k.GetOmnichainValidator(ctx, consAddress) + val, found := k.GetSubscriberChainValidator(ctx, consAddress) switch found { case true: if change.Power < 1 { logger.Info("deleting validator", "consAddress", consAddress) - k.DeleteOmnichainValidator(ctx, consAddress) + k.DeleteSubscriberChainValidator(ctx, consAddress) } else { logger.Info("updating validator", "consAddress", consAddress) val.Power = change.Power - k.SetOmnichainValidator(ctx, val) + k.SetSubscriberChainValidator(ctx, val) } case false: if change.Power > 0 { - ocVal, err := types.NewOmniChainValidator( + ocVal, err := types.NewSubscriberChainValidator( consAddress, change.Power, wrappedKey.ToSdkKey(), ) if err != nil { @@ -74,7 +75,7 @@ func (k Keeper) ApplyValidatorChanges( continue } logger.Info("adding validator", "consAddress", consAddress) - k.SetOmnichainValidator(ctx, ocVal) + k.SetSubscriberChainValidator(ctx, ocVal) ret = append(ret, change) } else { // edge case: we received an update for 0 power @@ -92,22 +93,22 @@ func (k Keeper) ApplyValidatorChanges( return ret } -// SetOmnichainValidator stores a validator based on the pub key derived address. -func (k Keeper) SetOmnichainValidator( - ctx sdk.Context, validator types.OmniChainValidator, +// SetSubscriberChainValidator stores a validator based on the pub key derived address. +func (k Keeper) SetSubscriberChainValidator( + ctx sdk.Context, validator types.SubscriberChainValidator, ) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&validator) - store.Set(types.OmniChainValidatorKey(validator.Address), bz) + store.Set(types.SubscriberChainValidatorKey(validator.ConsAddress), bz) } -// GetOmnichainValidator gets a validator based on the pub key derived (consensus) address. -func (k Keeper) GetOmnichainValidator( +// GetSubscriberChainValidator gets a validator based on the pub key derived (consensus) address. +func (k Keeper) GetSubscriberChainValidator( ctx sdk.Context, addr sdk.ConsAddress, -) (validator types.OmniChainValidator, found bool) { +) (validator types.SubscriberChainValidator, found bool) { store := ctx.KVStore(k.storeKey) - v := store.Get(types.OmniChainValidatorKey(addr.Bytes())) + v := store.Get(types.SubscriberChainValidatorKey(addr)) if v == nil { return } @@ -117,22 +118,22 @@ func (k Keeper) GetOmnichainValidator( return } -// DeleteOmnichainValidator deletes a validator based on the pub key derived address. -func (k Keeper) DeleteOmnichainValidator(ctx sdk.Context, addr sdk.ConsAddress) { +// DeleteSubscriberChainValidator deletes a validator based on the pub key derived address. +func (k Keeper) DeleteSubscriberChainValidator(ctx sdk.Context, addr sdk.ConsAddress) { store := ctx.KVStore(k.storeKey) - store.Delete(types.OmniChainValidatorKey(addr.Bytes())) + store.Delete(types.SubscriberChainValidatorKey(addr)) } -// GetAllOmnichainValidators returns all validators in the store. -func (k Keeper) GetAllOmnichainValidators( +// GetAllSubscriberChainValidators returns all validators in the store. +func (k Keeper) GetAllSubscriberChainValidators( ctx sdk.Context, -) (validators []types.OmniChainValidator) { +) (validators []types.SubscriberChainValidator) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.OmniChainValidatorBytePrefix}) + iterator := sdk.KVStorePrefixIterator(store, []byte{types.SubscriberChainValidatorBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { - val := types.OmniChainValidator{} + val := types.SubscriberChainValidator{} k.cdc.MustUnmarshal(iterator.Value(), &val) validators = append(validators, val) } diff --git a/x/appchain/subscriber/module_ibc.go b/x/appchain/subscriber/module_ibc.go index 22cb5d012..eac59d418 100644 --- a/x/appchain/subscriber/module_ibc.go +++ b/x/appchain/subscriber/module_ibc.go @@ -116,13 +116,13 @@ func (im IBCModule) OnChanOpenInit( // that the channel is opened by this chain. func (im IBCModule) OnChanOpenTry( ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, + _ channeltypes.Order, + _ []string, + _ string, + _ string, + _ *capabilitytypes.Capability, + _ channeltypes.Counterparty, + _ string, ) (string, error) { im.keeper.Logger(ctx).Debug( "OnChanOpenTry", @@ -225,8 +225,8 @@ func (im IBCModule) OnChanOpenAck( // OnChanOpenConfirm implements the IBCModule interface func (im IBCModule) OnChanOpenConfirm( ctx sdk.Context, - portID, - channelID string, + _ string, + _ string, ) error { im.keeper.Logger(ctx).Debug( "OnChanOpenConfirm", @@ -241,7 +241,7 @@ func (im IBCModule) OnChanOpenConfirm( // OnChanCloseInit implements the IBCModule interface func (im IBCModule) OnChanCloseInit( ctx sdk.Context, - portID, + _ string, channelID string, ) error { im.keeper.Logger(ctx).Debug( @@ -260,8 +260,8 @@ func (im IBCModule) OnChanCloseInit( // OnChanCloseConfirm implements the IBCModule interface func (im IBCModule) OnChanCloseConfirm( ctx sdk.Context, - portID, - channelID string, + _ string, + _ string, ) error { im.keeper.Logger(ctx).Debug( "OnChanCloseConfirm", @@ -311,7 +311,7 @@ func (im IBCModule) OnAcknowledgementPacket( ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, - relayer sdk.AccAddress, + _ sdk.AccAddress, ) error { im.keeper.Logger(ctx).Debug( "OnAcknowledgementPacket", @@ -358,8 +358,8 @@ func (im IBCModule) OnAcknowledgementPacket( // OnTimeoutPacket implements the IBCModule interface func (im IBCModule) OnTimeoutPacket( ctx sdk.Context, - modulePacket channeltypes.Packet, - relayer sdk.AccAddress, + _ channeltypes.Packet, + _ sdk.AccAddress, ) error { im.keeper.Logger(ctx).Debug( "OnTimeoutPacket", diff --git a/x/appchain/subscriber/types/keys.go b/x/appchain/subscriber/types/keys.go index 68c7742fd..8c4c4c0a9 100644 --- a/x/appchain/subscriber/types/keys.go +++ b/x/appchain/subscriber/types/keys.go @@ -46,8 +46,8 @@ const ( CoordinatorClientIDBytePrefix // ValsetUpdateIDBytePrefix is the prefix for the valset update ID key ValsetUpdateIDBytePrefix - // OmniChainValidatorBytePrefix is the prefix for the omni chain validator key - OmniChainValidatorBytePrefix + // SubscriberChainValidatorBytePrefix is the prefix for the subscriber chain validator key + SubscriberChainValidatorBytePrefix // CoordinatorChannelBytePrefix is the prefix for the coordinator channel key CoordinatorChannelBytePrefix // PendingChangesBytePrefix is the prefix for the pending changes key @@ -81,9 +81,10 @@ func ValsetUpdateIDKey(height int64) []byte { ) } -// OmniChainValidatorKey returns the key for the omni chain validator against the provided address. -func OmniChainValidatorKey(address sdk.ConsAddress) []byte { - return append([]byte{OmniChainValidatorBytePrefix}, address...) +// SubscriberChainValidatorKey returns the key for the subscriber chain validator +// against the provided address. +func SubscriberChainValidatorKey(address sdk.ConsAddress) []byte { + return append([]byte{SubscriberChainValidatorBytePrefix}, address...) } // CoordinatorChannelKey returns the key for which the ibc channel id to the coordinator chain diff --git a/x/appchain/subscriber/types/subscriber.pb.go b/x/appchain/subscriber/types/subscriber.pb.go index 445a4076e..ad56c953d 100644 --- a/x/appchain/subscriber/types/subscriber.pb.go +++ b/x/appchain/subscriber/types/subscriber.pb.go @@ -25,28 +25,30 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -type OmniChainValidator struct { - // The address is derived from the consenus key. It has no relation with the operator +// SubscriberChainValidator is a validator structure on the subscriber chain. +type SubscriberChainValidator struct { + // address, as derived from the consensus key. No correlation with the operator // address on Exocore. - Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - // Last known + ConsAddress []byte `protobuf:"bytes,1,opt,name=cons_address,json=consAddress,proto3" json:"cons_address,omitempty"` + // power is the vote power of the validator Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` // pubkey is the consensus public key of the validator, as a Protobuf Any. + // this type is chosen to match the x/staking/validator type. Pubkey *types.Any `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" yaml:"consensus_pubkey"` } -func (m *OmniChainValidator) Reset() { *m = OmniChainValidator{} } -func (m *OmniChainValidator) String() string { return proto.CompactTextString(m) } -func (*OmniChainValidator) ProtoMessage() {} -func (*OmniChainValidator) Descriptor() ([]byte, []int) { +func (m *SubscriberChainValidator) Reset() { *m = SubscriberChainValidator{} } +func (m *SubscriberChainValidator) String() string { return proto.CompactTextString(m) } +func (*SubscriberChainValidator) ProtoMessage() {} +func (*SubscriberChainValidator) Descriptor() ([]byte, []int) { return fileDescriptor_1c15efc73dd829e9, []int{0} } -func (m *OmniChainValidator) XXX_Unmarshal(b []byte) error { +func (m *SubscriberChainValidator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *OmniChainValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *SubscriberChainValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_OmniChainValidator.Marshal(b, m, deterministic) + return xxx_messageInfo_SubscriberChainValidator.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -56,33 +58,33 @@ func (m *OmniChainValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *OmniChainValidator) XXX_Merge(src proto.Message) { - xxx_messageInfo_OmniChainValidator.Merge(m, src) +func (m *SubscriberChainValidator) XXX_Merge(src proto.Message) { + xxx_messageInfo_SubscriberChainValidator.Merge(m, src) } -func (m *OmniChainValidator) XXX_Size() int { +func (m *SubscriberChainValidator) XXX_Size() int { return m.Size() } -func (m *OmniChainValidator) XXX_DiscardUnknown() { - xxx_messageInfo_OmniChainValidator.DiscardUnknown(m) +func (m *SubscriberChainValidator) XXX_DiscardUnknown() { + xxx_messageInfo_SubscriberChainValidator.DiscardUnknown(m) } -var xxx_messageInfo_OmniChainValidator proto.InternalMessageInfo +var xxx_messageInfo_SubscriberChainValidator proto.InternalMessageInfo -func (m *OmniChainValidator) GetAddress() []byte { +func (m *SubscriberChainValidator) GetConsAddress() []byte { if m != nil { - return m.Address + return m.ConsAddress } return nil } -func (m *OmniChainValidator) GetPower() int64 { +func (m *SubscriberChainValidator) GetPower() int64 { if m != nil { return m.Power } return 0 } -func (m *OmniChainValidator) GetPubkey() *types.Any { +func (m *SubscriberChainValidator) GetPubkey() *types.Any { if m != nil { return m.Pubkey } @@ -90,7 +92,7 @@ func (m *OmniChainValidator) GetPubkey() *types.Any { } func init() { - proto.RegisterType((*OmniChainValidator)(nil), "exocore.appchain.subscriber.v1.OmniChainValidator") + proto.RegisterType((*SubscriberChainValidator)(nil), "exocore.appchain.subscriber.v1.SubscriberChainValidator") } func init() { @@ -98,30 +100,31 @@ func init() { } var fileDescriptor_1c15efc73dd829e9 = []byte{ - // 320 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4e, 0x02, 0x31, - 0x14, 0x86, 0xa9, 0x44, 0x4c, 0x46, 0x57, 0x93, 0x49, 0x1c, 0x58, 0x54, 0xc2, 0x8a, 0x8d, 0x6d, - 0x90, 0x9d, 0x89, 0x0b, 0x31, 0xae, 0x4c, 0xd4, 0xb0, 0xd0, 0xc4, 0x0d, 0x69, 0x4b, 0x1d, 0x26, - 0x30, 0xf3, 0x9a, 0x76, 0x0a, 0xf4, 0x16, 0xde, 0xc2, 0x0b, 0x78, 0x08, 0xe3, 0x8a, 0xa5, 0x2b, - 0x63, 0xe0, 0x06, 0x9e, 0xc0, 0x40, 0x07, 0xc3, 0xc2, 0xdd, 0xfb, 0xfb, 0xfe, 0xbf, 0xef, 0xcb, - 0x1f, 0x50, 0x39, 0x07, 0x01, 0x5a, 0x52, 0xa6, 0x94, 0x18, 0xb1, 0x34, 0xa7, 0xc6, 0x72, 0x23, - 0x74, 0xca, 0xa5, 0xa6, 0xd3, 0xce, 0x8e, 0x22, 0x4a, 0x43, 0x01, 0x21, 0x2e, 0x03, 0x64, 0x1b, - 0x20, 0x3b, 0x96, 0x69, 0xa7, 0x51, 0x4f, 0x00, 0x92, 0x89, 0xa4, 0x1b, 0x37, 0xb7, 0xcf, 0x94, - 0xe5, 0xce, 0x47, 0x1b, 0x51, 0x02, 0x09, 0x6c, 0x46, 0xba, 0x9e, 0xca, 0xd7, 0xba, 0x00, 0x93, - 0x81, 0x19, 0xf8, 0x85, 0x17, 0x7e, 0xd5, 0x7a, 0x45, 0x41, 0x78, 0x97, 0xe5, 0xe9, 0xd5, 0xfa, - 0xce, 0x03, 0x9b, 0xa4, 0x43, 0x56, 0x80, 0x0e, 0xe3, 0xe0, 0x80, 0x0d, 0x87, 0x5a, 0x1a, 0x13, - 0xa3, 0x26, 0x6a, 0x1f, 0xf5, 0xb7, 0x32, 0x8c, 0x82, 0x7d, 0x05, 0x33, 0xa9, 0xe3, 0xbd, 0x26, - 0x6a, 0x57, 0xfb, 0x5e, 0x84, 0x2c, 0xa8, 0x29, 0xcb, 0xc7, 0xd2, 0xc5, 0xd5, 0x26, 0x6a, 0x1f, - 0x9e, 0x45, 0xc4, 0x33, 0x92, 0x2d, 0x23, 0xb9, 0xcc, 0x5d, 0xaf, 0xfb, 0xf3, 0x75, 0x72, 0xec, - 0x58, 0x36, 0x39, 0x6f, 0x09, 0xc8, 0x8d, 0xcc, 0x8d, 0x35, 0x03, 0x9f, 0x6b, 0x7d, 0xbc, 0x9d, - 0x46, 0x25, 0x99, 0xd0, 0x4e, 0x15, 0x40, 0xee, 0x2d, 0xbf, 0x91, 0xae, 0x5f, 0x7e, 0xdc, 0x7b, - 0x7c, 0x5f, 0x62, 0xb4, 0x58, 0x62, 0xf4, 0xbd, 0xc4, 0xe8, 0x65, 0x85, 0x2b, 0x8b, 0x15, 0xae, - 0x7c, 0xae, 0x70, 0xe5, 0xe9, 0x22, 0x49, 0x8b, 0x91, 0xe5, 0x44, 0x40, 0x46, 0xaf, 0x7d, 0x75, - 0xb7, 0xb2, 0x98, 0x81, 0x1e, 0xff, 0x55, 0x3f, 0xff, 0xb7, 0xfc, 0xc2, 0x29, 0x69, 0x78, 0x6d, - 0xc3, 0xd8, 0xfd, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xee, 0x66, 0xe1, 0x6d, 0xa8, 0x01, 0x00, 0x00, + // 325 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x51, 0x31, 0x4f, 0x02, 0x31, + 0x18, 0xa5, 0x12, 0x19, 0x0e, 0xa6, 0xcb, 0x25, 0x1e, 0x0c, 0x15, 0x99, 0x58, 0x6c, 0x83, 0x6c, + 0x26, 0x0e, 0x60, 0x9c, 0x4c, 0x8c, 0xc1, 0x44, 0x13, 0x17, 0xd2, 0x96, 0x7a, 0x5c, 0x80, 0xfb, + 0x9a, 0xf6, 0x0e, 0xe8, 0xbf, 0xf0, 0xc7, 0x18, 0x7f, 0x83, 0x71, 0x62, 0x74, 0x32, 0x06, 0xfe, + 0x81, 0xbf, 0xc0, 0x1c, 0x3d, 0x08, 0x83, 0x5b, 0xdf, 0xeb, 0xf7, 0x5e, 0x5f, 0xbf, 0xe7, 0x51, + 0xb9, 0x04, 0x01, 0x5a, 0x52, 0xa6, 0x94, 0x18, 0xb3, 0x38, 0xa1, 0x26, 0xe3, 0x46, 0xe8, 0x98, + 0x4b, 0x4d, 0xe7, 0x9d, 0x03, 0x44, 0x94, 0x86, 0x14, 0x7c, 0x5c, 0x08, 0xc8, 0x4e, 0x40, 0x0e, + 0x46, 0xe6, 0x9d, 0x46, 0x5d, 0x80, 0x99, 0x81, 0x19, 0x6e, 0xa7, 0xa9, 0x03, 0x4e, 0xda, 0x08, + 0x22, 0x88, 0xc0, 0xf1, 0xf9, 0xa9, 0x60, 0xeb, 0x11, 0x40, 0x34, 0x95, 0x74, 0x8b, 0x78, 0xf6, + 0x42, 0x59, 0x62, 0xdd, 0x55, 0xeb, 0x1d, 0x79, 0xe1, 0xc3, 0xde, 0xfd, 0x3a, 0x7f, 0xed, 0x91, + 0x4d, 0xe3, 0x11, 0x4b, 0x41, 0xfb, 0x67, 0x5e, 0x4d, 0x40, 0x62, 0x86, 0x6c, 0x34, 0xd2, 0xd2, + 0x98, 0x10, 0x35, 0x51, 0xbb, 0x36, 0xa8, 0xe6, 0x5c, 0xcf, 0x51, 0x7e, 0xe0, 0x1d, 0x2b, 0x58, + 0x48, 0x1d, 0x1e, 0x35, 0x51, 0xbb, 0x3c, 0x70, 0xc0, 0x67, 0x5e, 0x45, 0x65, 0x7c, 0x22, 0x6d, + 0x58, 0x6e, 0xa2, 0x76, 0xf5, 0x22, 0x20, 0x2e, 0x01, 0xd9, 0x25, 0x20, 0xbd, 0xc4, 0xf6, 0xbb, + 0xbf, 0xdf, 0xa7, 0x27, 0x96, 0xcd, 0xa6, 0x97, 0xad, 0xdc, 0x52, 0x26, 0x26, 0x33, 0x43, 0xa7, + 0x6b, 0x7d, 0xbe, 0x9d, 0x07, 0xc5, 0xcf, 0x84, 0xb6, 0x2a, 0x05, 0x72, 0x9f, 0xf1, 0x5b, 0x69, + 0x07, 0x85, 0x71, 0xff, 0xe9, 0x63, 0x8d, 0xd1, 0x6a, 0x8d, 0xd1, 0xcf, 0x1a, 0xa3, 0xd7, 0x0d, + 0x2e, 0xad, 0x36, 0xb8, 0xf4, 0xb5, 0xc1, 0xa5, 0xe7, 0xab, 0x28, 0x4e, 0xc7, 0x19, 0x27, 0x02, + 0x66, 0xf4, 0xc6, 0x6d, 0xf2, 0x4e, 0xa6, 0x0b, 0xd0, 0x93, 0x7d, 0x13, 0xcb, 0x7f, 0xbb, 0x48, + 0xad, 0x92, 0x86, 0x57, 0xb6, 0x19, 0xbb, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x38, 0x5d, + 0x69, 0xb7, 0x01, 0x00, 0x00, } -func (m *OmniChainValidator) Marshal() (dAtA []byte, err error) { +func (m *SubscriberChainValidator) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -131,12 +134,12 @@ func (m *OmniChainValidator) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *OmniChainValidator) MarshalTo(dAtA []byte) (int, error) { +func (m *SubscriberChainValidator) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *OmniChainValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *SubscriberChainValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -158,10 +161,10 @@ func (m *OmniChainValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - if len(m.Address) > 0 { - i -= len(m.Address) - copy(dAtA[i:], m.Address) - i = encodeVarintSubscriber(dAtA, i, uint64(len(m.Address))) + if len(m.ConsAddress) > 0 { + i -= len(m.ConsAddress) + copy(dAtA[i:], m.ConsAddress) + i = encodeVarintSubscriber(dAtA, i, uint64(len(m.ConsAddress))) i-- dAtA[i] = 0xa } @@ -179,13 +182,13 @@ func encodeVarintSubscriber(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *OmniChainValidator) Size() (n int) { +func (m *SubscriberChainValidator) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Address) + l = len(m.ConsAddress) if l > 0 { n += 1 + l + sovSubscriber(uint64(l)) } @@ -205,7 +208,7 @@ func sovSubscriber(x uint64) (n int) { func sozSubscriber(x uint64) (n int) { return sovSubscriber(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *OmniChainValidator) Unmarshal(dAtA []byte) error { +func (m *SubscriberChainValidator) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228,15 +231,15 @@ func (m *OmniChainValidator) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OmniChainValidator: wiretype end group for non-group") + return fmt.Errorf("proto: SubscriberChainValidator: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OmniChainValidator: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SubscriberChainValidator: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsAddress", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -263,9 +266,9 @@ func (m *OmniChainValidator) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...) - if m.Address == nil { - m.Address = []byte{} + m.ConsAddress = append(m.ConsAddress[:0], dAtA[iNdEx:postIndex]...) + if m.ConsAddress == nil { + m.ConsAddress = []byte{} } iNdEx = postIndex case 2: diff --git a/x/appchain/subscriber/types/validator.go b/x/appchain/subscriber/types/validator.go index 3bc44fa41..7ab49887b 100644 --- a/x/appchain/subscriber/types/validator.go +++ b/x/appchain/subscriber/types/validator.go @@ -8,31 +8,31 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// NewOmniChainValidator creates a new OmniChainValidator instance. -func NewOmniChainValidator( +// NewSubscriberChainValidator creates a new SubscriberChainValidator instance. +func NewSubscriberChainValidator( address []byte, power int64, pubKey cryptotypes.PubKey, -) (OmniChainValidator, error) { +) (SubscriberChainValidator, error) { pkAny, err := codectypes.NewAnyWithValue(pubKey) if err != nil { - return OmniChainValidator{}, err + return SubscriberChainValidator{}, err } - return OmniChainValidator{ - Address: address, - Power: power, - Pubkey: pkAny, + return SubscriberChainValidator{ + ConsAddress: address, + Power: power, + Pubkey: pkAny, }, nil } // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces. // It is required to ensure that ConsPubKey below works. -func (ocv OmniChainValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { +func (ocv SubscriberChainValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { var pk cryptotypes.PubKey return unpacker.UnpackAny(ocv.Pubkey, &pk) } // ConsPubKey returns the validator PubKey as a cryptotypes.PubKey. -func (ocv OmniChainValidator) ConsPubKey() (cryptotypes.PubKey, error) { +func (ocv SubscriberChainValidator) ConsPubKey() (cryptotypes.PubKey, error) { pk, ok := ocv.Pubkey.GetCachedValue().(cryptotypes.PubKey) if !ok { return nil, errorsmod.Wrapf( diff --git a/x/avs/keeper/avs.go b/x/avs/keeper/avs.go index d09895e52..e78076dc2 100644 --- a/x/avs/keeper/avs.go +++ b/x/avs/keeper/avs.go @@ -7,6 +7,7 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ethereum/go-ethereum/common" "github.com/evmos/evmos/v14/x/evm/statedb" @@ -118,7 +119,7 @@ func (k Keeper) RegisterAVSWithChainID( // guard against errors ctx, writeFunc := oCtx.CacheContext() // remove the version number and validate - params.ChainID = types.ChainIDWithoutRevision(params.ChainID) + params.ChainID = exocoretypes.ChainIDWithoutRevision(params.ChainID) if len(params.ChainID) == 0 { return common.Address{}, errorsmod.Wrap(types.ErrNotNull, "RegisterAVSWithChainID: chainID is null") } diff --git a/x/avs/keeper/keeper.go b/x/avs/keeper/keeper.go index 2556605c8..decfcb77f 100644 --- a/x/avs/keeper/keeper.go +++ b/x/avs/keeper/keeper.go @@ -8,6 +8,7 @@ import ( errorsmod "cosmossdk.io/errors" + exocoretypes "github.com/ExocoreNetwork/exocore/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" @@ -83,7 +84,7 @@ func (k Keeper) AVSInfoUpdate(ctx sdk.Context, params *types.AVSRegisterOrDeregi return errorsmod.Wrap(types.ErrAlreadyRegistered, fmt.Sprintf("the avsaddress is :%s", params.AvsAddress)) } startingEpoch := uint64(epoch.CurrentEpoch + 1) - if params.ChainID == types.ChainIDWithoutRevision(ctx.ChainID()) { + if params.ChainID == exocoretypes.ChainIDWithoutRevision(ctx.ChainID()) { // TODO: handle this better startingEpoch = uint64(epoch.CurrentEpoch) } diff --git a/x/avs/keeper/query.go b/x/avs/keeper/query.go index ff1a7c7be..b6e7dfcf9 100644 --- a/x/avs/keeper/query.go +++ b/x/avs/keeper/query.go @@ -3,6 +3,7 @@ package keeper import ( "context" + exocoretypes "github.com/ExocoreNetwork/exocore/types" "github.com/ExocoreNetwork/exocore/x/avs/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -22,7 +23,7 @@ func (k Keeper) QueryAVSTaskInfo(ctx context.Context, req *types.QueryAVSTaskInf // QueryAVSAddrByChainID is an implementation of the QueryAVSAddrByChainID gRPC method func (k Keeper) QueryAVSAddrByChainID(ctx context.Context, req *types.QueryAVSAddrByChainIDReq) (*types.QueryAVSAddrByChainIDResponse, error) { c := sdk.UnwrapSDKContext(ctx) - isChainAvs, avsAddr := k.IsAVSByChainID(c, types.ChainIDWithoutRevision(req.ChainID)) + isChainAvs, avsAddr := k.IsAVSByChainID(c, exocoretypes.ChainIDWithoutRevision(req.ChainID)) if !isChainAvs { return nil, types.ErrNotYetRegistered } diff --git a/x/avs/types/types.go b/x/avs/types/types.go index 0638ac8cf..4a4aa17a2 100644 --- a/x/avs/types/types.go +++ b/x/avs/types/types.go @@ -1,9 +1,6 @@ package types import ( - "strings" - - ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -70,16 +67,6 @@ type AVSRegisterOrDeregisterParams struct { Action uint64 } -// ChainIDWithoutRevision returns the chainID without the revision number. -// For example, "exocoretestnet_233-1" returns "exocoretestnet_233". -func ChainIDWithoutRevision(chainID string) string { - if !ibcclienttypes.IsRevisionFormat(chainID) { - return chainID - } - splitStr := strings.Split(chainID, "-") - return splitStr[0] -} - // GenerateAVSAddr generates a hex AVS address based on the chainID. // It returns a hex address as a string. func GenerateAVSAddr(chainID string) common.Address { diff --git a/x/dogfood/keeper/abci.go b/x/dogfood/keeper/abci.go index 4569e7f77..836a5ab66 100644 --- a/x/dogfood/keeper/abci.go +++ b/x/dogfood/keeper/abci.go @@ -2,9 +2,9 @@ package keeper import ( "cosmossdk.io/math" + exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ExocoreNetwork/exocore/utils" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -20,7 +20,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } defer k.ClearEpochEnd(ctx) - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(ctx.ChainID()) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()) // start by clearing the previous consensus keys for the chain. // each AVS can have a separate epoch and hence this function is a part of this module // and not the operator module. diff --git a/x/dogfood/keeper/genesis.go b/x/dogfood/keeper/genesis.go index a8bcdf9b2..f943cc6ba 100644 --- a/x/dogfood/keeper/genesis.go +++ b/x/dogfood/keeper/genesis.go @@ -46,7 +46,7 @@ func (k Keeper) InitGenesis( panic(fmt.Errorf("could not create the dogfood AVS: %s", err)) } avsAddrString := avsAddr.String() - ctx.Logger().With(types.ModuleName).Info(fmt.Sprintf("created dogfood avs %s %s", avsAddrString, ctx.ChainID())) + k.Logger(ctx).Info(fmt.Sprintf("created dogfood avs %s %s", avsAddrString, ctx.ChainID())) // create the validators out := make([]exocoretypes.WrappedConsKeyWithPower, 0, len(genState.ValSet)) for _, val := range genState.ValSet { diff --git a/x/dogfood/keeper/impl_delegation_hooks.go b/x/dogfood/keeper/impl_delegation_hooks.go index 7f298ae79..ceb581984 100644 --- a/x/dogfood/keeper/impl_delegation_hooks.go +++ b/x/dogfood/keeper/impl_delegation_hooks.go @@ -3,8 +3,8 @@ package keeper import ( "fmt" + exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -37,7 +37,7 @@ func (wrapper DelegationHooksWrapper) AfterDelegation( func (wrapper DelegationHooksWrapper) AfterUndelegationStarted( ctx sdk.Context, operator sdk.AccAddress, recordKey []byte, ) error { - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(ctx.ChainID()) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()) var unbondingCompletionEpoch int64 if wrapper.keeper.operatorKeeper.IsOperatorRemovingKeyFromChainID( ctx, operator, chainIDWithoutRevision, diff --git a/x/dogfood/keeper/impl_epochs_hooks_test.go b/x/dogfood/keeper/impl_epochs_hooks_test.go index 727dc66ec..437f8b87e 100644 --- a/x/dogfood/keeper/impl_epochs_hooks_test.go +++ b/x/dogfood/keeper/impl_epochs_hooks_test.go @@ -3,10 +3,10 @@ package keeper_test import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" + exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestSameEpochOperations() { // generate keys, and get the AVS address oldKey := utiltx.GenerateConsensusKey() newKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) // now define the operations @@ -252,7 +252,7 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { // generate keys, and get the AVS address oldKey := utiltx.GenerateConsensusKey() newKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) // now define the operations diff --git a/x/dogfood/keeper/impl_operator_hooks.go b/x/dogfood/keeper/impl_operator_hooks.go index 2d9532649..5d39b2899 100644 --- a/x/dogfood/keeper/impl_operator_hooks.go +++ b/x/dogfood/keeper/impl_operator_hooks.go @@ -1,8 +1,8 @@ package keeper import ( + exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -48,7 +48,7 @@ func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( // 3. X epochs later, the reverse lookup of old cons addr + chain id -> operator addr // should be cleared. consAddr := oldKey.ToConsAddr() - if chainID == avstypes.ChainIDWithoutRevision(ctx.ChainID()) { + if chainID == exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()) { // is the oldKey already active? if not, we should not do anything. // this can happen if we opt in with a key, then replace it with another key // during the same epoch. @@ -80,7 +80,7 @@ func (h OperatorHooksWrapper) AfterOperatorKeyRemovalInitiated( // keys from the chain. // 2. X epochs later, the removal is marked complete in the operator module. consAddr := key.ToConsAddr() - if chainID == avstypes.ChainIDWithoutRevision(ctx.ChainID()) { + if chainID == exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()) { _, found := h.keeper.GetExocoreValidator(ctx, consAddr) if found { h.keeper.SetOptOutInformation(ctx, operator) diff --git a/x/dogfood/keeper/impl_sdk.go b/x/dogfood/keeper/impl_sdk.go index 48d1a9426..5d5a1fcdb 100644 --- a/x/dogfood/keeper/impl_sdk.go +++ b/x/dogfood/keeper/impl_sdk.go @@ -4,7 +4,7 @@ import ( "sort" "cosmossdk.io/math" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" + exocoretypes "github.com/ExocoreNetwork/exocore/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" @@ -74,7 +74,7 @@ func (k Keeper) ValidatorByConsAddr( // a call to Validator(ctx, addr) in the slashing module, which is implemented in this file. // after that call, the ConsPubKey is fetched, which is also set by the below call. val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, addr, avstypes.ChainIDWithoutRevision(ctx.ChainID()), + ctx, addr, exocoretypes.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { return nil @@ -104,7 +104,7 @@ func (k Keeper) SlashWithInfractionReason( slashFactor sdk.Dec, infraction stakingtypes.Infraction, ) math.Int { found, accAddress := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( - ctx, avstypes.ChainIDWithoutRevision(ctx.ChainID()), addr, + ctx, exocoretypes.ChainIDWithoutRevision(ctx.ChainID()), addr, ) if !found { // TODO(mm): already slashed and removed from the set? @@ -122,7 +122,7 @@ func (k Keeper) SlashWithInfractionReason( // It delegates the call to the operator module. Alternatively, this may be handled // by the slashing module depending upon the design decisions. func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) { - k.operatorKeeper.Jail(ctx, addr, avstypes.ChainIDWithoutRevision(ctx.ChainID())) + k.operatorKeeper.Jail(ctx, addr, exocoretypes.ChainIDWithoutRevision(ctx.ChainID())) // TODO(mm) // once the operator module jails someone, a hook should be triggered // and the validator removed from the set. same for unjailing. @@ -133,7 +133,7 @@ func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) { // operator to do so. TODO(mm): We need to use the SDK's slashing module to allow for downtime // slashing but somehow we need to prevent its Unjail function from being called by anyone. func (k Keeper) Unjail(ctx sdk.Context, addr sdk.ConsAddress) { - k.operatorKeeper.Unjail(ctx, addr, avstypes.ChainIDWithoutRevision(ctx.ChainID())) + k.operatorKeeper.Unjail(ctx, addr, exocoretypes.ChainIDWithoutRevision(ctx.ChainID())) } // Delegation is an implementation of the staking interface expected by the SDK's slashing @@ -148,7 +148,10 @@ func (k Keeper) Delegation( operator := delegator operatorUSDValues, err := k.operatorKeeper.GetOrCalculateOperatorUSDValues(ctx, operator, ctx.ChainID()) if err != nil { - k.Logger(ctx).Error("Delegation: failed to get or calculate the operator USD values", "operator", operator.String(), "chainID", ctx.ChainID(), "error", err) + k.Logger(ctx).Error( + "Delegation: failed to get or calculate the operator USD values", + "operator", operator.String(), "chainID", ctx.ChainID(), "error", err, + ) return nil } return stakingtypes.Delegation{ @@ -176,7 +179,7 @@ func (k Keeper) GetAllValidators(sdk.Context) (validators []stakingtypes.Validat // slashing module. It is called by the slashing module to record validator signatures // for downtime tracking. We delegate the call to the operator keeper. func (k Keeper) IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool { - return k.operatorKeeper.IsOperatorJailedForChainID(ctx, addr, avstypes.ChainIDWithoutRevision(ctx.ChainID())) + return k.operatorKeeper.IsOperatorJailedForChainID(ctx, addr, exocoretypes.ChainIDWithoutRevision(ctx.ChainID())) } // ApplyAndReturnValidatorSetUpdates is an implementation of the staking interface expected @@ -206,7 +209,7 @@ func (k Keeper) IterateBondedValidatorsByPower( continue } val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, sdk.GetConsAddress(pk), avstypes.ChainIDWithoutRevision(ctx.ChainID()), + ctx, sdk.GetConsAddress(pk), exocoretypes.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { ctx.Logger().Error("Operator address not found; skipping", "consAddress", sdk.GetConsAddress(pk), "i", i) diff --git a/x/dogfood/keeper/opt_out_test.go b/x/dogfood/keeper/opt_out_test.go index 1a2726612..4078ae0a5 100644 --- a/x/dogfood/keeper/opt_out_test.go +++ b/x/dogfood/keeper/opt_out_test.go @@ -4,10 +4,10 @@ import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" + exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" operatorkeeper "github.com/ExocoreNetwork/exocore/x/operator/keeper" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -30,7 +30,7 @@ func (suite *KeeperTestSuite) TestBasicOperations() { suite.CheckLengthOfValidatorUpdates(0, nil, "register operator but don't opt in") // opt-in with a key - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) key := utiltx.GenerateConsensusKey() _, err = suite.OperatorMsgServer.OptIntoAVS(sdk.WrapSDKContext(suite.Ctx), &operatortypes.OptIntoAVSReq{ diff --git a/x/dogfood/keeper/unbonding_test.go b/x/dogfood/keeper/unbonding_test.go index a9e76d10e..ecdd5beee 100644 --- a/x/dogfood/keeper/unbonding_test.go +++ b/x/dogfood/keeper/unbonding_test.go @@ -3,9 +3,9 @@ package keeper_test import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" + exocoretypes "github.com/ExocoreNetwork/exocore/types" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -67,7 +67,7 @@ func (suite *KeeperTestSuite) TestUndelegations() { suite.NoError(err) // opt in oldKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) _, err = suite.OperatorMsgServer.OptIntoAVS( sdk.WrapSDKContext(suite.Ctx), @@ -228,7 +228,7 @@ func (suite *KeeperTestSuite) TestUndelegationEdgeCases() { suite.CheckLengthOfValidatorUpdates(0, []int64{}, "undelegate without opt in") // opt in oldKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) _, err = suite.OperatorMsgServer.OptIntoAVS( sdk.WrapSDKContext(suite.Ctx), diff --git a/x/dogfood/keeper/validators.go b/x/dogfood/keeper/validators.go index f8283d101..1d747b818 100644 --- a/x/dogfood/keeper/validators.go +++ b/x/dogfood/keeper/validators.go @@ -5,8 +5,8 @@ import ( "time" "cosmossdk.io/math" + exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/dogfood/types" abci "github.com/cometbft/cometbft/abci/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -70,7 +70,7 @@ func (k Keeper) ApplyValidatorChanges( // via stakingkeeeper.Validator(ctx, valAddr) // then it fetches the cons pub key from said validator to generate the lookup found, accAddress := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( - ctx, avstypes.ChainIDWithoutRevision(ctx.ChainID()), addr, + ctx, exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()), addr, ) if !found { // should never happen @@ -341,13 +341,13 @@ func (k Keeper) GetValidator( ) (stakingtypes.Validator, bool) { accAddr := sdk.AccAddress(valAddr) found, wrappedKey, err := k.operatorKeeper.GetOperatorConsKeyForChainID( - ctx, accAddr, avstypes.ChainIDWithoutRevision(ctx.ChainID()), + ctx, accAddr, exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()), ) if !found || err != nil || wrappedKey == nil { return stakingtypes.Validator{}, false } val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, wrappedKey.ToConsAddr(), avstypes.ChainIDWithoutRevision(ctx.ChainID()), + ctx, wrappedKey.ToConsAddr(), exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { return stakingtypes.Validator{}, false diff --git a/x/operator/keeper/grpc_query.go b/x/operator/keeper/grpc_query.go index 5a2c84d41..bdcf99882 100644 --- a/x/operator/keeper/grpc_query.go +++ b/x/operator/keeper/grpc_query.go @@ -6,9 +6,9 @@ import ( assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" + exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ExocoreNetwork/exocore/utils" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/operator/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/store/prefix" @@ -57,7 +57,7 @@ func (k *Keeper) QueryOperatorConsKeyForChainID( if err != nil { return nil, err } - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(req.Chain) found, key, err := k.GetOperatorConsKeyForChainID( ctx, addr, chainIDWithoutRevision, ) @@ -84,7 +84,7 @@ func (k Keeper) QueryOperatorConsAddressForChainID( if err != nil { return nil, err } - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(req.Chain) found, wrappedKey, err := k.GetOperatorConsKeyForChainID( ctx, addr, chainIDWithoutRevision, ) @@ -108,7 +108,7 @@ func (k Keeper) QueryAllOperatorConsKeysByChainID( ) (*types.QueryAllOperatorConsKeysByChainIDResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) res := make([]*types.OperatorConsKeyPair, 0) - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(req.Chain) chainPrefix := types.ChainIDAndAddrKey( types.BytePrefixForChainIDAndOperatorToConsKey, chainIDWithoutRevision, nil, @@ -145,7 +145,7 @@ func (k Keeper) QueryAllOperatorConsAddrsByChainID( ) (*types.QueryAllOperatorConsAddrsByChainIDResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) res := make([]*types.OperatorConsAddrPair, 0) - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(req.Chain) chainPrefix := types.ChainIDAndAddrKey( types.BytePrefixForChainIDAndOperatorToConsKey, chainIDWithoutRevision, nil, diff --git a/x/operator/keeper/slash.go b/x/operator/keeper/slash.go index e9fb2223c..7546d47af 100644 --- a/x/operator/keeper/slash.go +++ b/x/operator/keeper/slash.go @@ -9,8 +9,8 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" - avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -178,7 +178,7 @@ func (k Keeper) SlashWithInfractionReason( ctx sdk.Context, addr sdk.AccAddress, infractionHeight, power int64, slashFactor sdk.Dec, infraction stakingtypes.Infraction, ) sdkmath.Int { - chainID := avstypes.ChainIDWithoutRevision(ctx.ChainID()) + chainID := exocoretypes.ChainIDWithoutRevision(ctx.ChainID()) isAvs, avsAddr := k.avsKeeper.IsAVSByChainID(ctx, chainID) if !isAvs { k.Logger(ctx).Error("the chainID is not supported by AVS", chainID) diff --git a/x/operator/keeper/slash_test.go b/x/operator/keeper/slash_test.go index 9ec64dcb8..9549f1a15 100644 --- a/x/operator/keeper/slash_test.go +++ b/x/operator/keeper/slash_test.go @@ -4,6 +4,7 @@ import ( "time" sdkmath "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/operator/keeper" "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -23,7 +24,7 @@ func (suite *OperatorTestSuite) TestSlashWithInfractionReason() { suite.prepareDelegation(true, suite.assetAddr, delegationAmount) // opt into the AVS - avsAddr := avstypes.GenerateAVSAddr(avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID())).String() + avsAddr := avstypes.GenerateAVSAddr(exocoretypes.ChainIDWithoutRevision(suite.Ctx.ChainID())).String() err := suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, avsAddr) suite.NoError(err) // call the EndBlock to update the voting power diff --git a/x/operator/keeper/usd_value_test.go b/x/operator/keeper/usd_value_test.go index a1de54406..2fefd7857 100644 --- a/x/operator/keeper/usd_value_test.go +++ b/x/operator/keeper/usd_value_test.go @@ -4,6 +4,7 @@ import ( "time" sdkmath "cosmossdk.io/math" + exocoretypes "github.com/ExocoreNetwork/exocore/types" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" operatorKeeper "github.com/ExocoreNetwork/exocore/x/operator/keeper" @@ -114,8 +115,8 @@ func (suite *OperatorTestSuite) TestVotingPowerForDogFood() { addPower := 1 addUSDValue := sdkmath.LegacyNewDec(1) - chainIDWithoutRevision := avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) - avsAddress := avstypes.GenerateAVSAddr(avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID())).String() + chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + avsAddress := avstypes.GenerateAVSAddr(chainIDWithoutRevision).String() // CommitAfter causes the epoch hook to be triggered, and results in writing // of the AVS usd value to the store. suite.CommitAfter(time.Hour*24 + time.Nanosecond) From 9b21e4825e3d7e2d425a5be1cfce72d3335f4a10 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:45:06 +0000 Subject: [PATCH 36/52] fix build --- x/dogfood/keeper/msg_server.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/x/dogfood/keeper/msg_server.go b/x/dogfood/keeper/msg_server.go index 666bc717c..9167e598e 100644 --- a/x/dogfood/keeper/msg_server.go +++ b/x/dogfood/keeper/msg_server.go @@ -5,6 +5,7 @@ import ( "strings" "cosmossdk.io/errors" + exocoretypes "github.com/ExocoreNetwork/exocore/types" avskeeper "github.com/ExocoreNetwork/exocore/x/avs/keeper" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" @@ -110,9 +111,13 @@ func (k Keeper) UpdateParams( k.SetParams(c, nextParams) // update the related info in the AVS module - isAVS, avsAddr := k.avsKeeper.IsAVSByChainID(c, avstypes.ChainIDWithoutRevision(c.ChainID())) + isAVS, avsAddr := k.avsKeeper.IsAVSByChainID( + c, exocoretypes.ChainIDWithoutRevision(c.ChainID()), + ) if !isAVS { - return nil, errors.Wrapf(types.ErrNotAVSByChainID, "chainID:%s avsAddr:%s", c.ChainID(), avsAddr) + return nil, errors.Wrapf( + types.ErrNotAVSByChainID, "chainID:%s avsAddr:%s", c.ChainID(), avsAddr, + ) } err := k.avsKeeper.UpdateAVSInfo(c, &avstypes.AVSRegisterOrDeregisterParams{ AvsName: c.ChainID(), From a8a8d1fe3d091686dd87a8e103e40c78394a841c Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:51:20 +0000 Subject: [PATCH 37/52] chore: lint the proto file --- proto/exocore/appchain/common/v1/wire.proto | 4 +++- x/appchain/common/types/wire.pb.go | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/proto/exocore/appchain/common/v1/wire.proto b/proto/exocore/appchain/common/v1/wire.proto index 96bd36304..a496ce12a 100644 --- a/proto/exocore/appchain/common/v1/wire.proto +++ b/proto/exocore/appchain/common/v1/wire.proto @@ -12,8 +12,10 @@ option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/common/types"; // the coordinator or each of the subcribers. message HandshakeMetadata { - // This address is where the subscriber chain will send the fees proportionally + // coordinator_fee_pool_addr is the address on the coordinator to which the + // subscriber chain will send the fees proportionally and periodically. string coordinator_fee_pool_addr = 1; + // version is the version of the appchain protocol string version = 2; } diff --git a/x/appchain/common/types/wire.pb.go b/x/appchain/common/types/wire.pb.go index 0a95ba741..da45be2ee 100644 --- a/x/appchain/common/types/wire.pb.go +++ b/x/appchain/common/types/wire.pb.go @@ -61,9 +61,11 @@ func (SubscriberPacketDataType) EnumDescriptor() ([]byte, []int) { } type HandshakeMetadata struct { - // This address is where the subscriber chain will send the fees proportionally + // coordinator_fee_pool_addr is the address on the coordinator to which the + // subscriber chain will send the fees proportionally and periodically. CoordinatorFeePoolAddr string `protobuf:"bytes,1,opt,name=coordinator_fee_pool_addr,json=coordinatorFeePoolAddr,proto3" json:"coordinator_fee_pool_addr,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // version is the version of the appchain protocol + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` } func (m *HandshakeMetadata) Reset() { *m = HandshakeMetadata{} } From 05cee6d9074689df05a8c4b0fe52ca4c70dfbeac Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 10:02:19 +0000 Subject: [PATCH 38/52] attempt to fix tests --- types/chain_id.go | 11 ----------- utils/utils.go | 11 +++++++++++ x/appchain/coordinator/keeper/ibc_client.go | 4 ++-- x/appchain/coordinator/keeper/impl_epochs_hooks.go | 4 ++-- x/appchain/coordinator/keeper/slash.go | 4 ++-- x/avs/keeper/avs.go | 4 ++-- x/avs/keeper/keeper.go | 4 ++-- x/avs/keeper/query.go | 4 ++-- x/dogfood/keeper/abci.go | 4 ++-- x/dogfood/keeper/impl_delegation_hooks.go | 4 ++-- x/dogfood/keeper/impl_epochs_hooks_test.go | 6 +++--- x/dogfood/keeper/impl_operator_hooks.go | 6 +++--- x/dogfood/keeper/impl_sdk.go | 14 +++++++------- x/dogfood/keeper/msg_server.go | 4 ++-- x/dogfood/keeper/opt_out_test.go | 4 ++-- x/dogfood/keeper/unbonding_test.go | 6 +++--- x/dogfood/keeper/validators.go | 8 ++++---- x/operator/keeper/grpc_query.go | 10 +++++----- x/operator/keeper/slash.go | 4 ++-- x/operator/keeper/slash_test.go | 4 ++-- x/operator/keeper/usd_value_test.go | 4 ++-- 21 files changed, 62 insertions(+), 62 deletions(-) diff --git a/types/chain_id.go b/types/chain_id.go index 323918c0f..e8bf2b4c0 100644 --- a/types/chain_id.go +++ b/types/chain_id.go @@ -7,7 +7,6 @@ import ( "strings" errorsmod "cosmossdk.io/errors" - ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) var ( @@ -54,13 +53,3 @@ func ParseChainID(chainID string) (*big.Int, error) { return chainIDInt, nil } - -// ChainIDWithoutRevision returns the chainID without the revision number. -// For example, "exocoretestnet_233-1" returns "exocoretestnet_233". -func ChainIDWithoutRevision(chainID string) string { - if !ibcclienttypes.IsRevisionFormat(chainID) { - return chainID - } - splitStr := strings.Split(chainID, "-") - return splitStr[0] -} diff --git a/utils/utils.go b/utils/utils.go index c9f3e87ba..e3ccb166d 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -11,6 +11,7 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" sdk "github.com/cosmos/cosmos-sdk/types" + ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" "github.com/evmos/evmos/v14/crypto/ethsecp256k1" ) @@ -195,3 +196,13 @@ func AppendMany(byteses ...[]byte) (out []byte) { } return out } + +// ChainIDWithoutRevision returns the chainID without the revision number. +// For example, "exocoretestnet_233-1" returns "exocoretestnet_233". +func ChainIDWithoutRevision(chainID string) string { + if !ibcclienttypes.IsRevisionFormat(chainID) { + return chainID + } + splitStr := strings.Split(chainID, "-") + return splitStr[0] +} diff --git a/x/appchain/coordinator/keeper/ibc_client.go b/x/appchain/coordinator/keeper/ibc_client.go index 94e96da11..bc56f6529 100644 --- a/x/appchain/coordinator/keeper/ibc_client.go +++ b/x/appchain/coordinator/keeper/ibc_client.go @@ -4,8 +4,8 @@ import ( "fmt" errorsmod "cosmossdk.io/errors" - exocoretypes "github.com/ExocoreNetwork/exocore/types" "github.com/ExocoreNetwork/exocore/utils" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" abci "github.com/cometbft/cometbft/abci/types" @@ -134,7 +134,7 @@ func (k Keeper) MakeSubscriberGenesis( params := k.GetParams(ctx) chainID := req.ChainID k.Logger(ctx).Info("Creating genesis state for subscriber chain", "chainID", chainID) - chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(chainID) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(chainID) coordinatorUnbondingPeriod := k.stakingKeeper.UnbondingTime(ctx) // client state clientState := params.TemplateClient diff --git a/x/appchain/coordinator/keeper/impl_epochs_hooks.go b/x/appchain/coordinator/keeper/impl_epochs_hooks.go index 26e4bc58f..542daecdd 100644 --- a/x/appchain/coordinator/keeper/impl_epochs_hooks.go +++ b/x/appchain/coordinator/keeper/impl_epochs_hooks.go @@ -1,7 +1,7 @@ package keeper import ( - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -42,7 +42,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( ) // clear the registered AVS. remember that this module stores // the chainID with the revision but the AVS module stores it without. - chainID := exocoretypes.ChainIDWithoutRevision(subscriber.ChainID) + chainID := exocoreutils.ChainIDWithoutRevision(subscriber.ChainID) // always guaranteed to exist _, addr := wrapper.keeper.avsKeeper.IsAVSByChainID(ctx, chainID) if err := wrapper.keeper.avsKeeper.DeleteAVSInfo(ctx, addr); err != nil { diff --git a/x/appchain/coordinator/keeper/slash.go b/x/appchain/coordinator/keeper/slash.go index e84d476ef..e24be111f 100644 --- a/x/appchain/coordinator/keeper/slash.go +++ b/x/appchain/coordinator/keeper/slash.go @@ -3,7 +3,7 @@ package keeper import ( "time" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" types "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -55,7 +55,7 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data commonty // #nosec G703 // already validated slashProportionDecimal, _ := sdk.NewDecFromStr(slashProportion) jailDuration := k.GetSubDowntimeJailDuration(ctx, chainID) - chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(chainID) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(chainID) _, avsAddress := k.avsKeeper.IsAVSByChainID(ctx, chainIDWithoutRevision) // the slashing hook should trigger a validator set update for all affected AVSs. since the `chainID` is one of them // we should make sure we are well set up for that update. we will include an ack of the slash packet in the next diff --git a/x/avs/keeper/avs.go b/x/avs/keeper/avs.go index afebef682..7b0d3e370 100644 --- a/x/avs/keeper/avs.go +++ b/x/avs/keeper/avs.go @@ -7,7 +7,7 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ethereum/go-ethereum/common" "github.com/evmos/evmos/v14/x/evm/statedb" @@ -119,7 +119,7 @@ func (k Keeper) RegisterAVSWithChainID( // guard against errors ctx, writeFunc := oCtx.CacheContext() // remove the version number and validate - params.ChainID = exocoretypes.ChainIDWithoutRevision(params.ChainID) + params.ChainID = exocoreutils.ChainIDWithoutRevision(params.ChainID) if len(params.ChainID) == 0 { return common.Address{}, errorsmod.Wrap(types.ErrNotNull, "RegisterAVSWithChainID: chainID is null") } diff --git a/x/avs/keeper/keeper.go b/x/avs/keeper/keeper.go index e1391597f..ddc56c5bc 100644 --- a/x/avs/keeper/keeper.go +++ b/x/avs/keeper/keeper.go @@ -8,7 +8,7 @@ import ( errorsmod "cosmossdk.io/errors" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" @@ -84,7 +84,7 @@ func (k Keeper) UpdateAVSInfo(ctx sdk.Context, params *types.AVSRegisterOrDeregi return errorsmod.Wrap(types.ErrAlreadyRegistered, fmt.Sprintf("the avsaddress is :%s", params.AvsAddress)) } startingEpoch := uint64(epoch.CurrentEpoch + 1) - if params.ChainID == exocoretypes.ChainIDWithoutRevision(ctx.ChainID()) { + if params.ChainID == exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) { // TODO: handle this better startingEpoch = uint64(epoch.CurrentEpoch) } diff --git a/x/avs/keeper/query.go b/x/avs/keeper/query.go index b6e7dfcf9..8dbb97d41 100644 --- a/x/avs/keeper/query.go +++ b/x/avs/keeper/query.go @@ -3,7 +3,7 @@ package keeper import ( "context" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/avs/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -23,7 +23,7 @@ func (k Keeper) QueryAVSTaskInfo(ctx context.Context, req *types.QueryAVSTaskInf // QueryAVSAddrByChainID is an implementation of the QueryAVSAddrByChainID gRPC method func (k Keeper) QueryAVSAddrByChainID(ctx context.Context, req *types.QueryAVSAddrByChainIDReq) (*types.QueryAVSAddrByChainIDResponse, error) { c := sdk.UnwrapSDKContext(ctx) - isChainAvs, avsAddr := k.IsAVSByChainID(c, exocoretypes.ChainIDWithoutRevision(req.ChainID)) + isChainAvs, avsAddr := k.IsAVSByChainID(c, exocoreutils.ChainIDWithoutRevision(req.ChainID)) if !isChainAvs { return nil, types.ErrNotYetRegistered } diff --git a/x/dogfood/keeper/abci.go b/x/dogfood/keeper/abci.go index 836a5ab66..a967c9e62 100644 --- a/x/dogfood/keeper/abci.go +++ b/x/dogfood/keeper/abci.go @@ -2,9 +2,9 @@ package keeper import ( "cosmossdk.io/math" - exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ExocoreNetwork/exocore/utils" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -20,7 +20,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } defer k.ClearEpochEnd(ctx) - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) // start by clearing the previous consensus keys for the chain. // each AVS can have a separate epoch and hence this function is a part of this module // and not the operator module. diff --git a/x/dogfood/keeper/impl_delegation_hooks.go b/x/dogfood/keeper/impl_delegation_hooks.go index ceb581984..f65561692 100644 --- a/x/dogfood/keeper/impl_delegation_hooks.go +++ b/x/dogfood/keeper/impl_delegation_hooks.go @@ -3,8 +3,8 @@ package keeper import ( "fmt" - exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -37,7 +37,7 @@ func (wrapper DelegationHooksWrapper) AfterDelegation( func (wrapper DelegationHooksWrapper) AfterUndelegationStarted( ctx sdk.Context, operator sdk.AccAddress, recordKey []byte, ) error { - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) var unbondingCompletionEpoch int64 if wrapper.keeper.operatorKeeper.IsOperatorRemovingKeyFromChainID( ctx, operator, chainIDWithoutRevision, diff --git a/x/dogfood/keeper/impl_epochs_hooks_test.go b/x/dogfood/keeper/impl_epochs_hooks_test.go index 0c76dec8e..0d79bab95 100644 --- a/x/dogfood/keeper/impl_epochs_hooks_test.go +++ b/x/dogfood/keeper/impl_epochs_hooks_test.go @@ -3,8 +3,8 @@ package keeper_test import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" - exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" @@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestSameEpochOperations() { // generate keys, and get the AVS address oldKey := utiltx.GenerateConsensusKey() newKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) // now define the operations @@ -252,7 +252,7 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { // generate keys, and get the AVS address oldKey := utiltx.GenerateConsensusKey() newKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) // now define the operations diff --git a/x/dogfood/keeper/impl_operator_hooks.go b/x/dogfood/keeper/impl_operator_hooks.go index 5d39b2899..a66bfbb40 100644 --- a/x/dogfood/keeper/impl_operator_hooks.go +++ b/x/dogfood/keeper/impl_operator_hooks.go @@ -1,8 +1,8 @@ package keeper import ( - exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -48,7 +48,7 @@ func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( // 3. X epochs later, the reverse lookup of old cons addr + chain id -> operator addr // should be cleared. consAddr := oldKey.ToConsAddr() - if chainID == exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()) { + if chainID == exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) { // is the oldKey already active? if not, we should not do anything. // this can happen if we opt in with a key, then replace it with another key // during the same epoch. @@ -80,7 +80,7 @@ func (h OperatorHooksWrapper) AfterOperatorKeyRemovalInitiated( // keys from the chain. // 2. X epochs later, the removal is marked complete in the operator module. consAddr := key.ToConsAddr() - if chainID == exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()) { + if chainID == exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) { _, found := h.keeper.GetExocoreValidator(ctx, consAddr) if found { h.keeper.SetOptOutInformation(ctx, operator) diff --git a/x/dogfood/keeper/impl_sdk.go b/x/dogfood/keeper/impl_sdk.go index 5d5a1fcdb..bef635014 100644 --- a/x/dogfood/keeper/impl_sdk.go +++ b/x/dogfood/keeper/impl_sdk.go @@ -4,7 +4,7 @@ import ( "sort" "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" @@ -74,7 +74,7 @@ func (k Keeper) ValidatorByConsAddr( // a call to Validator(ctx, addr) in the slashing module, which is implemented in this file. // after that call, the ConsPubKey is fetched, which is also set by the below call. val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, addr, exocoretypes.ChainIDWithoutRevision(ctx.ChainID()), + ctx, addr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { return nil @@ -104,7 +104,7 @@ func (k Keeper) SlashWithInfractionReason( slashFactor sdk.Dec, infraction stakingtypes.Infraction, ) math.Int { found, accAddress := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( - ctx, exocoretypes.ChainIDWithoutRevision(ctx.ChainID()), addr, + ctx, exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), addr, ) if !found { // TODO(mm): already slashed and removed from the set? @@ -122,7 +122,7 @@ func (k Keeper) SlashWithInfractionReason( // It delegates the call to the operator module. Alternatively, this may be handled // by the slashing module depending upon the design decisions. func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) { - k.operatorKeeper.Jail(ctx, addr, exocoretypes.ChainIDWithoutRevision(ctx.ChainID())) + k.operatorKeeper.Jail(ctx, addr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID())) // TODO(mm) // once the operator module jails someone, a hook should be triggered // and the validator removed from the set. same for unjailing. @@ -133,7 +133,7 @@ func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) { // operator to do so. TODO(mm): We need to use the SDK's slashing module to allow for downtime // slashing but somehow we need to prevent its Unjail function from being called by anyone. func (k Keeper) Unjail(ctx sdk.Context, addr sdk.ConsAddress) { - k.operatorKeeper.Unjail(ctx, addr, exocoretypes.ChainIDWithoutRevision(ctx.ChainID())) + k.operatorKeeper.Unjail(ctx, addr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID())) } // Delegation is an implementation of the staking interface expected by the SDK's slashing @@ -179,7 +179,7 @@ func (k Keeper) GetAllValidators(sdk.Context) (validators []stakingtypes.Validat // slashing module. It is called by the slashing module to record validator signatures // for downtime tracking. We delegate the call to the operator keeper. func (k Keeper) IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool { - return k.operatorKeeper.IsOperatorJailedForChainID(ctx, addr, exocoretypes.ChainIDWithoutRevision(ctx.ChainID())) + return k.operatorKeeper.IsOperatorJailedForChainID(ctx, addr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID())) } // ApplyAndReturnValidatorSetUpdates is an implementation of the staking interface expected @@ -209,7 +209,7 @@ func (k Keeper) IterateBondedValidatorsByPower( continue } val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, sdk.GetConsAddress(pk), exocoretypes.ChainIDWithoutRevision(ctx.ChainID()), + ctx, sdk.GetConsAddress(pk), exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { ctx.Logger().Error("Operator address not found; skipping", "consAddress", sdk.GetConsAddress(pk), "i", i) diff --git a/x/dogfood/keeper/msg_server.go b/x/dogfood/keeper/msg_server.go index 9167e598e..5fb026381 100644 --- a/x/dogfood/keeper/msg_server.go +++ b/x/dogfood/keeper/msg_server.go @@ -5,7 +5,7 @@ import ( "strings" "cosmossdk.io/errors" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" avskeeper "github.com/ExocoreNetwork/exocore/x/avs/keeper" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" @@ -112,7 +112,7 @@ func (k Keeper) UpdateParams( // update the related info in the AVS module isAVS, avsAddr := k.avsKeeper.IsAVSByChainID( - c, exocoretypes.ChainIDWithoutRevision(c.ChainID()), + c, exocoreutils.ChainIDWithoutRevision(c.ChainID()), ) if !isAVS { return nil, errors.Wrapf( diff --git a/x/dogfood/keeper/opt_out_test.go b/x/dogfood/keeper/opt_out_test.go index 4078ae0a5..1a08944c6 100644 --- a/x/dogfood/keeper/opt_out_test.go +++ b/x/dogfood/keeper/opt_out_test.go @@ -4,8 +4,8 @@ import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" - exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" @@ -30,7 +30,7 @@ func (suite *KeeperTestSuite) TestBasicOperations() { suite.CheckLengthOfValidatorUpdates(0, nil, "register operator but don't opt in") // opt-in with a key - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) key := utiltx.GenerateConsensusKey() _, err = suite.OperatorMsgServer.OptIntoAVS(sdk.WrapSDKContext(suite.Ctx), &operatortypes.OptIntoAVSReq{ diff --git a/x/dogfood/keeper/unbonding_test.go b/x/dogfood/keeper/unbonding_test.go index ecdd5beee..a6f473acc 100644 --- a/x/dogfood/keeper/unbonding_test.go +++ b/x/dogfood/keeper/unbonding_test.go @@ -3,7 +3,7 @@ package keeper_test import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" @@ -67,7 +67,7 @@ func (suite *KeeperTestSuite) TestUndelegations() { suite.NoError(err) // opt in oldKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) _, err = suite.OperatorMsgServer.OptIntoAVS( sdk.WrapSDKContext(suite.Ctx), @@ -228,7 +228,7 @@ func (suite *KeeperTestSuite) TestUndelegationEdgeCases() { suite.CheckLengthOfValidatorUpdates(0, []int64{}, "undelegate without opt in") // opt in oldKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) _, err = suite.OperatorMsgServer.OptIntoAVS( sdk.WrapSDKContext(suite.Ctx), diff --git a/x/dogfood/keeper/validators.go b/x/dogfood/keeper/validators.go index 1d747b818..89be9d8a7 100644 --- a/x/dogfood/keeper/validators.go +++ b/x/dogfood/keeper/validators.go @@ -5,8 +5,8 @@ import ( "time" "cosmossdk.io/math" - exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/dogfood/types" abci "github.com/cometbft/cometbft/abci/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -70,7 +70,7 @@ func (k Keeper) ApplyValidatorChanges( // via stakingkeeeper.Validator(ctx, valAddr) // then it fetches the cons pub key from said validator to generate the lookup found, accAddress := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( - ctx, exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()), addr, + ctx, exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), addr, ) if !found { // should never happen @@ -341,13 +341,13 @@ func (k Keeper) GetValidator( ) (stakingtypes.Validator, bool) { accAddr := sdk.AccAddress(valAddr) found, wrappedKey, err := k.operatorKeeper.GetOperatorConsKeyForChainID( - ctx, accAddr, exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()), + ctx, accAddr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), ) if !found || err != nil || wrappedKey == nil { return stakingtypes.Validator{}, false } val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, wrappedKey.ToConsAddr(), exocoretypes2.ChainIDWithoutRevision(ctx.ChainID()), + ctx, wrappedKey.ToConsAddr(), exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { return stakingtypes.Validator{}, false diff --git a/x/operator/keeper/grpc_query.go b/x/operator/keeper/grpc_query.go index bdcf99882..8e3d8455b 100644 --- a/x/operator/keeper/grpc_query.go +++ b/x/operator/keeper/grpc_query.go @@ -6,9 +6,9 @@ import ( assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" - exocoretypes2 "github.com/ExocoreNetwork/exocore/types" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ExocoreNetwork/exocore/utils" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/operator/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/store/prefix" @@ -57,7 +57,7 @@ func (k *Keeper) QueryOperatorConsKeyForChainID( if err != nil { return nil, err } - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(req.Chain) found, key, err := k.GetOperatorConsKeyForChainID( ctx, addr, chainIDWithoutRevision, ) @@ -84,7 +84,7 @@ func (k Keeper) QueryOperatorConsAddressForChainID( if err != nil { return nil, err } - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(req.Chain) found, wrappedKey, err := k.GetOperatorConsKeyForChainID( ctx, addr, chainIDWithoutRevision, ) @@ -108,7 +108,7 @@ func (k Keeper) QueryAllOperatorConsKeysByChainID( ) (*types.QueryAllOperatorConsKeysByChainIDResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) res := make([]*types.OperatorConsKeyPair, 0) - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(req.Chain) chainPrefix := types.ChainIDAndAddrKey( types.BytePrefixForChainIDAndOperatorToConsKey, chainIDWithoutRevision, nil, @@ -145,7 +145,7 @@ func (k Keeper) QueryAllOperatorConsAddrsByChainID( ) (*types.QueryAllOperatorConsAddrsByChainIDResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) res := make([]*types.OperatorConsAddrPair, 0) - chainIDWithoutRevision := exocoretypes2.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(req.Chain) chainPrefix := types.ChainIDAndAddrKey( types.BytePrefixForChainIDAndOperatorToConsKey, chainIDWithoutRevision, nil, diff --git a/x/operator/keeper/slash.go b/x/operator/keeper/slash.go index 7546d47af..24d576caf 100644 --- a/x/operator/keeper/slash.go +++ b/x/operator/keeper/slash.go @@ -9,7 +9,7 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -178,7 +178,7 @@ func (k Keeper) SlashWithInfractionReason( ctx sdk.Context, addr sdk.AccAddress, infractionHeight, power int64, slashFactor sdk.Dec, infraction stakingtypes.Infraction, ) sdkmath.Int { - chainID := exocoretypes.ChainIDWithoutRevision(ctx.ChainID()) + chainID := exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) isAvs, avsAddr := k.avsKeeper.IsAVSByChainID(ctx, chainID) if !isAvs { k.Logger(ctx).Error("the chainID is not supported by AVS", chainID) diff --git a/x/operator/keeper/slash_test.go b/x/operator/keeper/slash_test.go index 9549f1a15..b335b8002 100644 --- a/x/operator/keeper/slash_test.go +++ b/x/operator/keeper/slash_test.go @@ -4,7 +4,7 @@ import ( "time" sdkmath "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/operator/keeper" "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -24,7 +24,7 @@ func (suite *OperatorTestSuite) TestSlashWithInfractionReason() { suite.prepareDelegation(true, suite.assetAddr, delegationAmount) // opt into the AVS - avsAddr := avstypes.GenerateAVSAddr(exocoretypes.ChainIDWithoutRevision(suite.Ctx.ChainID())).String() + avsAddr := avstypes.GenerateAVSAddr(exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID())).String() err := suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, avsAddr) suite.NoError(err) // call the EndBlock to update the voting power diff --git a/x/operator/keeper/usd_value_test.go b/x/operator/keeper/usd_value_test.go index 2fefd7857..d0ef2e80e 100644 --- a/x/operator/keeper/usd_value_test.go +++ b/x/operator/keeper/usd_value_test.go @@ -4,7 +4,7 @@ import ( "time" sdkmath "cosmossdk.io/math" - exocoretypes "github.com/ExocoreNetwork/exocore/types" + exocoreutils "github.com/ExocoreNetwork/exocore/utils" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" operatorKeeper "github.com/ExocoreNetwork/exocore/x/operator/keeper" @@ -115,7 +115,7 @@ func (suite *OperatorTestSuite) TestVotingPowerForDogFood() { addPower := 1 addUSDValue := sdkmath.LegacyNewDec(1) - chainIDWithoutRevision := exocoretypes.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) avsAddress := avstypes.GenerateAVSAddr(chainIDWithoutRevision).String() // CommitAfter causes the epoch hook to be triggered, and results in writing // of the AVS usd value to the store. From bd43d6a12d7ff415e1ef3592730ab2bf8e19015c Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 11:23:48 +0000 Subject: [PATCH 39/52] fix retry --- types/benchmark_test.go | 6 ++++-- types/chain_id_test.go | 9 +++++---- types/validation_test.go | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/types/benchmark_test.go b/types/benchmark_test.go index 8636ec511..2d0f117b9 100644 --- a/types/benchmark_test.go +++ b/types/benchmark_test.go @@ -1,8 +1,10 @@ -package types +package types_test import ( "fmt" "testing" + + "github.com/evmos/evmos/v14/types" ) func BenchmarkParseChainID(b *testing.B) { @@ -10,7 +12,7 @@ func BenchmarkParseChainID(b *testing.B) { // Start at 1, for valid EIP155, see regexEIP155 variable. for i := 1; i < b.N; i++ { chainID := fmt.Sprintf("evmos_1-%d", i) - if _, err := ParseChainID(chainID); err != nil { + if _, err := types.ParseChainID(chainID); err != nil { b.Fatal(err) } } diff --git a/types/chain_id_test.go b/types/chain_id_test.go index f7c6cfaa0..85b608ef5 100644 --- a/types/chain_id_test.go +++ b/types/chain_id_test.go @@ -1,10 +1,11 @@ -package types +package types_test import ( "math/big" "strings" "testing" + "github.com/evmos/evmos/v14/types" "github.com/stretchr/testify/require" ) @@ -72,16 +73,16 @@ func TestParseChainID(t *testing.T) { } for _, tc := range testCases { - chainIDEpoch, err := ParseChainID(tc.chainID) + chainIDEpoch, err := types.ParseChainID(tc.chainID) if tc.expError { require.Error(t, err, tc.name) require.Nil(t, chainIDEpoch) - require.False(t, IsValidChainID(tc.chainID), tc.name) + require.False(t, types.IsValidChainID(tc.chainID), tc.name) } else { require.NoError(t, err, tc.name) require.Equal(t, tc.expInt, chainIDEpoch, tc.name) - require.True(t, IsValidChainID(tc.chainID)) + require.True(t, types.IsValidChainID(tc.chainID)) } } } diff --git a/types/validation_test.go b/types/validation_test.go index 7a909b19a..0d1dddadb 100644 --- a/types/validation_test.go +++ b/types/validation_test.go @@ -3,8 +3,8 @@ package types_test import ( "testing" + utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" "github.com/ethereum/go-ethereum/common" - utiltx "github.com/evmos/evmos/v14/testutil/tx" "github.com/evmos/evmos/v14/types" "github.com/stretchr/testify/require" ) From f080f54617541d65fc435c5420059cab14961967 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 11:27:02 +0000 Subject: [PATCH 40/52] Merge develop From 5acf5281c8b95086b7e1c25ed27ddb5a6f62290a Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 12:01:55 +0000 Subject: [PATCH 41/52] Fix tests --- types/account_test.go | 2 +- types/benchmark_test.go | 6 ++---- types/chain_id_test.go | 9 ++++----- types/validation_test.go | 13 ++++++------- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/types/account_test.go b/types/account_test.go index 5d0706dda..2c18e0cec 100644 --- a/types/account_test.go +++ b/types/account_test.go @@ -1,4 +1,4 @@ -package types_test +package types import ( "testing" diff --git a/types/benchmark_test.go b/types/benchmark_test.go index 2d0f117b9..8636ec511 100644 --- a/types/benchmark_test.go +++ b/types/benchmark_test.go @@ -1,10 +1,8 @@ -package types_test +package types import ( "fmt" "testing" - - "github.com/evmos/evmos/v14/types" ) func BenchmarkParseChainID(b *testing.B) { @@ -12,7 +10,7 @@ func BenchmarkParseChainID(b *testing.B) { // Start at 1, for valid EIP155, see regexEIP155 variable. for i := 1; i < b.N; i++ { chainID := fmt.Sprintf("evmos_1-%d", i) - if _, err := types.ParseChainID(chainID); err != nil { + if _, err := ParseChainID(chainID); err != nil { b.Fatal(err) } } diff --git a/types/chain_id_test.go b/types/chain_id_test.go index 85b608ef5..f7c6cfaa0 100644 --- a/types/chain_id_test.go +++ b/types/chain_id_test.go @@ -1,11 +1,10 @@ -package types_test +package types import ( "math/big" "strings" "testing" - "github.com/evmos/evmos/v14/types" "github.com/stretchr/testify/require" ) @@ -73,16 +72,16 @@ func TestParseChainID(t *testing.T) { } for _, tc := range testCases { - chainIDEpoch, err := types.ParseChainID(tc.chainID) + chainIDEpoch, err := ParseChainID(tc.chainID) if tc.expError { require.Error(t, err, tc.name) require.Nil(t, chainIDEpoch) - require.False(t, types.IsValidChainID(tc.chainID), tc.name) + require.False(t, IsValidChainID(tc.chainID), tc.name) } else { require.NoError(t, err, tc.name) require.Equal(t, tc.expInt, chainIDEpoch, tc.name) - require.True(t, types.IsValidChainID(tc.chainID)) + require.True(t, IsValidChainID(tc.chainID)) } } } diff --git a/types/validation_test.go b/types/validation_test.go index 0d1dddadb..8c9fc1f98 100644 --- a/types/validation_test.go +++ b/types/validation_test.go @@ -1,11 +1,10 @@ -package types_test +package types import ( "testing" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" "github.com/ethereum/go-ethereum/common" - "github.com/evmos/evmos/v14/types" "github.com/stretchr/testify/require" ) @@ -28,7 +27,7 @@ func TestIsEmptyHash(t *testing.T) { } for _, tc := range testCases { - require.Equal(t, tc.expEmpty, types.IsEmptyHash(tc.hash), tc.name) + require.Equal(t, tc.expEmpty, IsEmptyHash(tc.hash), tc.name) } } @@ -51,7 +50,7 @@ func TestIsZeroAddress(t *testing.T) { } for _, tc := range testCases { - require.Equal(t, tc.expEmpty, types.IsZeroAddress(tc.address), tc.name) + require.Equal(t, tc.expEmpty, IsZeroAddress(tc.address), tc.name) } } @@ -76,7 +75,7 @@ func TestValidateAddress(t *testing.T) { } for _, tc := range testCases { - err := types.ValidateAddress(tc.address) + err := ValidateAddress(tc.address) if tc.expError { require.Error(t, err, tc.name) @@ -107,7 +106,7 @@ func TestValidateNonZeroAddress(t *testing.T) { } for _, tc := range testCases { - err := types.ValidateNonZeroAddress(tc.address) + err := ValidateNonZeroAddress(tc.address) if tc.expError { require.Error(t, err, tc.name) @@ -132,7 +131,7 @@ func TestSafeInt64(t *testing.T) { } for _, tc := range testCases { - value, err := types.SafeInt64(tc.value) + value, err := SafeInt64(tc.value) if tc.expError { require.Error(t, err, tc.name) continue From 00c870773cb9dae9aed73fd82702394a4e7f76eb Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 12:09:21 +0000 Subject: [PATCH 42/52] chore: fix lint by removing duplicated imports --- x/appchain/coordinator/keeper/ibc_client.go | 3 +-- x/appchain/coordinator/keeper/impl_epochs_hooks.go | 4 ++-- x/appchain/coordinator/keeper/slash.go | 4 ++-- x/avs/keeper/avs.go | 4 ++-- x/avs/keeper/keeper.go | 4 ++-- x/avs/keeper/query.go | 4 ++-- x/dogfood/keeper/abci.go | 3 +-- x/dogfood/keeper/impl_delegation_hooks.go | 4 ++-- x/dogfood/keeper/impl_epochs_hooks_test.go | 6 +++--- x/dogfood/keeper/impl_operator_hooks.go | 6 +++--- x/dogfood/keeper/impl_sdk.go | 14 +++++++------- x/dogfood/keeper/msg_server.go | 4 ++-- x/dogfood/keeper/opt_out_test.go | 4 ++-- x/dogfood/keeper/unbonding_test.go | 6 +++--- x/dogfood/keeper/validators.go | 8 ++++---- x/operator/keeper/grpc_query.go | 9 ++++----- x/operator/keeper/slash.go | 4 ++-- x/operator/keeper/slash_test.go | 4 ++-- x/operator/keeper/usd_value_test.go | 4 ++-- 19 files changed, 48 insertions(+), 51 deletions(-) diff --git a/x/appchain/coordinator/keeper/ibc_client.go b/x/appchain/coordinator/keeper/ibc_client.go index bc56f6529..fff348c0d 100644 --- a/x/appchain/coordinator/keeper/ibc_client.go +++ b/x/appchain/coordinator/keeper/ibc_client.go @@ -5,7 +5,6 @@ import ( errorsmod "cosmossdk.io/errors" "github.com/ExocoreNetwork/exocore/utils" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" abci "github.com/cometbft/cometbft/abci/types" @@ -134,7 +133,7 @@ func (k Keeper) MakeSubscriberGenesis( params := k.GetParams(ctx) chainID := req.ChainID k.Logger(ctx).Info("Creating genesis state for subscriber chain", "chainID", chainID) - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(chainID) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(chainID) coordinatorUnbondingPeriod := k.stakingKeeper.UnbondingTime(ctx) // client state clientState := params.TemplateClient diff --git a/x/appchain/coordinator/keeper/impl_epochs_hooks.go b/x/appchain/coordinator/keeper/impl_epochs_hooks.go index 542daecdd..5ee43d80f 100644 --- a/x/appchain/coordinator/keeper/impl_epochs_hooks.go +++ b/x/appchain/coordinator/keeper/impl_epochs_hooks.go @@ -1,7 +1,7 @@ package keeper import ( - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -42,7 +42,7 @@ func (wrapper EpochsHooksWrapper) AfterEpochEnd( ) // clear the registered AVS. remember that this module stores // the chainID with the revision but the AVS module stores it without. - chainID := exocoreutils.ChainIDWithoutRevision(subscriber.ChainID) + chainID := utils.ChainIDWithoutRevision(subscriber.ChainID) // always guaranteed to exist _, addr := wrapper.keeper.avsKeeper.IsAVSByChainID(ctx, chainID) if err := wrapper.keeper.avsKeeper.DeleteAVSInfo(ctx, addr); err != nil { diff --git a/x/appchain/coordinator/keeper/slash.go b/x/appchain/coordinator/keeper/slash.go index e24be111f..7caaf572b 100644 --- a/x/appchain/coordinator/keeper/slash.go +++ b/x/appchain/coordinator/keeper/slash.go @@ -3,7 +3,7 @@ package keeper import ( "time" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" types "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -55,7 +55,7 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data commonty // #nosec G703 // already validated slashProportionDecimal, _ := sdk.NewDecFromStr(slashProportion) jailDuration := k.GetSubDowntimeJailDuration(ctx, chainID) - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(chainID) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(chainID) _, avsAddress := k.avsKeeper.IsAVSByChainID(ctx, chainIDWithoutRevision) // the slashing hook should trigger a validator set update for all affected AVSs. since the `chainID` is one of them // we should make sure we are well set up for that update. we will include an ack of the slash packet in the next diff --git a/x/avs/keeper/avs.go b/x/avs/keeper/avs.go index 7b0d3e370..01e22c5d4 100644 --- a/x/avs/keeper/avs.go +++ b/x/avs/keeper/avs.go @@ -7,7 +7,7 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ethereum/go-ethereum/common" "github.com/evmos/evmos/v14/x/evm/statedb" @@ -119,7 +119,7 @@ func (k Keeper) RegisterAVSWithChainID( // guard against errors ctx, writeFunc := oCtx.CacheContext() // remove the version number and validate - params.ChainID = exocoreutils.ChainIDWithoutRevision(params.ChainID) + params.ChainID = utils.ChainIDWithoutRevision(params.ChainID) if len(params.ChainID) == 0 { return common.Address{}, errorsmod.Wrap(types.ErrNotNull, "RegisterAVSWithChainID: chainID is null") } diff --git a/x/avs/keeper/keeper.go b/x/avs/keeper/keeper.go index ddc56c5bc..986c008d8 100644 --- a/x/avs/keeper/keeper.go +++ b/x/avs/keeper/keeper.go @@ -8,7 +8,7 @@ import ( errorsmod "cosmossdk.io/errors" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/cometbft/cometbft/libs/log" "github.com/cosmos/cosmos-sdk/codec" @@ -84,7 +84,7 @@ func (k Keeper) UpdateAVSInfo(ctx sdk.Context, params *types.AVSRegisterOrDeregi return errorsmod.Wrap(types.ErrAlreadyRegistered, fmt.Sprintf("the avsaddress is :%s", params.AvsAddress)) } startingEpoch := uint64(epoch.CurrentEpoch + 1) - if params.ChainID == exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) { + if params.ChainID == utils.ChainIDWithoutRevision(ctx.ChainID()) { // TODO: handle this better startingEpoch = uint64(epoch.CurrentEpoch) } diff --git a/x/avs/keeper/query.go b/x/avs/keeper/query.go index 8dbb97d41..bdd4105ad 100644 --- a/x/avs/keeper/query.go +++ b/x/avs/keeper/query.go @@ -3,7 +3,7 @@ package keeper import ( "context" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/avs/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -23,7 +23,7 @@ func (k Keeper) QueryAVSTaskInfo(ctx context.Context, req *types.QueryAVSTaskInf // QueryAVSAddrByChainID is an implementation of the QueryAVSAddrByChainID gRPC method func (k Keeper) QueryAVSAddrByChainID(ctx context.Context, req *types.QueryAVSAddrByChainIDReq) (*types.QueryAVSAddrByChainIDResponse, error) { c := sdk.UnwrapSDKContext(ctx) - isChainAvs, avsAddr := k.IsAVSByChainID(c, exocoreutils.ChainIDWithoutRevision(req.ChainID)) + isChainAvs, avsAddr := k.IsAVSByChainID(c, utils.ChainIDWithoutRevision(req.ChainID)) if !isChainAvs { return nil, types.ErrNotYetRegistered } diff --git a/x/dogfood/keeper/abci.go b/x/dogfood/keeper/abci.go index a967c9e62..dd5d59ab1 100644 --- a/x/dogfood/keeper/abci.go +++ b/x/dogfood/keeper/abci.go @@ -4,7 +4,6 @@ import ( "cosmossdk.io/math" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ExocoreNetwork/exocore/utils" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -20,7 +19,7 @@ func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } defer k.ClearEpochEnd(ctx) - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(ctx.ChainID()) // start by clearing the previous consensus keys for the chain. // each AVS can have a separate epoch and hence this function is a part of this module // and not the operator module. diff --git a/x/dogfood/keeper/impl_delegation_hooks.go b/x/dogfood/keeper/impl_delegation_hooks.go index f65561692..56aa76009 100644 --- a/x/dogfood/keeper/impl_delegation_hooks.go +++ b/x/dogfood/keeper/impl_delegation_hooks.go @@ -4,7 +4,7 @@ import ( "fmt" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -37,7 +37,7 @@ func (wrapper DelegationHooksWrapper) AfterDelegation( func (wrapper DelegationHooksWrapper) AfterUndelegationStarted( ctx sdk.Context, operator sdk.AccAddress, recordKey []byte, ) error { - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(ctx.ChainID()) var unbondingCompletionEpoch int64 if wrapper.keeper.operatorKeeper.IsOperatorRemovingKeyFromChainID( ctx, operator, chainIDWithoutRevision, diff --git a/x/dogfood/keeper/impl_epochs_hooks_test.go b/x/dogfood/keeper/impl_epochs_hooks_test.go index 0d79bab95..f12eb7e48 100644 --- a/x/dogfood/keeper/impl_epochs_hooks_test.go +++ b/x/dogfood/keeper/impl_epochs_hooks_test.go @@ -4,7 +4,7 @@ import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" @@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestSameEpochOperations() { // generate keys, and get the AVS address oldKey := utiltx.GenerateConsensusKey() newKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) // now define the operations @@ -252,7 +252,7 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() { // generate keys, and get the AVS address oldKey := utiltx.GenerateConsensusKey() newKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) // now define the operations diff --git a/x/dogfood/keeper/impl_operator_hooks.go b/x/dogfood/keeper/impl_operator_hooks.go index a66bfbb40..a52b9e8c7 100644 --- a/x/dogfood/keeper/impl_operator_hooks.go +++ b/x/dogfood/keeper/impl_operator_hooks.go @@ -2,7 +2,7 @@ package keeper import ( exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -48,7 +48,7 @@ func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( // 3. X epochs later, the reverse lookup of old cons addr + chain id -> operator addr // should be cleared. consAddr := oldKey.ToConsAddr() - if chainID == exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) { + if chainID == utils.ChainIDWithoutRevision(ctx.ChainID()) { // is the oldKey already active? if not, we should not do anything. // this can happen if we opt in with a key, then replace it with another key // during the same epoch. @@ -80,7 +80,7 @@ func (h OperatorHooksWrapper) AfterOperatorKeyRemovalInitiated( // keys from the chain. // 2. X epochs later, the removal is marked complete in the operator module. consAddr := key.ToConsAddr() - if chainID == exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) { + if chainID == utils.ChainIDWithoutRevision(ctx.ChainID()) { _, found := h.keeper.GetExocoreValidator(ctx, consAddr) if found { h.keeper.SetOptOutInformation(ctx, operator) diff --git a/x/dogfood/keeper/impl_sdk.go b/x/dogfood/keeper/impl_sdk.go index bef635014..c57af5c9e 100644 --- a/x/dogfood/keeper/impl_sdk.go +++ b/x/dogfood/keeper/impl_sdk.go @@ -4,7 +4,7 @@ import ( "sort" "cosmossdk.io/math" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" @@ -74,7 +74,7 @@ func (k Keeper) ValidatorByConsAddr( // a call to Validator(ctx, addr) in the slashing module, which is implemented in this file. // after that call, the ConsPubKey is fetched, which is also set by the below call. val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, addr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), + ctx, addr, utils.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { return nil @@ -104,7 +104,7 @@ func (k Keeper) SlashWithInfractionReason( slashFactor sdk.Dec, infraction stakingtypes.Infraction, ) math.Int { found, accAddress := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( - ctx, exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), addr, + ctx, utils.ChainIDWithoutRevision(ctx.ChainID()), addr, ) if !found { // TODO(mm): already slashed and removed from the set? @@ -122,7 +122,7 @@ func (k Keeper) SlashWithInfractionReason( // It delegates the call to the operator module. Alternatively, this may be handled // by the slashing module depending upon the design decisions. func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) { - k.operatorKeeper.Jail(ctx, addr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID())) + k.operatorKeeper.Jail(ctx, addr, utils.ChainIDWithoutRevision(ctx.ChainID())) // TODO(mm) // once the operator module jails someone, a hook should be triggered // and the validator removed from the set. same for unjailing. @@ -133,7 +133,7 @@ func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) { // operator to do so. TODO(mm): We need to use the SDK's slashing module to allow for downtime // slashing but somehow we need to prevent its Unjail function from being called by anyone. func (k Keeper) Unjail(ctx sdk.Context, addr sdk.ConsAddress) { - k.operatorKeeper.Unjail(ctx, addr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID())) + k.operatorKeeper.Unjail(ctx, addr, utils.ChainIDWithoutRevision(ctx.ChainID())) } // Delegation is an implementation of the staking interface expected by the SDK's slashing @@ -179,7 +179,7 @@ func (k Keeper) GetAllValidators(sdk.Context) (validators []stakingtypes.Validat // slashing module. It is called by the slashing module to record validator signatures // for downtime tracking. We delegate the call to the operator keeper. func (k Keeper) IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool { - return k.operatorKeeper.IsOperatorJailedForChainID(ctx, addr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID())) + return k.operatorKeeper.IsOperatorJailedForChainID(ctx, addr, utils.ChainIDWithoutRevision(ctx.ChainID())) } // ApplyAndReturnValidatorSetUpdates is an implementation of the staking interface expected @@ -209,7 +209,7 @@ func (k Keeper) IterateBondedValidatorsByPower( continue } val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, sdk.GetConsAddress(pk), exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), + ctx, sdk.GetConsAddress(pk), utils.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { ctx.Logger().Error("Operator address not found; skipping", "consAddress", sdk.GetConsAddress(pk), "i", i) diff --git a/x/dogfood/keeper/msg_server.go b/x/dogfood/keeper/msg_server.go index 5fb026381..35db11763 100644 --- a/x/dogfood/keeper/msg_server.go +++ b/x/dogfood/keeper/msg_server.go @@ -5,7 +5,7 @@ import ( "strings" "cosmossdk.io/errors" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" avskeeper "github.com/ExocoreNetwork/exocore/x/avs/keeper" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" @@ -112,7 +112,7 @@ func (k Keeper) UpdateParams( // update the related info in the AVS module isAVS, avsAddr := k.avsKeeper.IsAVSByChainID( - c, exocoreutils.ChainIDWithoutRevision(c.ChainID()), + c, utils.ChainIDWithoutRevision(c.ChainID()), ) if !isAVS { return nil, errors.Wrapf( diff --git a/x/dogfood/keeper/opt_out_test.go b/x/dogfood/keeper/opt_out_test.go index 1a08944c6..6733809e2 100644 --- a/x/dogfood/keeper/opt_out_test.go +++ b/x/dogfood/keeper/opt_out_test.go @@ -5,7 +5,7 @@ import ( utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" @@ -30,7 +30,7 @@ func (suite *KeeperTestSuite) TestBasicOperations() { suite.CheckLengthOfValidatorUpdates(0, nil, "register operator but don't opt in") // opt-in with a key - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) key := utiltx.GenerateConsensusKey() _, err = suite.OperatorMsgServer.OptIntoAVS(sdk.WrapSDKContext(suite.Ctx), &operatortypes.OptIntoAVSReq{ diff --git a/x/dogfood/keeper/unbonding_test.go b/x/dogfood/keeper/unbonding_test.go index a6f473acc..2350c3148 100644 --- a/x/dogfood/keeper/unbonding_test.go +++ b/x/dogfood/keeper/unbonding_test.go @@ -3,7 +3,7 @@ package keeper_test import ( sdkmath "cosmossdk.io/math" utiltx "github.com/ExocoreNetwork/exocore/testutil/tx" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" assetskeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper" assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" @@ -67,7 +67,7 @@ func (suite *KeeperTestSuite) TestUndelegations() { suite.NoError(err) // opt in oldKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) _, err = suite.OperatorMsgServer.OptIntoAVS( sdk.WrapSDKContext(suite.Ctx), @@ -228,7 +228,7 @@ func (suite *KeeperTestSuite) TestUndelegationEdgeCases() { suite.CheckLengthOfValidatorUpdates(0, []int64{}, "undelegate without opt in") // opt in oldKey := utiltx.GenerateConsensusKey() - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(suite.Ctx.ChainID()) _, avsAddress := suite.App.AVSManagerKeeper.IsAVSByChainID(suite.Ctx, chainIDWithoutRevision) _, err = suite.OperatorMsgServer.OptIntoAVS( sdk.WrapSDKContext(suite.Ctx), diff --git a/x/dogfood/keeper/validators.go b/x/dogfood/keeper/validators.go index 89be9d8a7..5602c89a5 100644 --- a/x/dogfood/keeper/validators.go +++ b/x/dogfood/keeper/validators.go @@ -6,7 +6,7 @@ import ( "cosmossdk.io/math" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/dogfood/types" abci "github.com/cometbft/cometbft/abci/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -70,7 +70,7 @@ func (k Keeper) ApplyValidatorChanges( // via stakingkeeeper.Validator(ctx, valAddr) // then it fetches the cons pub key from said validator to generate the lookup found, accAddress := k.operatorKeeper.GetOperatorAddressForChainIDAndConsAddr( - ctx, exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), addr, + ctx, utils.ChainIDWithoutRevision(ctx.ChainID()), addr, ) if !found { // should never happen @@ -341,13 +341,13 @@ func (k Keeper) GetValidator( ) (stakingtypes.Validator, bool) { accAddr := sdk.AccAddress(valAddr) found, wrappedKey, err := k.operatorKeeper.GetOperatorConsKeyForChainID( - ctx, accAddr, exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), + ctx, accAddr, utils.ChainIDWithoutRevision(ctx.ChainID()), ) if !found || err != nil || wrappedKey == nil { return stakingtypes.Validator{}, false } val, found := k.operatorKeeper.ValidatorByConsAddrForChainID( - ctx, wrappedKey.ToConsAddr(), exocoreutils.ChainIDWithoutRevision(ctx.ChainID()), + ctx, wrappedKey.ToConsAddr(), utils.ChainIDWithoutRevision(ctx.ChainID()), ) if !found { return stakingtypes.Validator{}, false diff --git a/x/operator/keeper/grpc_query.go b/x/operator/keeper/grpc_query.go index 8e3d8455b..a150125c5 100644 --- a/x/operator/keeper/grpc_query.go +++ b/x/operator/keeper/grpc_query.go @@ -8,7 +8,6 @@ import ( exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" "github.com/ExocoreNetwork/exocore/utils" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/operator/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/store/prefix" @@ -57,7 +56,7 @@ func (k *Keeper) QueryOperatorConsKeyForChainID( if err != nil { return nil, err } - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(req.Chain) found, key, err := k.GetOperatorConsKeyForChainID( ctx, addr, chainIDWithoutRevision, ) @@ -84,7 +83,7 @@ func (k Keeper) QueryOperatorConsAddressForChainID( if err != nil { return nil, err } - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(req.Chain) found, wrappedKey, err := k.GetOperatorConsKeyForChainID( ctx, addr, chainIDWithoutRevision, ) @@ -108,7 +107,7 @@ func (k Keeper) QueryAllOperatorConsKeysByChainID( ) (*types.QueryAllOperatorConsKeysByChainIDResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) res := make([]*types.OperatorConsKeyPair, 0) - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(req.Chain) chainPrefix := types.ChainIDAndAddrKey( types.BytePrefixForChainIDAndOperatorToConsKey, chainIDWithoutRevision, nil, @@ -145,7 +144,7 @@ func (k Keeper) QueryAllOperatorConsAddrsByChainID( ) (*types.QueryAllOperatorConsAddrsByChainIDResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) res := make([]*types.OperatorConsAddrPair, 0) - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(req.Chain) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(req.Chain) chainPrefix := types.ChainIDAndAddrKey( types.BytePrefixForChainIDAndOperatorToConsKey, chainIDWithoutRevision, nil, diff --git a/x/operator/keeper/slash.go b/x/operator/keeper/slash.go index 24d576caf..2bfdaa9aa 100644 --- a/x/operator/keeper/slash.go +++ b/x/operator/keeper/slash.go @@ -9,7 +9,7 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types" "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -178,7 +178,7 @@ func (k Keeper) SlashWithInfractionReason( ctx sdk.Context, addr sdk.AccAddress, infractionHeight, power int64, slashFactor sdk.Dec, infraction stakingtypes.Infraction, ) sdkmath.Int { - chainID := exocoreutils.ChainIDWithoutRevision(ctx.ChainID()) + chainID := utils.ChainIDWithoutRevision(ctx.ChainID()) isAvs, avsAddr := k.avsKeeper.IsAVSByChainID(ctx, chainID) if !isAvs { k.Logger(ctx).Error("the chainID is not supported by AVS", chainID) diff --git a/x/operator/keeper/slash_test.go b/x/operator/keeper/slash_test.go index b335b8002..c7ba285f8 100644 --- a/x/operator/keeper/slash_test.go +++ b/x/operator/keeper/slash_test.go @@ -4,7 +4,7 @@ import ( "time" sdkmath "cosmossdk.io/math" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/operator/keeper" "github.com/ExocoreNetwork/exocore/x/operator/types" @@ -24,7 +24,7 @@ func (suite *OperatorTestSuite) TestSlashWithInfractionReason() { suite.prepareDelegation(true, suite.assetAddr, delegationAmount) // opt into the AVS - avsAddr := avstypes.GenerateAVSAddr(exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID())).String() + avsAddr := avstypes.GenerateAVSAddr(utils.ChainIDWithoutRevision(suite.Ctx.ChainID())).String() err := suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, avsAddr) suite.NoError(err) // call the EndBlock to update the voting power diff --git a/x/operator/keeper/usd_value_test.go b/x/operator/keeper/usd_value_test.go index d0ef2e80e..54c1a7af6 100644 --- a/x/operator/keeper/usd_value_test.go +++ b/x/operator/keeper/usd_value_test.go @@ -4,7 +4,7 @@ import ( "time" sdkmath "cosmossdk.io/math" - exocoreutils "github.com/ExocoreNetwork/exocore/utils" + "github.com/ExocoreNetwork/exocore/utils" assetstype "github.com/ExocoreNetwork/exocore/x/assets/types" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" operatorKeeper "github.com/ExocoreNetwork/exocore/x/operator/keeper" @@ -115,7 +115,7 @@ func (suite *OperatorTestSuite) TestVotingPowerForDogFood() { addPower := 1 addUSDValue := sdkmath.LegacyNewDec(1) - chainIDWithoutRevision := exocoreutils.ChainIDWithoutRevision(suite.Ctx.ChainID()) + chainIDWithoutRevision := utils.ChainIDWithoutRevision(suite.Ctx.ChainID()) avsAddress := avstypes.GenerateAVSAddr(chainIDWithoutRevision).String() // CommitAfter causes the epoch hook to be triggered, and results in writing // of the AVS usd value to the store. From 5438d850202540ec24462fde83e7fa910f0ca824 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 9 Sep 2024 12:13:55 +0000 Subject: [PATCH 43/52] chore: proto lint --- proto/exocore/appchain/common/v1/wire.proto | 12 +-- x/appchain/common/types/wire.pb.go | 112 ++++++++++---------- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/proto/exocore/appchain/common/v1/wire.proto b/proto/exocore/appchain/common/v1/wire.proto index a496ce12a..1bcebaad3 100644 --- a/proto/exocore/appchain/common/v1/wire.proto +++ b/proto/exocore/appchain/common/v1/wire.proto @@ -46,15 +46,15 @@ message VscMaturedPacketData { // SubscriberPacketData is the enum to identify the type of packet sent. enum SubscriberPacketDataType { option (gogoproto.goproto_enum_prefix) = false; - // SUBSCRIBER_PACKET_TYPE_UNSPECIFIED is the default value - SUBSCRIBER_PACKET_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "UnspecifiedPacket" ]; - // SUBSCRIBER_PACKET_TYPE_SLASH is the type of packet sent when a subscriber + // SUBSCRIBER_PACKET_DATA_TYPE_UNSPECIFIED is the default value + SUBSCRIBER_PACKET_DATA_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "UnspecifiedPacket" ]; + // SUBSCRIBER_PACKET_DATA_TYPE_SLASH is the type of packet sent when a subscriber // chain wants to request the slashing of a validator on the coordinator chain. - SUBSCRIBER_PACKET_TYPE_SLASH = 1 [ (gogoproto.enumvalue_customname) = "SlashPacket" ]; - // SUBSCRIBER_PACKET_TYPE_VSC_MATURED is the type of packet sent when a subscriber + SUBSCRIBER_PACKET_DATA_TYPE_SLASH = 1 [ (gogoproto.enumvalue_customname) = "SlashPacket" ]; + // SUBSCRIBER_PACKET_DATA_TYPE_VSC_MATURED is the type of packet sent when a subscriber // chain wants to indicate that a VSC has matured and unbondings associated with // that VSC can now be released. - SUBSCRIBER_PACKET_TYPE_VSC_MATURED = 2 [ (gogoproto.enumvalue_customname) = "VscMaturedPacket" ];; + SUBSCRIBER_PACKET_DATA_TYPE_VSC_MATURED = 2 [ (gogoproto.enumvalue_customname) = "VscMaturedPacket" ]; } // SubscriberPacketData is a wrapped message that contains the type of packet diff --git a/x/appchain/common/types/wire.pb.go b/x/appchain/common/types/wire.pb.go index da45be2ee..45cc6ad83 100644 --- a/x/appchain/common/types/wire.pb.go +++ b/x/appchain/common/types/wire.pb.go @@ -29,27 +29,27 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type SubscriberPacketDataType int32 const ( - // SUBSCRIBER_PACKET_TYPE_UNSPECIFIED is the default value + // SUBSCRIBER_PACKET_DATA_TYPE_UNSPECIFIED is the default value UnspecifiedPacket SubscriberPacketDataType = 0 - // SUBSCRIBER_PACKET_TYPE_SLASH is the type of packet sent when a subscriber + // SUBSCRIBER_PACKET_DATA_TYPE_SLASH is the type of packet sent when a subscriber // chain wants to request the slashing of a validator on the coordinator chain. SlashPacket SubscriberPacketDataType = 1 - // SUBSCRIBER_PACKET_TYPE_VSC_MATURED is the type of packet sent when a subscriber + // SUBSCRIBER_PACKET_DATA_TYPE_VSC_MATURED is the type of packet sent when a subscriber // chain wants to indicate that a VSC has matured and unbondings associated with // that VSC can now be released. VscMaturedPacket SubscriberPacketDataType = 2 ) var SubscriberPacketDataType_name = map[int32]string{ - 0: "SUBSCRIBER_PACKET_TYPE_UNSPECIFIED", - 1: "SUBSCRIBER_PACKET_TYPE_SLASH", - 2: "SUBSCRIBER_PACKET_TYPE_VSC_MATURED", + 0: "SUBSCRIBER_PACKET_DATA_TYPE_UNSPECIFIED", + 1: "SUBSCRIBER_PACKET_DATA_TYPE_SLASH", + 2: "SUBSCRIBER_PACKET_DATA_TYPE_VSC_MATURED", } var SubscriberPacketDataType_value = map[string]int32{ - "SUBSCRIBER_PACKET_TYPE_UNSPECIFIED": 0, - "SUBSCRIBER_PACKET_TYPE_SLASH": 1, - "SUBSCRIBER_PACKET_TYPE_VSC_MATURED": 2, + "SUBSCRIBER_PACKET_DATA_TYPE_UNSPECIFIED": 0, + "SUBSCRIBER_PACKET_DATA_TYPE_SLASH": 1, + "SUBSCRIBER_PACKET_DATA_TYPE_VSC_MATURED": 2, } func (x SubscriberPacketDataType) String() string { @@ -408,53 +408,53 @@ func init() { } var fileDescriptor_646142158918d547 = []byte{ - // 730 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x41, 0x6f, 0xda, 0x48, - 0x14, 0xb6, 0x03, 0xca, 0x8a, 0x41, 0x22, 0x60, 0xb1, 0xbb, 0x5e, 0x6f, 0x96, 0x58, 0xd6, 0xae, - 0x84, 0x76, 0x25, 0x7b, 0xa1, 0xbd, 0xa4, 0x4a, 0x0f, 0x18, 0x88, 0x40, 0x6d, 0x22, 0x64, 0x03, - 0x52, 0x7a, 0xb1, 0x06, 0x7b, 0x02, 0x23, 0xc0, 0x63, 0x79, 0x06, 0x27, 0xf9, 0x07, 0x55, 0x4e, - 0xfd, 0x03, 0x39, 0xf5, 0xde, 0xdf, 0x91, 0x63, 0x8e, 0x3d, 0x45, 0x15, 0x39, 0xf4, 0xd2, 0x53, - 0x7f, 0x41, 0x65, 0x1b, 0x13, 0x92, 0x42, 0x54, 0xa9, 0xb7, 0x99, 0x79, 0xef, 0x7d, 0xef, 0xcd, - 0xf7, 0x7d, 0x7a, 0xe0, 0x1f, 0x74, 0x4e, 0x6c, 0xe2, 0x23, 0x0d, 0x7a, 0x9e, 0x3d, 0x82, 0xd8, - 0xd5, 0x6c, 0x32, 0x9d, 0x12, 0x57, 0x0b, 0x2a, 0xda, 0x19, 0xf6, 0x91, 0xea, 0xf9, 0x84, 0x11, - 0x41, 0x5a, 0xa4, 0xa9, 0x49, 0x9a, 0x1a, 0xa7, 0xa9, 0x41, 0x45, 0xfa, 0xdb, 0x26, 0x74, 0x4a, - 0xa8, 0x46, 0x19, 0x1c, 0x63, 0x77, 0xa8, 0x05, 0x95, 0x01, 0x62, 0xb0, 0x92, 0xdc, 0x63, 0x04, - 0xa9, 0x38, 0x24, 0x43, 0x12, 0x1d, 0xb5, 0xf0, 0xb4, 0x78, 0xfd, 0x93, 0x21, 0xd7, 0x41, 0xfe, - 0x14, 0xbb, 0x4c, 0x83, 0x03, 0x1b, 0x6b, 0xec, 0xc2, 0x43, 0x34, 0x0e, 0x2a, 0x23, 0x50, 0x68, - 0x41, 0xd7, 0xa1, 0x23, 0x38, 0x46, 0x47, 0x88, 0x41, 0x07, 0x32, 0x28, 0xec, 0x83, 0x3f, 0x6c, - 0x42, 0x7c, 0x07, 0xbb, 0x90, 0x11, 0xdf, 0x3a, 0x45, 0xc8, 0xf2, 0x08, 0x99, 0x58, 0xd0, 0x71, - 0x7c, 0x91, 0x97, 0xf9, 0x72, 0xc6, 0xf8, 0x6d, 0x25, 0xe1, 0x10, 0xa1, 0x0e, 0x21, 0x93, 0x9a, - 0xe3, 0xf8, 0x82, 0x08, 0x7e, 0x09, 0x90, 0x4f, 0x31, 0x71, 0xc5, 0xad, 0x28, 0x31, 0xb9, 0x2a, - 0x9f, 0x79, 0xb0, 0x63, 0x4e, 0x20, 0x1d, 0x75, 0xa0, 0x3d, 0x46, 0xac, 0x11, 0x36, 0x32, 0x40, - 0x26, 0x80, 0x13, 0xec, 0x84, 0x28, 0x11, 0x70, 0xb6, 0x2a, 0xa9, 0xf7, 0xe3, 0xaa, 0xe1, 0xb8, - 0x6a, 0x3f, 0xc9, 0xd0, 0xc5, 0xeb, 0xdb, 0x3d, 0xee, 0xeb, 0xed, 0x5e, 0xfe, 0x02, 0x4e, 0x27, - 0x2f, 0x94, 0x65, 0xa9, 0x62, 0xdc, 0xc3, 0x08, 0x07, 0x20, 0x1f, 0xc0, 0x09, 0x45, 0xcc, 0x9a, - 0x79, 0x0e, 0x64, 0xc8, 0xc2, 0x4e, 0x34, 0x4a, 0x5a, 0x17, 0xe6, 0xb7, 0x7b, 0xb9, 0x7e, 0x14, - 0xeb, 0x45, 0xa1, 0x76, 0xc3, 0xc8, 0x05, 0xab, 0x77, 0x47, 0xd0, 0x01, 0xc0, 0xee, 0xa9, 0x0f, - 0x6d, 0x16, 0x7e, 0x21, 0x25, 0xf3, 0xe5, 0x5c, 0x55, 0x51, 0x63, 0xf6, 0xd5, 0x84, 0xed, 0x05, - 0xfb, 0x6a, 0x7b, 0x99, 0x69, 0xac, 0x54, 0x29, 0x5d, 0x50, 0xec, 0x53, 0xfb, 0x08, 0xb2, 0x99, - 0x8f, 0x9c, 0x95, 0xdf, 0xae, 0x9b, 0x8c, 0xff, 0xd1, 0xc9, 0x94, 0x0f, 0x5b, 0xa0, 0x68, 0xce, - 0x06, 0xd4, 0xf6, 0xf1, 0x00, 0xf9, 0x2b, 0xb0, 0x2d, 0x90, 0x0e, 0x15, 0x8d, 0xa0, 0x72, 0xd5, - 0xe7, 0xea, 0x66, 0x1b, 0xa9, 0xeb, 0xea, 0xbb, 0x17, 0x1e, 0x32, 0x22, 0x04, 0xe1, 0x04, 0x14, - 0x68, 0xa8, 0x90, 0xe5, 0x45, 0x51, 0x2b, 0x34, 0x43, 0xc4, 0x5d, 0xb6, 0xfa, 0xdf, 0x93, 0xb0, - 0x0f, 0x65, 0x6d, 0x71, 0xc6, 0x0e, 0x7d, 0xa4, 0x34, 0x06, 0xbf, 0x07, 0xd4, 0xb6, 0xa6, 0x31, - 0x29, 0x0f, 0x1a, 0xa4, 0xa2, 0x06, 0xff, 0x3f, 0xd5, 0x60, 0x1d, 0x9d, 0x2d, 0xce, 0x28, 0x06, - 0x6b, 0xde, 0xf5, 0x6d, 0x90, 0x0e, 0x71, 0x95, 0x2f, 0x3c, 0xd8, 0x5d, 0x7a, 0xc7, 0x44, 0xac, - 0x3e, 0x82, 0xee, 0x10, 0xad, 0xcc, 0x44, 0x40, 0x61, 0x69, 0x9b, 0x85, 0x24, 0x54, 0xe4, 0xe5, - 0x54, 0x39, 0x5b, 0x95, 0x37, 0xbb, 0x30, 0x16, 0x44, 0x97, 0x17, 0x5e, 0x14, 0x1f, 0x79, 0x31, - 0x01, 0x52, 0x8c, 0x7c, 0xf0, 0xb0, 0x84, 0xfe, 0xa4, 0x35, 0xff, 0x02, 0x20, 0x56, 0x07, 0xda, - 0x63, 0x2a, 0xa6, 0xe4, 0x54, 0x39, 0x63, 0x64, 0xa2, 0x97, 0x9a, 0x3d, 0xa6, 0xff, 0xde, 0xf0, - 0x40, 0xdc, 0xa4, 0xaf, 0xf0, 0x12, 0x28, 0x66, 0x4f, 0x37, 0xeb, 0x46, 0x5b, 0x6f, 0x1a, 0x56, - 0xa7, 0x56, 0x7f, 0xd5, 0xec, 0x5a, 0xdd, 0x93, 0x4e, 0xd3, 0xea, 0x1d, 0x9b, 0x9d, 0x66, 0xbd, - 0x7d, 0xd8, 0x6e, 0x36, 0xf2, 0x9c, 0xf4, 0xeb, 0xe5, 0x95, 0x5c, 0xe8, 0xb9, 0xd4, 0x43, 0x36, - 0x3e, 0xc5, 0x09, 0xad, 0x42, 0x05, 0xec, 0x6e, 0x28, 0x37, 0x5f, 0xd7, 0xcc, 0x56, 0x9e, 0x97, - 0x76, 0x2e, 0xaf, 0xe4, 0xec, 0x8a, 0x0f, 0x84, 0x83, 0x8d, 0x1d, 0xfb, 0x66, 0xdd, 0x3a, 0xaa, - 0x75, 0x7b, 0x46, 0xb3, 0x91, 0xdf, 0x92, 0x8a, 0x97, 0x57, 0x72, 0xfe, 0xb1, 0xbe, 0x52, 0xfa, - 0xed, 0xfb, 0x12, 0xa7, 0x9b, 0xd7, 0xf3, 0x12, 0x7f, 0x33, 0x2f, 0xf1, 0x9f, 0xe6, 0x25, 0xfe, - 0xdd, 0x5d, 0x89, 0xbb, 0xb9, 0x2b, 0x71, 0x1f, 0xef, 0x4a, 0xdc, 0x9b, 0xfd, 0x21, 0x66, 0xa3, - 0xd9, 0x20, 0xb4, 0x88, 0xd6, 0x8c, 0x7d, 0x73, 0x8c, 0xd8, 0x19, 0xf1, 0xc7, 0x5a, 0xb2, 0x6c, - 0xcf, 0xbf, 0x5b, 0xb7, 0xd1, 0xde, 0x1b, 0x6c, 0x47, 0x8b, 0xef, 0xd9, 0xb7, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x5b, 0xc8, 0x9b, 0x3f, 0x96, 0x05, 0x00, 0x00, + // 734 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xc1, 0x6e, 0xda, 0x4a, + 0x14, 0xb5, 0x03, 0xca, 0x13, 0x83, 0x44, 0xc0, 0xe2, 0xbd, 0xe7, 0xe7, 0xd7, 0x12, 0xd7, 0x6a, + 0x55, 0xd4, 0x4a, 0x76, 0xa1, 0x55, 0xa5, 0x54, 0xdd, 0xd8, 0x40, 0x04, 0x6a, 0x13, 0x21, 0x1b, + 0x90, 0xd2, 0x8d, 0x35, 0xd8, 0x13, 0xb0, 0x00, 0x8f, 0xe5, 0x19, 0x9c, 0xe4, 0x0f, 0xaa, 0xac, + 0xfa, 0x03, 0x59, 0x75, 0xdf, 0xef, 0xc8, 0x32, 0xcb, 0xae, 0xd2, 0x8a, 0x2c, 0xba, 0xe9, 0xaa, + 0x5f, 0x50, 0xd9, 0xc6, 0x84, 0xa4, 0x04, 0x55, 0xea, 0x6e, 0x66, 0xee, 0xbd, 0xe7, 0xde, 0x39, + 0xe7, 0xe8, 0x82, 0x47, 0xe8, 0x18, 0x5b, 0xd8, 0x47, 0x0a, 0xf4, 0x3c, 0x6b, 0x08, 0x1d, 0x57, + 0xb1, 0xf0, 0x64, 0x82, 0x5d, 0x25, 0xa8, 0x28, 0x47, 0x8e, 0x8f, 0x64, 0xcf, 0xc7, 0x14, 0x73, + 0xc2, 0x3c, 0x4d, 0x4e, 0xd2, 0xe4, 0x38, 0x4d, 0x0e, 0x2a, 0xc2, 0x43, 0x0b, 0x93, 0x09, 0x26, + 0x0a, 0xa1, 0x70, 0xe4, 0xb8, 0x03, 0x25, 0xa8, 0xf4, 0x11, 0x85, 0x95, 0xe4, 0x1e, 0x23, 0x08, + 0xc5, 0x01, 0x1e, 0xe0, 0xe8, 0xa8, 0x84, 0xa7, 0xf9, 0xeb, 0xff, 0x14, 0xb9, 0x36, 0xf2, 0x27, + 0x8e, 0x4b, 0x15, 0xd8, 0xb7, 0x1c, 0x85, 0x9e, 0x78, 0x88, 0xc4, 0x41, 0x69, 0x08, 0x0a, 0x4d, + 0xe8, 0xda, 0x64, 0x08, 0x47, 0x68, 0x0f, 0x51, 0x68, 0x43, 0x0a, 0xb9, 0x1d, 0xf0, 0x9f, 0x85, + 0xb1, 0x6f, 0x3b, 0x2e, 0xa4, 0xd8, 0x37, 0x0f, 0x11, 0x32, 0x3d, 0x8c, 0xc7, 0x26, 0xb4, 0x6d, + 0x9f, 0x67, 0x45, 0xb6, 0x9c, 0xd1, 0xff, 0x59, 0x4a, 0xd8, 0x45, 0xa8, 0x8d, 0xf1, 0x58, 0xb5, + 0x6d, 0x9f, 0xe3, 0xc1, 0x5f, 0x01, 0xf2, 0x89, 0x83, 0x5d, 0x7e, 0x23, 0x4a, 0x4c, 0xae, 0xd2, + 0x37, 0x16, 0x6c, 0x19, 0x63, 0x48, 0x86, 0x6d, 0x68, 0x8d, 0x10, 0xad, 0x87, 0x8d, 0x74, 0x90, + 0x09, 0xe0, 0xd8, 0xb1, 0x43, 0x94, 0x08, 0x38, 0x5b, 0x15, 0xe4, 0xeb, 0x71, 0xe5, 0x70, 0x5c, + 0xb9, 0x97, 0x64, 0x68, 0xfc, 0xf9, 0xe5, 0x36, 0xf3, 0xe3, 0x72, 0x3b, 0x7f, 0x02, 0x27, 0xe3, + 0x57, 0xd2, 0xa2, 0x54, 0xd2, 0xaf, 0x61, 0xb8, 0xd7, 0x20, 0x1f, 0xc0, 0x31, 0x41, 0xd4, 0x9c, + 0x7a, 0x36, 0xa4, 0xc8, 0x74, 0xec, 0x68, 0x94, 0xb4, 0xc6, 0xcd, 0x2e, 0xb7, 0x73, 0xbd, 0x28, + 0xd6, 0x8d, 0x42, 0xad, 0xba, 0x9e, 0x0b, 0x96, 0xef, 0x36, 0xa7, 0x01, 0xe0, 0xb8, 0x87, 0x3e, + 0xb4, 0x68, 0xf8, 0x85, 0x94, 0xc8, 0x96, 0x73, 0x55, 0x49, 0x8e, 0xd9, 0x97, 0x13, 0xb6, 0xe7, + 0xec, 0xcb, 0xad, 0x45, 0xa6, 0xbe, 0x54, 0x25, 0x75, 0x40, 0xb1, 0x47, 0xac, 0x3d, 0x48, 0xa7, + 0x3e, 0xb2, 0x97, 0x7e, 0xbb, 0x6a, 0x32, 0xf6, 0x77, 0x27, 0x93, 0x3e, 0x6d, 0x80, 0xa2, 0x31, + 0xed, 0x13, 0xcb, 0x77, 0xfa, 0xc8, 0x5f, 0x82, 0x6d, 0x82, 0x74, 0xa8, 0x68, 0x04, 0x95, 0xab, + 0xbe, 0x90, 0xef, 0xb6, 0x91, 0xbc, 0xaa, 0xbe, 0x73, 0xe2, 0x21, 0x3d, 0x42, 0xe0, 0x0e, 0x40, + 0x81, 0x84, 0x0a, 0x99, 0x5e, 0x14, 0x35, 0x43, 0x33, 0x44, 0xdc, 0x65, 0xab, 0x4f, 0xd7, 0xc2, + 0xde, 0x94, 0xb5, 0xc9, 0xe8, 0x5b, 0xe4, 0x96, 0xd2, 0x0e, 0xf8, 0x37, 0x20, 0x96, 0x39, 0x89, + 0x49, 0xb9, 0xd1, 0x20, 0x15, 0x35, 0x78, 0xb6, 0xae, 0xc1, 0x2a, 0x3a, 0x9b, 0x8c, 0x5e, 0x0c, + 0x56, 0xbc, 0x6b, 0x9b, 0x20, 0x1d, 0xe2, 0x4a, 0xdf, 0x59, 0x70, 0x6f, 0xe1, 0x1d, 0x03, 0xd1, + 0xda, 0x10, 0xba, 0x03, 0xb4, 0x34, 0x13, 0x06, 0x85, 0x85, 0x6d, 0xe6, 0x92, 0x10, 0x9e, 0x15, + 0x53, 0xe5, 0x6c, 0x55, 0xbc, 0xdb, 0x85, 0xb1, 0x20, 0x9a, 0x38, 0xf7, 0x22, 0x7f, 0xcb, 0x8b, + 0x09, 0x90, 0xa4, 0xe7, 0x83, 0x9b, 0x25, 0xe4, 0x0f, 0xad, 0x79, 0x1f, 0x80, 0x58, 0x1d, 0x68, + 0x8d, 0x08, 0x9f, 0x12, 0x53, 0xe5, 0x8c, 0x9e, 0x89, 0x5e, 0x54, 0x6b, 0x44, 0x9e, 0x7c, 0x61, + 0x01, 0x7f, 0x97, 0xbe, 0x9c, 0x06, 0x1e, 0x1b, 0x5d, 0xcd, 0xa8, 0xe9, 0x2d, 0xad, 0xa1, 0x9b, + 0x6d, 0xb5, 0xf6, 0xa6, 0xd1, 0x31, 0xeb, 0x6a, 0x47, 0x35, 0x3b, 0x07, 0xed, 0x86, 0xd9, 0xdd, + 0x37, 0xda, 0x8d, 0x5a, 0x6b, 0xb7, 0xd5, 0xa8, 0xe7, 0x19, 0xe1, 0xef, 0xd3, 0x33, 0xb1, 0xd0, + 0x75, 0x89, 0x87, 0x2c, 0xe7, 0xd0, 0x49, 0xb8, 0xe5, 0x5e, 0x82, 0x07, 0xeb, 0x30, 0x8c, 0xb7, + 0xaa, 0xd1, 0xcc, 0xb3, 0xc2, 0xd6, 0xe9, 0x99, 0x98, 0x5d, 0x72, 0x04, 0xa7, 0xae, 0xef, 0xdd, + 0x33, 0x6a, 0xe6, 0x9e, 0xda, 0xe9, 0xea, 0x8d, 0x7a, 0x7e, 0x43, 0x28, 0x9e, 0x9e, 0x89, 0xf9, + 0xdb, 0x72, 0x0b, 0xe9, 0xf7, 0x1f, 0x4b, 0x8c, 0x66, 0x9c, 0xcf, 0x4a, 0xec, 0xc5, 0xac, 0xc4, + 0x7e, 0x9d, 0x95, 0xd8, 0x0f, 0x57, 0x25, 0xe6, 0xe2, 0xaa, 0xc4, 0x7c, 0xbe, 0x2a, 0x31, 0xef, + 0x76, 0x06, 0x0e, 0x1d, 0x4e, 0xfb, 0xa1, 0x63, 0x94, 0x46, 0x6c, 0xa3, 0x7d, 0x44, 0x8f, 0xb0, + 0x3f, 0x52, 0x92, 0xdd, 0x7b, 0xfc, 0xcb, 0xf6, 0x8d, 0xd6, 0x60, 0x7f, 0x33, 0xda, 0x83, 0xcf, + 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0xd3, 0x7d, 0xb8, 0xe9, 0xa5, 0x05, 0x00, 0x00, } func (m *HandshakeMetadata) Marshal() (dAtA []byte, err error) { From 617d77469bde782aed8cf950e507196adff8467b Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 10 Sep 2024 18:24:01 +0000 Subject: [PATCH 44/52] feat(appchains): part 4 PR - handles slashing, rewards, validator set, maturity, unbonding and opt out --- proto/exocore/appchain/common/v1/common.proto | 19 + proto/exocore/appchain/common/v1/wire.proto | 2 +- .../appchain/coordinator/v1/coordinator.proto | 14 + .../appchain/subscriber/v1/subscriber.proto | 26 -- utils/utils.go | 21 + x/appchain/common/types/common.pb.go | 390 +++++++++++++--- x/appchain/common/types/events.go | 11 +- x/appchain/common/types/expected_keepers.go | 20 + x/appchain/common/types/types.go | 22 + x/appchain/common/types/utils.go | 42 ++ .../{subscriber => common}/types/validator.go | 14 +- x/appchain/common/types/wire.go | 38 +- x/appchain/common/types/wire.pb.go | 112 ++--- x/appchain/coordinator/keeper/height.go | 23 + x/appchain/coordinator/keeper/ibc_client.go | 68 ++- x/appchain/coordinator/keeper/identifiers.go | 31 ++ .../keeper/impl_delegation_hooks.go | 87 ++++ .../coordinator/keeper/impl_epochs_hooks.go | 67 +-- .../coordinator/keeper/impl_operator_hooks.go | 73 +++ x/appchain/coordinator/keeper/keeper.go | 3 + x/appchain/coordinator/keeper/register.go | 2 +- x/appchain/coordinator/keeper/relay.go | 2 +- x/appchain/coordinator/keeper/slash.go | 17 +- x/appchain/coordinator/keeper/timeout.go | 87 ++++ x/appchain/coordinator/keeper/unbonding.go | 108 +++++ .../keeper/validator_set_update.go | 257 +++++++++++ x/appchain/coordinator/keeper/validators.go | 83 ++++ .../coordinator/types/coordinator.pb.go | 402 +++++++++++++++- .../coordinator/types/expected_keepers.go | 10 + x/appchain/coordinator/types/keys.go | 111 ++++- x/appchain/subscriber/keeper/genesis.go | 4 +- x/appchain/subscriber/keeper/grpc_query.go | 2 +- x/appchain/subscriber/keeper/impl_sdk.go | 162 +++++++ x/appchain/subscriber/keeper/keeper.go | 102 ++++- x/appchain/subscriber/keeper/params.go | 20 +- x/appchain/subscriber/keeper/queue.go | 91 ++++ x/appchain/subscriber/keeper/relay.go | 184 +++++++- x/appchain/subscriber/keeper/rewards.go | 202 ++++++++ x/appchain/subscriber/keeper/validators.go | 147 +++++- x/appchain/subscriber/module.go | 44 +- x/appchain/subscriber/module_ibc.go | 3 +- x/appchain/subscriber/types/events.go | 11 + x/appchain/subscriber/types/keys.go | 40 +- x/appchain/subscriber/types/subscriber.pb.go | 433 ------------------ x/appchain/subscriber/types/types.go | 10 + x/avs/keeper/avs.go | 19 +- x/dogfood/keeper/genesis.go | 7 +- x/operator/keeper/consensus_keys.go | 5 +- x/operator/keeper/operator.go | 14 + x/operator/keeper/opt.go | 4 +- x/operator/keeper/slash.go | 1 + x/operator/types/keys.go | 14 +- x/operator/types/utils.go | 20 - 53 files changed, 2925 insertions(+), 776 deletions(-) delete mode 100644 proto/exocore/appchain/subscriber/v1/subscriber.proto create mode 100644 x/appchain/common/types/utils.go rename x/appchain/{subscriber => common}/types/validator.go (69%) create mode 100644 x/appchain/coordinator/keeper/impl_delegation_hooks.go create mode 100644 x/appchain/coordinator/keeper/impl_operator_hooks.go create mode 100644 x/appchain/coordinator/keeper/unbonding.go create mode 100644 x/appchain/coordinator/keeper/validator_set_update.go create mode 100644 x/appchain/coordinator/keeper/validators.go create mode 100644 x/appchain/subscriber/keeper/impl_sdk.go create mode 100644 x/appchain/subscriber/keeper/queue.go create mode 100644 x/appchain/subscriber/keeper/rewards.go delete mode 100644 x/appchain/subscriber/types/subscriber.pb.go delete mode 100644 x/operator/types/utils.go diff --git a/proto/exocore/appchain/common/v1/common.proto b/proto/exocore/appchain/common/v1/common.proto index 41c5f59a3..34ea132c6 100644 --- a/proto/exocore/appchain/common/v1/common.proto +++ b/proto/exocore/appchain/common/v1/common.proto @@ -3,7 +3,9 @@ syntax = "proto3"; package exocore.appchain.common.v1; import "amino/amino.proto"; +import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; import "tendermint/abci/types.proto"; @@ -103,4 +105,21 @@ message CoordinatorInfo { // initial_val_set is the initial validator set of the subscriber chain. repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 [ (gogoproto.nullable) = false ]; +} + +// SubscriberValidator is a validator structure on the subscriber chain. It is stored +// within the subscriber module, indexed by a prefix + consensus address, and +// within the coordinator module, indexed by a prefix + chain id + consensus address. +message SubscriberValidator { + // address, as derived from the consensus key. No correlation with the operator + // address on Exocore. + bytes cons_address = 1; + // power is the vote power of the validator + int64 power = 2; + // pubkey is the consensus public key of the validator, as a Protobuf Any. + // this type is chosen to match the x/staking/validator type. + google.protobuf.Any pubkey = 3 [ + (cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", + (gogoproto.moretags) = "yaml:\"consensus_pubkey\"" + ]; } \ No newline at end of file diff --git a/proto/exocore/appchain/common/v1/wire.proto b/proto/exocore/appchain/common/v1/wire.proto index 1bcebaad3..a0fe46890 100644 --- a/proto/exocore/appchain/common/v1/wire.proto +++ b/proto/exocore/appchain/common/v1/wire.proto @@ -83,5 +83,5 @@ message ValidatorSetChangePacketData { uint64 valset_update_id = 2 [(gogoproto.customname) = "ValsetUpdateID"]; // slash_acks is the list of consensus addresses slashed on the coordinator chain, // in response to such requests from the subscriber chain. - repeated string slash_acks = 3; + repeated bytes slash_acks = 3; } \ No newline at end of file diff --git a/proto/exocore/appchain/coordinator/v1/coordinator.proto b/proto/exocore/appchain/coordinator/v1/coordinator.proto index 4b0a3e06e..7043bb3b4 100644 --- a/proto/exocore/appchain/coordinator/v1/coordinator.proto +++ b/proto/exocore/appchain/coordinator/v1/coordinator.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package exocore.appchain.coordinator.v1; +import "exocore/appchain/common/v1/wire.proto"; import "exocore/appchain/coordinator/v1/tx.proto"; import "gogoproto/gogo.proto"; @@ -25,4 +26,17 @@ message ChainIDs { message ConsensusAddresses { // list is the list of consensus addresses. repeated bytes list = 1; +} + +// ValidatorSetChangePackets is a helper structure to store a list of packets +message ValidatorSetChangePackets { + // list is the list of packets to be sent to the subscriber chain. + repeated .exocore.appchain.common.v1.ValidatorSetChangePacketData list = 1 + [(gogoproto.nullable) = false]; +} + +// UndelegationRecordKeys is a collection of undelegation record keys. +message UndelegationRecordKeys { + // list is the list of undelegation record keys. + repeated bytes list = 1; } \ No newline at end of file diff --git a/proto/exocore/appchain/subscriber/v1/subscriber.proto b/proto/exocore/appchain/subscriber/v1/subscriber.proto deleted file mode 100644 index 673cb21bd..000000000 --- a/proto/exocore/appchain/subscriber/v1/subscriber.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; - -package exocore.appchain.subscriber.v1; - -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; - -// SubscriberChainValidator is a validator structure on the subscriber chain. -// The name is verbose intentionally. -message SubscriberChainValidator { - // address, as derived from the consensus key. No correlation with the operator - // address on Exocore. - bytes cons_address = 1; - // power is the vote power of the validator - int64 power = 2; - // pubkey is the consensus public key of the validator, as a Protobuf Any. - // this type is chosen to match the x/staking/validator type. - google.protobuf.Any pubkey = 3 [ - (cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", - (gogoproto.moretags) = "yaml:\"consensus_pubkey\"" - ]; -} - diff --git a/utils/utils.go b/utils/utils.go index e3ccb166d..2056f1f8c 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -199,6 +199,12 @@ func AppendMany(byteses ...[]byte) (out []byte) { // ChainIDWithoutRevision returns the chainID without the revision number. // For example, "exocoretestnet_233-1" returns "exocoretestnet_233". +// In the case of app chains, it is not used because upgrading the subscriber +// isn't handled yet, because, during an upgrade, it is not safe to assume +// that the same set of operators will continue with the new chainID. +// The coordinator upgrade also similarly needs to be +// designed and implemented, but that it should be a trivial fix like +// deploying a new IBC client. func ChainIDWithoutRevision(chainID string) string { if !ibcclienttypes.IsRevisionFormat(chainID) { return chainID @@ -206,3 +212,18 @@ func ChainIDWithoutRevision(chainID string) string { splitStr := strings.Split(chainID, "-") return splitStr[0] } + +// ChainIDWithLenKey returns the key with the following format: +// bytePrefix | len(chainId) | chainId +// This is similar to Solidity's ABI encoding. +// The caller should typically append a constant length byte array to this and use it as a key. +func ChainIDWithLenKey(chainID string) []byte { + chainIDL := len(chainID) + return AppendMany( + // Append the chainID length + // #nosec G701 + sdk.Uint64ToBigEndian(uint64(chainIDL)), + // Append the chainID + []byte(chainID), + ) +} diff --git a/x/appchain/common/types/common.pb.go b/x/appchain/common/types/common.pb.go index 8b230e1aa..729ffbee8 100644 --- a/x/appchain/common/types/common.pb.go +++ b/x/appchain/common/types/common.pb.go @@ -6,6 +6,8 @@ package types import ( fmt "fmt" types "github.com/cometbft/cometbft/abci/types" + _ "github.com/cosmos/cosmos-proto" + types1 "github.com/cosmos/cosmos-sdk/codec/types" _ "github.com/cosmos/cosmos-sdk/types/tx/amino" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -316,10 +318,79 @@ func (m *CoordinatorInfo) GetInitialValSet() []types.ValidatorUpdate { return nil } +// SubscriberValidator is a validator structure on the subscriber chain. It is stored +// within the subscriber module, indexed by a prefix + consensus address, and +// within the coordinator module, indexed by a prefix + chain id + consensus address. +type SubscriberValidator struct { + // address, as derived from the consensus key. No correlation with the operator + // address on Exocore. + ConsAddress []byte `protobuf:"bytes,1,opt,name=cons_address,json=consAddress,proto3" json:"cons_address,omitempty"` + // power is the vote power of the validator + Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` + // pubkey is the consensus public key of the validator, as a Protobuf Any. + // this type is chosen to match the x/staking/validator type. + Pubkey *types1.Any `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" yaml:"consensus_pubkey"` +} + +func (m *SubscriberValidator) Reset() { *m = SubscriberValidator{} } +func (m *SubscriberValidator) String() string { return proto.CompactTextString(m) } +func (*SubscriberValidator) ProtoMessage() {} +func (*SubscriberValidator) Descriptor() ([]byte, []int) { + return fileDescriptor_71cb7b22d050d7a3, []int{3} +} +func (m *SubscriberValidator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SubscriberValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SubscriberValidator.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SubscriberValidator) XXX_Merge(src proto.Message) { + xxx_messageInfo_SubscriberValidator.Merge(m, src) +} +func (m *SubscriberValidator) XXX_Size() int { + return m.Size() +} +func (m *SubscriberValidator) XXX_DiscardUnknown() { + xxx_messageInfo_SubscriberValidator.DiscardUnknown(m) +} + +var xxx_messageInfo_SubscriberValidator proto.InternalMessageInfo + +func (m *SubscriberValidator) GetConsAddress() []byte { + if m != nil { + return m.ConsAddress + } + return nil +} + +func (m *SubscriberValidator) GetPower() int64 { + if m != nil { + return m.Power + } + return 0 +} + +func (m *SubscriberValidator) GetPubkey() *types1.Any { + if m != nil { + return m.Pubkey + } + return nil +} + func init() { proto.RegisterType((*SubscriberParams)(nil), "exocore.appchain.common.v1.SubscriberParams") proto.RegisterType((*SubscriberGenesisState)(nil), "exocore.appchain.common.v1.SubscriberGenesisState") proto.RegisterType((*CoordinatorInfo)(nil), "exocore.appchain.common.v1.CoordinatorInfo") + proto.RegisterType((*SubscriberValidator)(nil), "exocore.appchain.common.v1.SubscriberValidator") } func init() { @@ -327,59 +398,66 @@ func init() { } var fileDescriptor_71cb7b22d050d7a3 = []byte{ - // 819 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xc1, 0x6e, 0x1c, 0x45, - 0x10, 0xf5, 0xc4, 0xc1, 0x24, 0xbd, 0x09, 0xbb, 0x6e, 0x25, 0xf1, 0x64, 0x81, 0xf5, 0xda, 0x42, - 0xc2, 0x22, 0x30, 0xa3, 0x18, 0x09, 0x09, 0x71, 0x01, 0xdb, 0x09, 0x8a, 0x85, 0x8c, 0xb5, 0x1b, - 0x82, 0x04, 0x12, 0xad, 0x9e, 0x9e, 0xda, 0xd9, 0x22, 0xb3, 0xdd, 0xa3, 0xee, 0x1e, 0x3b, 0xfc, - 0x02, 0x27, 0x8e, 0x7c, 0x02, 0x47, 0xae, 0xfc, 0x41, 0x8e, 0x39, 0x72, 0x0a, 0xc8, 0x3e, 0xf0, - 0x0f, 0x9c, 0x50, 0xf7, 0xcc, 0x78, 0x67, 0x1d, 0x19, 0xe7, 0xb2, 0xea, 0xee, 0x7a, 0xf5, 0xea, - 0x55, 0xd5, 0x56, 0x0d, 0x79, 0x1f, 0x9e, 0x29, 0xa1, 0x34, 0xc4, 0xbc, 0x28, 0xc4, 0x94, 0xa3, - 0x8c, 0x85, 0x9a, 0xcd, 0x94, 0x8c, 0x8f, 0xee, 0xd7, 0xa7, 0xa8, 0xd0, 0xca, 0x2a, 0xda, 0xaf, - 0x81, 0x51, 0x03, 0x8c, 0x6a, 0xf3, 0xd1, 0xfd, 0xfe, 0x2a, 0x9f, 0xa1, 0x54, 0xb1, 0xff, 0xad, - 0xe0, 0xfd, 0x5b, 0x99, 0xca, 0x94, 0x3f, 0xc6, 0xee, 0x54, 0xbf, 0x0e, 0x32, 0xa5, 0xb2, 0x1c, - 0x62, 0x7f, 0x4b, 0xca, 0x49, 0x9c, 0x96, 0x9a, 0x5b, 0x6c, 0x82, 0xf4, 0x63, 0x4c, 0x44, 0x9c, - 0x63, 0x36, 0xb5, 0x22, 0x47, 0x90, 0xd6, 0xc4, 0x16, 0x64, 0x0a, 0x7a, 0x86, 0xd2, 0x3a, 0x45, - 0xf3, 0x5b, 0xed, 0xf0, 0x76, 0xcb, 0xce, 0x13, 0x81, 0xb1, 0xfd, 0xa9, 0x00, 0x53, 0x19, 0x37, - 0xff, 0x5d, 0x21, 0xbd, 0x71, 0x99, 0x18, 0xa1, 0x31, 0x01, 0x7d, 0xc8, 0x35, 0x9f, 0x19, 0xfa, - 0x39, 0x79, 0x57, 0x28, 0xa5, 0x53, 0x94, 0xdc, 0x2a, 0xcd, 0x26, 0x00, 0xac, 0x50, 0x2a, 0x67, - 0x3c, 0x4d, 0x35, 0x33, 0x56, 0x87, 0xc1, 0x30, 0xd8, 0xba, 0x3e, 0xba, 0xdb, 0x02, 0x3d, 0x04, - 0x38, 0x54, 0x2a, 0xff, 0x22, 0x4d, 0xf5, 0xd8, 0x6a, 0xba, 0x4f, 0x36, 0x52, 0x34, 0x56, 0x63, - 0x52, 0x3a, 0xe9, 0xcc, 0x6a, 0x2e, 0xcd, 0x0c, 0x8d, 0x71, 0x17, 0x31, 0xe5, 0x52, 0x42, 0x1e, - 0x5e, 0xf1, 0x2c, 0xeb, 0x6d, 0xe0, 0xe3, 0x16, 0x6e, 0xb7, 0x82, 0xd1, 0xaf, 0xc9, 0x7b, 0x49, - 0xae, 0xc4, 0x53, 0xc3, 0x0a, 0xd0, 0xec, 0x42, 0xda, 0x70, 0x79, 0x18, 0x6c, 0x2d, 0x8f, 0x36, - 0x2a, 0xec, 0x21, 0xe8, 0xbd, 0x0b, 0x78, 0xe9, 0x57, 0x64, 0xd3, 0x9c, 0xa5, 0xcc, 0x34, 0x2c, - 0x50, 0x4e, 0x34, 0x17, 0xee, 0x10, 0x5e, 0xf5, 0xea, 0x86, 0x73, 0xe4, 0x68, 0x01, 0xf8, 0xb0, - 0xc6, 0xd1, 0x0d, 0x72, 0x43, 0xc3, 0x31, 0xd7, 0x29, 0x4b, 0x41, 0xaa, 0x59, 0xf8, 0x86, 0xf7, - 0xeb, 0x54, 0x6f, 0x7b, 0xee, 0x89, 0x02, 0xa1, 0x98, 0x08, 0x66, 0x71, 0x06, 0xaa, 0xb4, 0x2e, - 0x0d, 0x54, 0x69, 0xb8, 0x32, 0x0c, 0xb6, 0x3a, 0xdb, 0x77, 0xa3, 0xaa, 0xdf, 0x51, 0xd3, 0xef, - 0x68, 0xaf, 0xee, 0xf7, 0xce, 0x3b, 0xcf, 0x5f, 0xae, 0x2f, 0x9d, 0xbc, 0x5c, 0xef, 0x3d, 0xda, - 0xd9, 0x7d, 0x5c, 0xf9, 0x1e, 0x7a, 0xd7, 0x5f, 0xff, 0x5a, 0x0f, 0x46, 0x3d, 0x4c, 0xc4, 0xc2, - 0x2b, 0xfd, 0x9e, 0xac, 0xf9, 0x82, 0x4c, 0x40, 0x9f, 0x8f, 0xf5, 0xe6, 0x65, 0xb1, 0xae, 0xb9, - 0x58, 0x9e, 0xf7, 0x76, 0xc3, 0xb1, 0x48, 0x7e, 0x40, 0x7a, 0xa5, 0x4c, 0x94, 0x4c, 0x51, 0x66, - 0x0d, 0xeb, 0xb5, 0xd7, 0x67, 0xed, 0x9e, 0x39, 0xd7, 0x7c, 0x1f, 0x11, 0x3a, 0x45, 0x63, 0x95, - 0x46, 0xc1, 0x73, 0x06, 0xd2, 0x6a, 0x04, 0x13, 0x5e, 0xf7, 0x3d, 0x5c, 0x9d, 0x5b, 0x1e, 0x54, - 0x06, 0xfa, 0x09, 0x59, 0x33, 0x39, 0x37, 0xd3, 0xb3, 0xfe, 0xb0, 0x54, 0x1d, 0x4b, 0x97, 0x65, - 0xd8, 0xf5, 0x05, 0xbf, 0xed, 0xcd, 0x4d, 0x57, 0xf6, 0x6a, 0x23, 0xfd, 0x81, 0xdc, 0x69, 0x80, - 0xec, 0x47, 0x8e, 0x39, 0x6b, 0xa6, 0x29, 0xec, 0x5d, 0x26, 0xfe, 0x66, 0x23, 0xfe, 0xb7, 0x7f, - 0x7e, 0xff, 0x20, 0x18, 0xdd, 0x6a, 0x78, 0xf6, 0x39, 0xe6, 0x0d, 0x88, 0x7e, 0x46, 0xfa, 0xaf, - 0xe8, 0x2a, 0x93, 0x1c, 0x98, 0xc1, 0x4c, 0x86, 0xab, 0x5e, 0xda, 0xda, 0x39, 0x69, 0xce, 0x3e, - 0xc6, 0x4c, 0x6e, 0xfe, 0x11, 0x90, 0x3b, 0xf3, 0xe1, 0xfb, 0x12, 0x24, 0x18, 0x34, 0x63, 0xcb, - 0x2d, 0xd0, 0x7d, 0xb2, 0x52, 0xf8, 0x61, 0xf4, 0xb3, 0xd6, 0xd9, 0xfe, 0x30, 0xba, 0x78, 0xb7, - 0x44, 0xe7, 0x07, 0x78, 0xe7, 0xaa, 0x93, 0x3e, 0xaa, 0x19, 0xe8, 0x98, 0x74, 0x5a, 0x93, 0xea, - 0xc7, 0xae, 0xb3, 0x7d, 0xef, 0xff, 0x08, 0x77, 0xe7, 0xf0, 0x47, 0x72, 0xa2, 0x6a, 0xbe, 0x36, - 0xcb, 0xe6, 0xcf, 0x57, 0x48, 0xf7, 0x1c, 0x8c, 0x1e, 0x90, 0x1b, 0xd5, 0x4e, 0x62, 0xc6, 0x25, - 0x51, 0x4b, 0xbf, 0x17, 0x61, 0x22, 0xa2, 0xf6, 0xc6, 0x8a, 0x5a, 0x3b, 0xca, 0x45, 0xf3, 0xaf, - 0x3e, 0xef, 0x51, 0x47, 0xcc, 0x2f, 0xf4, 0x5b, 0xd2, 0x15, 0x4a, 0x1a, 0x90, 0xa6, 0x34, 0x35, - 0x65, 0x25, 0x3e, 0xba, 0x94, 0xb2, 0x71, 0xab, 0x58, 0xdf, 0x12, 0x0b, 0x77, 0x7a, 0x40, 0xba, - 0x28, 0xd1, 0x22, 0xcf, 0xd9, 0x11, 0xcf, 0x99, 0x01, 0x1b, 0x2e, 0x0f, 0x97, 0xb7, 0x3a, 0xdb, - 0xc3, 0x36, 0x8f, 0x5b, 0x96, 0xd1, 0x13, 0x9e, 0x63, 0xea, 0x32, 0xfc, 0xa6, 0x48, 0xb9, 0x85, - 0xba, 0x14, 0x37, 0x6b, 0xf7, 0x27, 0x3c, 0x1f, 0x83, 0xdd, 0x19, 0x3f, 0x3f, 0x19, 0x04, 0x2f, - 0x4e, 0x06, 0xc1, 0xdf, 0x27, 0x83, 0xe0, 0x97, 0xd3, 0xc1, 0xd2, 0x8b, 0xd3, 0xc1, 0xd2, 0x9f, - 0xa7, 0x83, 0xa5, 0xef, 0x3e, 0xcd, 0xd0, 0x4e, 0xcb, 0xc4, 0xd5, 0x36, 0x7e, 0x50, 0x15, 0xfc, - 0x00, 0xec, 0xb1, 0xd2, 0x4f, 0xe3, 0xe6, 0xab, 0xf2, 0xec, 0x95, 0xef, 0x8a, 0x5f, 0xd0, 0xc9, - 0x8a, 0xff, 0x4b, 0x7e, 0xfc, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7, 0xc6, 0x07, 0xf5, 0x7f, - 0x06, 0x00, 0x00, + // 930 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4f, 0x6f, 0x1c, 0x35, + 0x14, 0xcf, 0x34, 0x6d, 0x68, 0xbd, 0x29, 0xd9, 0x98, 0x6d, 0x33, 0x59, 0x60, 0x77, 0xb3, 0x42, + 0x22, 0xa2, 0x74, 0x46, 0xdd, 0x4a, 0x48, 0xc0, 0x85, 0x6c, 0xd2, 0xa2, 0x06, 0x14, 0x56, 0xbb, + 0xa5, 0x48, 0x20, 0x61, 0x79, 0x3c, 0xde, 0x5d, 0x93, 0x19, 0x7b, 0x64, 0x7b, 0x92, 0xee, 0x57, + 0xe0, 0xc4, 0x91, 0x8f, 0xc0, 0x11, 0x24, 0x2e, 0x7c, 0x83, 0x8a, 0x53, 0x8f, 0x9c, 0x02, 0x4a, + 0x0e, 0xdc, 0x39, 0x72, 0x42, 0xf6, 0x78, 0xb2, 0x7f, 0xa2, 0x90, 0x5e, 0x46, 0xf3, 0xfc, 0x7e, + 0xef, 0xe7, 0xdf, 0xf3, 0xf3, 0x7b, 0x06, 0xef, 0xd2, 0xe7, 0x82, 0x08, 0x49, 0x43, 0x9c, 0x65, + 0x64, 0x8c, 0x19, 0x0f, 0x89, 0x48, 0x53, 0xc1, 0xc3, 0xa3, 0x07, 0xee, 0x2f, 0xc8, 0xa4, 0xd0, + 0x02, 0xd6, 0x1d, 0x30, 0x28, 0x81, 0x81, 0x73, 0x1f, 0x3d, 0xa8, 0xaf, 0xe3, 0x94, 0x71, 0x11, + 0xda, 0x6f, 0x01, 0xaf, 0x6f, 0x12, 0xa1, 0x52, 0xa1, 0x90, 0xb5, 0xc2, 0xc2, 0x70, 0xae, 0xda, + 0x48, 0x8c, 0x44, 0xb1, 0x6e, 0xfe, 0xca, 0x80, 0x91, 0x10, 0xa3, 0x84, 0x86, 0xd6, 0x8a, 0xf2, + 0x61, 0x88, 0xf9, 0xc4, 0xb9, 0x1a, 0x8b, 0xae, 0x38, 0x97, 0x58, 0xb3, 0x52, 0x5a, 0x3d, 0x64, + 0x11, 0x09, 0x13, 0x36, 0x1a, 0x6b, 0x92, 0x30, 0xca, 0xb5, 0x0a, 0x35, 0xe5, 0x31, 0x95, 0x29, + 0xe3, 0xda, 0xe4, 0x31, 0xb5, 0x5c, 0xc0, 0x9b, 0x33, 0x7e, 0x1c, 0x11, 0x16, 0xea, 0x49, 0x46, + 0x9d, 0xbc, 0xf6, 0xbf, 0x2b, 0xa0, 0x3a, 0xc8, 0x23, 0x45, 0x24, 0x8b, 0xa8, 0xec, 0x61, 0x89, + 0x53, 0x05, 0x3f, 0x01, 0x6f, 0x13, 0x21, 0x64, 0xcc, 0x38, 0xd6, 0x42, 0xa2, 0x21, 0xa5, 0x28, + 0x13, 0x22, 0x41, 0x38, 0x8e, 0x25, 0x52, 0x5a, 0xfa, 0x5e, 0xcb, 0xdb, 0xbe, 0xd5, 0xdf, 0x9c, + 0x01, 0x3d, 0xa6, 0xb4, 0x27, 0x44, 0xb2, 0x13, 0xc7, 0x72, 0xa0, 0x25, 0xdc, 0x07, 0x5b, 0x31, + 0x53, 0x5a, 0xb2, 0x28, 0x37, 0xd2, 0x91, 0x96, 0x98, 0xab, 0x94, 0x29, 0x65, 0x0c, 0x32, 0xc6, + 0x9c, 0xd3, 0xc4, 0xbf, 0x66, 0x59, 0x9a, 0xb3, 0xc0, 0xa7, 0x33, 0xb8, 0xdd, 0x02, 0x06, 0xbf, + 0x00, 0xef, 0x44, 0x89, 0x20, 0x87, 0x0a, 0x65, 0x54, 0xa2, 0x4b, 0x69, 0xfd, 0xe5, 0x96, 0xb7, + 0xbd, 0xdc, 0xdf, 0x2a, 0xb0, 0x3d, 0x2a, 0xf7, 0x2e, 0xe1, 0x85, 0x9f, 0x83, 0xb6, 0x3a, 0x4f, + 0x19, 0x49, 0x3a, 0x47, 0x39, 0x94, 0x98, 0x98, 0x1f, 0xff, 0xba, 0x55, 0xd7, 0x9a, 0x22, 0xfb, + 0x73, 0xc0, 0xc7, 0x0e, 0x07, 0xb7, 0xc0, 0xaa, 0xa4, 0xc7, 0x58, 0xc6, 0x28, 0xa6, 0x5c, 0xa4, + 0xfe, 0x0d, 0x1b, 0x57, 0x29, 0xd6, 0xf6, 0xcc, 0x12, 0xa4, 0x00, 0xb2, 0x88, 0x20, 0xcd, 0x52, + 0x2a, 0x72, 0x6d, 0xd2, 0x60, 0x22, 0xf6, 0x57, 0x5a, 0xde, 0x76, 0xa5, 0xb3, 0x19, 0x14, 0xf5, + 0x0e, 0xca, 0x7a, 0x07, 0x7b, 0xae, 0xde, 0xdd, 0xb7, 0x5e, 0x9c, 0x34, 0x97, 0x4e, 0x4f, 0x9a, + 0xd5, 0x27, 0xdd, 0xdd, 0xa7, 0x45, 0x6c, 0xcf, 0x86, 0xfe, 0xf8, 0x67, 0xd3, 0xeb, 0x57, 0x59, + 0x44, 0xe6, 0x56, 0xe1, 0x37, 0x60, 0xc3, 0x1e, 0xc8, 0x90, 0xca, 0xc5, 0xbd, 0x5e, 0xbb, 0x6a, + 0xaf, 0x9b, 0x66, 0x2f, 0xcb, 0x7b, 0xa7, 0xe4, 0x98, 0x27, 0x3f, 0x00, 0xd5, 0x9c, 0x47, 0x82, + 0xc7, 0x8c, 0x8f, 0x4a, 0xd6, 0x9b, 0xaf, 0xce, 0xba, 0x76, 0x1e, 0xec, 0xf8, 0xee, 0x03, 0x38, + 0x66, 0x4a, 0x0b, 0xc9, 0x08, 0x4e, 0x10, 0xe5, 0x5a, 0x32, 0xaa, 0xfc, 0x5b, 0xb6, 0x86, 0xeb, + 0x53, 0xcf, 0xa3, 0xc2, 0x01, 0x3f, 0x00, 0x1b, 0x2a, 0xc1, 0x6a, 0x7c, 0x5e, 0x1f, 0x14, 0x8b, + 0x63, 0x6e, 0xb2, 0xf4, 0xd7, 0xec, 0x81, 0xdf, 0xb1, 0xee, 0xb2, 0x2a, 0x7b, 0xce, 0x09, 0xbf, + 0x05, 0x77, 0x4b, 0x20, 0xfa, 0x0e, 0xb3, 0x04, 0x95, 0xdd, 0xe4, 0x57, 0xaf, 0x12, 0x7f, 0xbb, + 0x14, 0xff, 0xd3, 0xdf, 0x3f, 0xbf, 0xe7, 0xf5, 0x6b, 0x25, 0xcf, 0x3e, 0x66, 0x49, 0x09, 0x82, + 0x1f, 0x83, 0xfa, 0x05, 0x5d, 0x79, 0x94, 0x50, 0xa4, 0xd8, 0x88, 0xfb, 0xeb, 0x56, 0xda, 0xc6, + 0x82, 0x34, 0xe3, 0x1f, 0xb0, 0x11, 0x6f, 0xff, 0xe6, 0x81, 0xbb, 0xd3, 0xe6, 0xfb, 0x94, 0x72, + 0xaa, 0x98, 0x1a, 0x68, 0xac, 0x29, 0xdc, 0x07, 0x2b, 0x99, 0x6d, 0x46, 0xdb, 0x6b, 0x95, 0xce, + 0xfb, 0xc1, 0xe5, 0x13, 0x29, 0x58, 0x6c, 0xe0, 0xee, 0x75, 0x23, 0xbd, 0xef, 0x18, 0xe0, 0x00, + 0x54, 0x66, 0x3a, 0xd5, 0xb6, 0x5d, 0xa5, 0x73, 0xef, 0xff, 0x08, 0x77, 0xa7, 0xf0, 0x27, 0x7c, + 0x28, 0x1c, 0xdf, 0x2c, 0x4b, 0xfb, 0xfb, 0x6b, 0x60, 0x6d, 0x01, 0x06, 0x0f, 0xc0, 0x6a, 0x31, + 0x93, 0x90, 0x32, 0x49, 0x38, 0xe9, 0xf7, 0x02, 0x16, 0x91, 0x60, 0x76, 0x62, 0x05, 0x33, 0x33, + 0xca, 0xec, 0x66, 0x57, 0x6d, 0xde, 0xfd, 0x0a, 0x99, 0x1a, 0xf0, 0x2b, 0xb0, 0x46, 0x04, 0x57, + 0x94, 0xab, 0x5c, 0x39, 0xca, 0x42, 0x7c, 0x70, 0x25, 0x65, 0x19, 0x56, 0xb0, 0xbe, 0x4e, 0xe6, + 0x6c, 0x78, 0x00, 0xd6, 0x18, 0x67, 0x9a, 0xe1, 0x04, 0x1d, 0xe1, 0x04, 0x29, 0xaa, 0xfd, 0xe5, + 0xd6, 0xf2, 0x76, 0xa5, 0xd3, 0x9a, 0xe5, 0x31, 0xc3, 0x32, 0x78, 0x86, 0x13, 0x16, 0x9b, 0x0c, + 0xbf, 0xcc, 0x62, 0xac, 0xa9, 0x3b, 0x8a, 0xdb, 0x2e, 0xfc, 0x19, 0x4e, 0x06, 0x54, 0xb7, 0x7f, + 0xf1, 0xc0, 0x1b, 0xd3, 0x22, 0x9c, 0x87, 0x98, 0xd9, 0x60, 0x76, 0xb6, 0x83, 0x93, 0xaa, 0xa2, + 0x96, 0xab, 0xe6, 0x1c, 0xb9, 0xda, 0x29, 0x96, 0x60, 0x0d, 0xdc, 0xc8, 0xc4, 0x31, 0x2d, 0xca, + 0xb2, 0xdc, 0x2f, 0x0c, 0x88, 0xc1, 0x4a, 0x96, 0x47, 0x87, 0x74, 0x62, 0xa7, 0x5a, 0xa5, 0x53, + 0xbb, 0x70, 0x4d, 0x77, 0xf8, 0xa4, 0xfb, 0xf0, 0x9f, 0x93, 0xe6, 0xc6, 0x04, 0xa7, 0xc9, 0x47, + 0xed, 0xe9, 0x39, 0x15, 0x71, 0xed, 0xdf, 0x7f, 0xbd, 0x5f, 0x73, 0x0f, 0x11, 0x91, 0x93, 0x4c, + 0x8b, 0xa0, 0x97, 0x47, 0x9f, 0xd1, 0x49, 0xdf, 0x11, 0x77, 0x07, 0x2f, 0x4e, 0x1b, 0xde, 0xcb, + 0xd3, 0x86, 0xf7, 0xd7, 0x69, 0xc3, 0xfb, 0xe1, 0xac, 0xb1, 0xf4, 0xf2, 0xac, 0xb1, 0xf4, 0xc7, + 0x59, 0x63, 0xe9, 0xeb, 0x0f, 0x47, 0x4c, 0x8f, 0xf3, 0xc8, 0xdc, 0x87, 0xf0, 0x51, 0x71, 0x49, + 0x0e, 0xa8, 0x3e, 0x16, 0xf2, 0x30, 0x2c, 0xdf, 0xcf, 0xe7, 0x17, 0x5e, 0x50, 0xfb, 0xa8, 0x44, + 0x2b, 0x56, 0xdf, 0xc3, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x17, 0x4e, 0x95, 0x63, 0x69, 0x07, + 0x00, 0x00, } func (m *SubscriberParams) Marshal() (dAtA []byte, err error) { @@ -597,6 +675,53 @@ func (m *CoordinatorInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SubscriberValidator) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SubscriberValidator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SubscriberValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pubkey != nil { + { + size, err := m.Pubkey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommon(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Power != 0 { + i = encodeVarintCommon(dAtA, i, uint64(m.Power)) + i-- + dAtA[i] = 0x10 + } + if len(m.ConsAddress) > 0 { + i -= len(m.ConsAddress) + copy(dAtA[i:], m.ConsAddress) + i = encodeVarintCommon(dAtA, i, uint64(len(m.ConsAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintCommon(dAtA []byte, offset int, v uint64) int { offset -= sovCommon(v) base := offset @@ -691,6 +816,26 @@ func (m *CoordinatorInfo) Size() (n int) { return n } +func (m *SubscriberValidator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ConsAddress) + if l > 0 { + n += 1 + l + sovCommon(uint64(l)) + } + if m.Power != 0 { + n += 1 + sovCommon(uint64(m.Power)) + } + if m.Pubkey != nil { + l = m.Pubkey.Size() + n += 1 + l + sovCommon(uint64(l)) + } + return n +} + func sovCommon(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1381,6 +1526,145 @@ func (m *CoordinatorInfo) Unmarshal(dAtA []byte) error { } return nil } +func (m *SubscriberValidator) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubscriberValidator: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubscriberValidator: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsAddress", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConsAddress = append(m.ConsAddress[:0], dAtA[iNdEx:postIndex]...) + if m.ConsAddress == nil { + m.ConsAddress = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType) + } + m.Power = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Power |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pubkey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommon + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommon + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommon + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pubkey == nil { + m.Pubkey = &types1.Any{} + } + if err := m.Pubkey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommon(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommon + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipCommon(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/appchain/common/types/events.go b/x/appchain/common/types/events.go index 5f2bcbd49..35a14bceb 100644 --- a/x/appchain/common/types/events.go +++ b/x/appchain/common/types/events.go @@ -1,10 +1,13 @@ package types const ( - AttributeChainID = "chain_id" - AttributeKeyAckSuccess = "success" - AttributeKeyAck = "acknowledgement" - AttributeKeyAckError = "ack_error" + AttributeChainID = "chain_id" + AttributeKeyAckSuccess = "success" + AttributeKeyAck = "acknowledgement" + AttributeKeyAckError = "ack_error" + AttributeInfractionType = "infraction_type" + AttributeValidatorAddress = "validator_address" + AttributeValSetUpdateID = "valset_update_id" EventTypeChannelEstablished = "channel_established" EventTypePacket = "common_packet" diff --git a/x/appchain/common/types/expected_keepers.go b/x/appchain/common/types/expected_keepers.go index a677c2335..15eb8245e 100644 --- a/x/appchain/common/types/expected_keepers.go +++ b/x/appchain/common/types/expected_keepers.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" auth "github.com/cosmos/cosmos-sdk/x/auth/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" @@ -74,3 +75,22 @@ type IBCCoreKeeper interface { type AccountKeeper interface { GetModuleAccount(ctx sdk.Context, name string) auth.ModuleAccountI } + +// BankKeeper defines the expected bank keeper +type BankKeeper interface { + GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin + GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + SendCoinsFromModuleToModule( + ctx sdk.Context, + senderModule, recipientModule string, + amt sdk.Coins, + ) error +} + +// IBCTransferKeeper defines the expected IBC transfer keeper +type IBCTransferKeeper interface { + Transfer( + context.Context, + *transfertypes.MsgTransfer, + ) (*transfertypes.MsgTransferResponse, error) +} diff --git a/x/appchain/common/types/types.go b/x/appchain/common/types/types.go index 6b5466099..7c25c94d3 100644 --- a/x/appchain/common/types/types.go +++ b/x/appchain/common/types/types.go @@ -1,6 +1,7 @@ package types import ( + abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) @@ -16,3 +17,24 @@ func NewResultAcknowledgementWithLog(ctx sdk.Context, res []byte) channeltypes.A ctx.Logger().Info("IBC ResultAcknowledgement constructed", "res", res) return channeltypes.NewResultAcknowledgement(res) } + +// NewVscPacketData creates a new ValidatorSetChangePacketData instance. +func NewVscPacketData( + updates []abci.ValidatorUpdate, + valsetUpdateID uint64, + slashAcks [][]byte, +) ValidatorSetChangePacketData { + return ValidatorSetChangePacketData{ + ValidatorUpdates: updates, + ValsetUpdateID: valsetUpdateID, + SlashAcks: slashAcks, + } +} + +func NewVscMaturedPacketData( + valsetUpdateID uint64, +) *VscMaturedPacketData { + return &VscMaturedPacketData{ + ValsetUpdateID: valsetUpdateID, + } +} diff --git a/x/appchain/common/types/utils.go b/x/appchain/common/types/utils.go new file mode 100644 index 000000000..ccb8bfef5 --- /dev/null +++ b/x/appchain/common/types/utils.go @@ -0,0 +1,42 @@ +package types + +import ( + "time" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" +) + +// SendIBCPacket sends an IBC packet with packetData over the source channelID and portID. +func SendIBCPacket( + ctx sdk.Context, + scopedKeeper ScopedKeeper, + channelKeeper ChannelKeeper, + sourceChannelID string, + sourcePortID string, + packetData []byte, + timeoutPeriod time.Duration, +) error { + _, ok := channelKeeper.GetChannel(ctx, sourcePortID, sourceChannelID) + if !ok { + return errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", sourceChannelID) + } + channelCap, ok := scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(sourcePortID, sourceChannelID)) + if !ok { + return errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") + } + + _, err := channelKeeper.SendPacket(ctx, + channelCap, + sourcePortID, + sourceChannelID, + clienttypes.Height{}, // timeout height disabled + uint64(ctx.BlockTime().Add(timeoutPeriod).UnixNano()), // timeout timestamp + packetData, + ) + return err +} diff --git a/x/appchain/subscriber/types/validator.go b/x/appchain/common/types/validator.go similarity index 69% rename from x/appchain/subscriber/types/validator.go rename to x/appchain/common/types/validator.go index 7ab49887b..b5d2eab79 100644 --- a/x/appchain/subscriber/types/validator.go +++ b/x/appchain/common/types/validator.go @@ -8,16 +8,16 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// NewSubscriberChainValidator creates a new SubscriberChainValidator instance. -func NewSubscriberChainValidator( +// NewSubscriberValidator creates a new SubscriberValidator instance. +func NewSubscriberValidator( address []byte, power int64, pubKey cryptotypes.PubKey, -) (SubscriberChainValidator, error) { +) (SubscriberValidator, error) { pkAny, err := codectypes.NewAnyWithValue(pubKey) if err != nil { - return SubscriberChainValidator{}, err + return SubscriberValidator{}, err } - return SubscriberChainValidator{ + return SubscriberValidator{ ConsAddress: address, Power: power, Pubkey: pkAny, @@ -26,13 +26,13 @@ func NewSubscriberChainValidator( // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces. // It is required to ensure that ConsPubKey below works. -func (ocv SubscriberChainValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { +func (ocv SubscriberValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { var pk cryptotypes.PubKey return unpacker.UnpackAny(ocv.Pubkey, &pk) } // ConsPubKey returns the validator PubKey as a cryptotypes.PubKey. -func (ocv SubscriberChainValidator) ConsPubKey() (cryptotypes.PubKey, error) { +func (ocv SubscriberValidator) ConsPubKey() (cryptotypes.PubKey, error) { pk, ok := ocv.Pubkey.GetCachedValue().(cryptotypes.PubKey) if !ok { return nil, errorsmod.Wrapf( diff --git a/x/appchain/common/types/wire.go b/x/appchain/common/types/wire.go index bef4e3aac..4e678ff8a 100644 --- a/x/appchain/common/types/wire.go +++ b/x/appchain/common/types/wire.go @@ -1,15 +1,49 @@ package types import ( + abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) +// WrappedSubscriberPacketData is a wrapper interface for SubscriberPacketData. It allows +// exposting the private interface defined in `wire.pb.go` to the outside world. +type WrappedSubscriberPacketData interface { + isSubscriberPacketData_Data +} + +// NewSubscriberPacketData creates a new SubscriberPacketData instance. +func NewSubscriberPacketData( + packetType SubscriberPacketDataType, packet isSubscriberPacketData_Data, +) SubscriberPacketData { + return SubscriberPacketData{ + Type: packetType, + Data: packet, + } +} + +// NewSlashPacketData creates a new SlashPacketData instance. +func NewSlashPacketData( + validator abci.Validator, + valUpdateID uint64, + infractionType stakingtypes.Infraction, +) *SlashPacketData { + return &SlashPacketData{ + Validator: validator, + ValsetUpdateID: valUpdateID, + Infraction: infractionType, + } +} + // PacketAckResult is the acknowledgment result of a packet. type PacketAckResult []byte -// SlashPacketHandledResult is the success acknowledgment result of a slash packet. -var SlashPacketHandledResult = PacketAckResult([]byte{byte(2)}) +var ( + // VscPacketHandledResult is the success acknowledgment result of a validator set change packet. + VscPacketHandledResult = PacketAckResult([]byte{byte(1)}) + // SlashPacketHandledResult is the success acknowledgment result of a slash packet. + SlashPacketHandledResult = PacketAckResult([]byte{byte(2)}) +) func (vdt SlashPacketData) Validate() error { // vdt.Validator.Address must be a consensus address diff --git a/x/appchain/common/types/wire.pb.go b/x/appchain/common/types/wire.pb.go index 45cc6ad83..b8f974a49 100644 --- a/x/appchain/common/types/wire.pb.go +++ b/x/appchain/common/types/wire.pb.go @@ -337,7 +337,7 @@ type ValidatorSetChangePacketData struct { ValsetUpdateID uint64 `protobuf:"varint,2,opt,name=valset_update_id,json=valsetUpdateId,proto3" json:"valset_update_id,omitempty"` // slash_acks is the list of consensus addresses slashed on the coordinator chain, // in response to such requests from the subscriber chain. - SlashAcks []string `protobuf:"bytes,3,rep,name=slash_acks,json=slashAcks,proto3" json:"slash_acks,omitempty"` + SlashAcks [][]byte `protobuf:"bytes,3,rep,name=slash_acks,json=slashAcks,proto3" json:"slash_acks,omitempty"` } func (m *ValidatorSetChangePacketData) Reset() { *m = ValidatorSetChangePacketData{} } @@ -387,7 +387,7 @@ func (m *ValidatorSetChangePacketData) GetValsetUpdateID() uint64 { return 0 } -func (m *ValidatorSetChangePacketData) GetSlashAcks() []string { +func (m *ValidatorSetChangePacketData) GetSlashAcks() [][]byte { if m != nil { return m.SlashAcks } @@ -409,52 +409,52 @@ func init() { var fileDescriptor_646142158918d547 = []byte{ // 734 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xc1, 0x6e, 0xda, 0x4a, - 0x14, 0xb5, 0x03, 0xca, 0x13, 0x83, 0x44, 0xc0, 0xe2, 0xbd, 0xe7, 0xe7, 0xd7, 0x12, 0xd7, 0x6a, - 0x55, 0xd4, 0x4a, 0x76, 0xa1, 0x55, 0xa5, 0x54, 0xdd, 0xd8, 0x40, 0x04, 0x6a, 0x13, 0x21, 0x1b, - 0x90, 0xd2, 0x8d, 0x35, 0xd8, 0x13, 0xb0, 0x00, 0x8f, 0xe5, 0x19, 0x9c, 0xe4, 0x0f, 0xaa, 0xac, - 0xfa, 0x03, 0x59, 0x75, 0xdf, 0xef, 0xc8, 0x32, 0xcb, 0xae, 0xd2, 0x8a, 0x2c, 0xba, 0xe9, 0xaa, - 0x5f, 0x50, 0xd9, 0xc6, 0x84, 0xa4, 0x04, 0x55, 0xea, 0x6e, 0x66, 0xee, 0xbd, 0xe7, 0xde, 0x39, - 0xe7, 0xe8, 0x82, 0x47, 0xe8, 0x18, 0x5b, 0xd8, 0x47, 0x0a, 0xf4, 0x3c, 0x6b, 0x08, 0x1d, 0x57, - 0xb1, 0xf0, 0x64, 0x82, 0x5d, 0x25, 0xa8, 0x28, 0x47, 0x8e, 0x8f, 0x64, 0xcf, 0xc7, 0x14, 0x73, - 0xc2, 0x3c, 0x4d, 0x4e, 0xd2, 0xe4, 0x38, 0x4d, 0x0e, 0x2a, 0xc2, 0x43, 0x0b, 0x93, 0x09, 0x26, - 0x0a, 0xa1, 0x70, 0xe4, 0xb8, 0x03, 0x25, 0xa8, 0xf4, 0x11, 0x85, 0x95, 0xe4, 0x1e, 0x23, 0x08, - 0xc5, 0x01, 0x1e, 0xe0, 0xe8, 0xa8, 0x84, 0xa7, 0xf9, 0xeb, 0xff, 0x14, 0xb9, 0x36, 0xf2, 0x27, - 0x8e, 0x4b, 0x15, 0xd8, 0xb7, 0x1c, 0x85, 0x9e, 0x78, 0x88, 0xc4, 0x41, 0x69, 0x08, 0x0a, 0x4d, - 0xe8, 0xda, 0x64, 0x08, 0x47, 0x68, 0x0f, 0x51, 0x68, 0x43, 0x0a, 0xb9, 0x1d, 0xf0, 0x9f, 0x85, - 0xb1, 0x6f, 0x3b, 0x2e, 0xa4, 0xd8, 0x37, 0x0f, 0x11, 0x32, 0x3d, 0x8c, 0xc7, 0x26, 0xb4, 0x6d, - 0x9f, 0x67, 0x45, 0xb6, 0x9c, 0xd1, 0xff, 0x59, 0x4a, 0xd8, 0x45, 0xa8, 0x8d, 0xf1, 0x58, 0xb5, - 0x6d, 0x9f, 0xe3, 0xc1, 0x5f, 0x01, 0xf2, 0x89, 0x83, 0x5d, 0x7e, 0x23, 0x4a, 0x4c, 0xae, 0xd2, - 0x37, 0x16, 0x6c, 0x19, 0x63, 0x48, 0x86, 0x6d, 0x68, 0x8d, 0x10, 0xad, 0x87, 0x8d, 0x74, 0x90, - 0x09, 0xe0, 0xd8, 0xb1, 0x43, 0x94, 0x08, 0x38, 0x5b, 0x15, 0xe4, 0xeb, 0x71, 0xe5, 0x70, 0x5c, - 0xb9, 0x97, 0x64, 0x68, 0xfc, 0xf9, 0xe5, 0x36, 0xf3, 0xe3, 0x72, 0x3b, 0x7f, 0x02, 0x27, 0xe3, - 0x57, 0xd2, 0xa2, 0x54, 0xd2, 0xaf, 0x61, 0xb8, 0xd7, 0x20, 0x1f, 0xc0, 0x31, 0x41, 0xd4, 0x9c, - 0x7a, 0x36, 0xa4, 0xc8, 0x74, 0xec, 0x68, 0x94, 0xb4, 0xc6, 0xcd, 0x2e, 0xb7, 0x73, 0xbd, 0x28, - 0xd6, 0x8d, 0x42, 0xad, 0xba, 0x9e, 0x0b, 0x96, 0xef, 0x36, 0xa7, 0x01, 0xe0, 0xb8, 0x87, 0x3e, - 0xb4, 0x68, 0xf8, 0x85, 0x94, 0xc8, 0x96, 0x73, 0x55, 0x49, 0x8e, 0xd9, 0x97, 0x13, 0xb6, 0xe7, - 0xec, 0xcb, 0xad, 0x45, 0xa6, 0xbe, 0x54, 0x25, 0x75, 0x40, 0xb1, 0x47, 0xac, 0x3d, 0x48, 0xa7, - 0x3e, 0xb2, 0x97, 0x7e, 0xbb, 0x6a, 0x32, 0xf6, 0x77, 0x27, 0x93, 0x3e, 0x6d, 0x80, 0xa2, 0x31, - 0xed, 0x13, 0xcb, 0x77, 0xfa, 0xc8, 0x5f, 0x82, 0x6d, 0x82, 0x74, 0xa8, 0x68, 0x04, 0x95, 0xab, - 0xbe, 0x90, 0xef, 0xb6, 0x91, 0xbc, 0xaa, 0xbe, 0x73, 0xe2, 0x21, 0x3d, 0x42, 0xe0, 0x0e, 0x40, - 0x81, 0x84, 0x0a, 0x99, 0x5e, 0x14, 0x35, 0x43, 0x33, 0x44, 0xdc, 0x65, 0xab, 0x4f, 0xd7, 0xc2, - 0xde, 0x94, 0xb5, 0xc9, 0xe8, 0x5b, 0xe4, 0x96, 0xd2, 0x0e, 0xf8, 0x37, 0x20, 0x96, 0x39, 0x89, - 0x49, 0xb9, 0xd1, 0x20, 0x15, 0x35, 0x78, 0xb6, 0xae, 0xc1, 0x2a, 0x3a, 0x9b, 0x8c, 0x5e, 0x0c, - 0x56, 0xbc, 0x6b, 0x9b, 0x20, 0x1d, 0xe2, 0x4a, 0xdf, 0x59, 0x70, 0x6f, 0xe1, 0x1d, 0x03, 0xd1, - 0xda, 0x10, 0xba, 0x03, 0xb4, 0x34, 0x13, 0x06, 0x85, 0x85, 0x6d, 0xe6, 0x92, 0x10, 0x9e, 0x15, - 0x53, 0xe5, 0x6c, 0x55, 0xbc, 0xdb, 0x85, 0xb1, 0x20, 0x9a, 0x38, 0xf7, 0x22, 0x7f, 0xcb, 0x8b, - 0x09, 0x90, 0xa4, 0xe7, 0x83, 0x9b, 0x25, 0xe4, 0x0f, 0xad, 0x79, 0x1f, 0x80, 0x58, 0x1d, 0x68, - 0x8d, 0x08, 0x9f, 0x12, 0x53, 0xe5, 0x8c, 0x9e, 0x89, 0x5e, 0x54, 0x6b, 0x44, 0x9e, 0x7c, 0x61, - 0x01, 0x7f, 0x97, 0xbe, 0x9c, 0x06, 0x1e, 0x1b, 0x5d, 0xcd, 0xa8, 0xe9, 0x2d, 0xad, 0xa1, 0x9b, - 0x6d, 0xb5, 0xf6, 0xa6, 0xd1, 0x31, 0xeb, 0x6a, 0x47, 0x35, 0x3b, 0x07, 0xed, 0x86, 0xd9, 0xdd, - 0x37, 0xda, 0x8d, 0x5a, 0x6b, 0xb7, 0xd5, 0xa8, 0xe7, 0x19, 0xe1, 0xef, 0xd3, 0x33, 0xb1, 0xd0, - 0x75, 0x89, 0x87, 0x2c, 0xe7, 0xd0, 0x49, 0xb8, 0xe5, 0x5e, 0x82, 0x07, 0xeb, 0x30, 0x8c, 0xb7, - 0xaa, 0xd1, 0xcc, 0xb3, 0xc2, 0xd6, 0xe9, 0x99, 0x98, 0x5d, 0x72, 0x04, 0xa7, 0xae, 0xef, 0xdd, - 0x33, 0x6a, 0xe6, 0x9e, 0xda, 0xe9, 0xea, 0x8d, 0x7a, 0x7e, 0x43, 0x28, 0x9e, 0x9e, 0x89, 0xf9, - 0xdb, 0x72, 0x0b, 0xe9, 0xf7, 0x1f, 0x4b, 0x8c, 0x66, 0x9c, 0xcf, 0x4a, 0xec, 0xc5, 0xac, 0xc4, - 0x7e, 0x9d, 0x95, 0xd8, 0x0f, 0x57, 0x25, 0xe6, 0xe2, 0xaa, 0xc4, 0x7c, 0xbe, 0x2a, 0x31, 0xef, - 0x76, 0x06, 0x0e, 0x1d, 0x4e, 0xfb, 0xa1, 0x63, 0x94, 0x46, 0x6c, 0xa3, 0x7d, 0x44, 0x8f, 0xb0, - 0x3f, 0x52, 0x92, 0xdd, 0x7b, 0xfc, 0xcb, 0xf6, 0x8d, 0xd6, 0x60, 0x7f, 0x33, 0xda, 0x83, 0xcf, - 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0xd3, 0x7d, 0xb8, 0xe9, 0xa5, 0x05, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xc1, 0x6e, 0xd3, 0x4a, + 0x14, 0xb5, 0x9b, 0xa8, 0x4f, 0x9d, 0x3c, 0xa5, 0x89, 0x95, 0xf7, 0x30, 0x06, 0x52, 0x63, 0x81, + 0x88, 0x40, 0xb2, 0x49, 0x40, 0x48, 0x45, 0x6c, 0xec, 0x24, 0x55, 0x22, 0x68, 0x15, 0xd9, 0x49, + 0xa4, 0xb2, 0xb1, 0x26, 0xf6, 0x34, 0xb1, 0x92, 0x78, 0x2c, 0xcf, 0xc4, 0x6d, 0xff, 0x00, 0x75, + 0xc5, 0x0f, 0x74, 0xc5, 0x9e, 0xef, 0xe8, 0xb2, 0x4b, 0x56, 0x05, 0xa5, 0x0b, 0x36, 0xac, 0xf8, + 0x02, 0x64, 0x3b, 0x4e, 0xd3, 0x92, 0x46, 0x48, 0xec, 0x66, 0xe6, 0xde, 0x7b, 0xee, 0x9d, 0x73, + 0x8e, 0x2e, 0x78, 0x8c, 0x8e, 0xb0, 0x85, 0x7d, 0xa4, 0x40, 0xcf, 0xb3, 0x06, 0xd0, 0x71, 0x15, + 0x0b, 0x8f, 0xc7, 0xd8, 0x55, 0x82, 0xb2, 0x72, 0xe8, 0xf8, 0x48, 0xf6, 0x7c, 0x4c, 0x31, 0x27, + 0xcc, 0xd2, 0xe4, 0x24, 0x4d, 0x8e, 0xd3, 0xe4, 0xa0, 0x2c, 0x3c, 0xb2, 0x30, 0x19, 0x63, 0xa2, + 0x10, 0x0a, 0x87, 0x8e, 0xdb, 0x57, 0x82, 0x72, 0x0f, 0x51, 0x58, 0x4e, 0xee, 0x31, 0x82, 0x50, + 0xe8, 0xe3, 0x3e, 0x8e, 0x8e, 0x4a, 0x78, 0x9a, 0xbd, 0xde, 0xa3, 0xc8, 0xb5, 0x91, 0x3f, 0x76, + 0x5c, 0xaa, 0xc0, 0x9e, 0xe5, 0x28, 0xf4, 0xd8, 0x43, 0x24, 0x0e, 0x4a, 0x03, 0x90, 0x6f, 0x40, + 0xd7, 0x26, 0x03, 0x38, 0x44, 0xbb, 0x88, 0x42, 0x1b, 0x52, 0xc8, 0x6d, 0x83, 0xbb, 0x16, 0xc6, + 0xbe, 0xed, 0xb8, 0x90, 0x62, 0xdf, 0x3c, 0x40, 0xc8, 0xf4, 0x30, 0x1e, 0x99, 0xd0, 0xb6, 0x7d, + 0x9e, 0x15, 0xd9, 0xd2, 0x86, 0xfe, 0xff, 0x42, 0xc2, 0x0e, 0x42, 0x2d, 0x8c, 0x47, 0xaa, 0x6d, + 0xfb, 0x1c, 0x0f, 0xfe, 0x09, 0x90, 0x4f, 0x1c, 0xec, 0xf2, 0x6b, 0x51, 0x62, 0x72, 0x95, 0xbe, + 0xb3, 0x60, 0xd3, 0x18, 0x41, 0x32, 0x68, 0x41, 0x6b, 0x88, 0x68, 0x2d, 0x6c, 0xa4, 0x83, 0x8d, + 0x00, 0x8e, 0x1c, 0x3b, 0x44, 0x89, 0x80, 0x33, 0x15, 0x41, 0xbe, 0x1a, 0x57, 0x0e, 0xc7, 0x95, + 0xbb, 0x49, 0x86, 0xc6, 0x9f, 0x5d, 0x6c, 0x31, 0x3f, 0x2f, 0xb6, 0x72, 0xc7, 0x70, 0x3c, 0x7a, + 0x2d, 0xcd, 0x4b, 0x25, 0xfd, 0x0a, 0x86, 0x7b, 0x03, 0x72, 0x01, 0x1c, 0x11, 0x44, 0xcd, 0x89, + 0x67, 0x43, 0x8a, 0x4c, 0xc7, 0x8e, 0x46, 0x49, 0x6b, 0xdc, 0xf4, 0x62, 0x2b, 0xdb, 0x8d, 0x62, + 0x9d, 0x28, 0xd4, 0xac, 0xe9, 0xd9, 0x60, 0xf1, 0x6e, 0x73, 0x1a, 0x00, 0x8e, 0x7b, 0xe0, 0x43, + 0x8b, 0x86, 0x5f, 0x48, 0x89, 0x6c, 0x29, 0x5b, 0x91, 0xe4, 0x98, 0x7d, 0x39, 0x61, 0x7b, 0xc6, + 0xbe, 0xdc, 0x9c, 0x67, 0xea, 0x0b, 0x55, 0x52, 0x1b, 0x14, 0xba, 0xc4, 0xda, 0x85, 0x74, 0xe2, + 0x23, 0x7b, 0xe1, 0xb7, 0xcb, 0x26, 0x63, 0xff, 0x74, 0x32, 0xe9, 0xf3, 0x1a, 0x28, 0x18, 0x93, + 0x1e, 0xb1, 0x7c, 0xa7, 0x87, 0xfc, 0x05, 0xd8, 0x06, 0x48, 0x87, 0x8a, 0x46, 0x50, 0xd9, 0xca, + 0x4b, 0xf9, 0x76, 0x1b, 0xc9, 0xcb, 0xea, 0xdb, 0xc7, 0x1e, 0xd2, 0x23, 0x04, 0x6e, 0x1f, 0xe4, + 0x49, 0xa8, 0x90, 0xe9, 0x45, 0x51, 0x33, 0x34, 0x43, 0xc4, 0x5d, 0xa6, 0xf2, 0x6c, 0x25, 0xec, + 0x75, 0x59, 0x1b, 0x8c, 0xbe, 0x49, 0x6e, 0x28, 0xed, 0x80, 0x3b, 0x01, 0xb1, 0xcc, 0x71, 0x4c, + 0xca, 0xb5, 0x06, 0xa9, 0xa8, 0xc1, 0xf3, 0x55, 0x0d, 0x96, 0xd1, 0xd9, 0x60, 0xf4, 0x42, 0xb0, + 0xe4, 0x5d, 0x5b, 0x07, 0xe9, 0x10, 0x57, 0xfa, 0xc1, 0x82, 0xfb, 0x73, 0xef, 0x18, 0x88, 0x56, + 0x07, 0xd0, 0xed, 0xa3, 0x85, 0x99, 0x30, 0xc8, 0xcf, 0x6d, 0x33, 0x93, 0x84, 0xf0, 0xac, 0x98, + 0x2a, 0x65, 0x2a, 0xe2, 0xed, 0x2e, 0x8c, 0x05, 0xd1, 0xc4, 0x99, 0x17, 0xf9, 0x1b, 0x5e, 0x4c, + 0x80, 0x24, 0x3d, 0x17, 0x5c, 0x2f, 0x21, 0x7f, 0x69, 0xcd, 0x07, 0x00, 0xc4, 0xea, 0x40, 0x6b, + 0x48, 0xf8, 0x94, 0x98, 0x2a, 0xfd, 0xab, 0x6f, 0x44, 0x2f, 0xaa, 0x35, 0x24, 0x4f, 0xbf, 0xb2, + 0x80, 0xbf, 0x4d, 0x5f, 0x4e, 0x03, 0x4f, 0x8c, 0x8e, 0x66, 0x54, 0xf5, 0xa6, 0x56, 0xd7, 0xcd, + 0x96, 0x5a, 0x7d, 0x5b, 0x6f, 0x9b, 0x35, 0xb5, 0xad, 0x9a, 0xed, 0xfd, 0x56, 0xdd, 0xec, 0xec, + 0x19, 0xad, 0x7a, 0xb5, 0xb9, 0xd3, 0xac, 0xd7, 0x72, 0x8c, 0xf0, 0xdf, 0xc9, 0xa9, 0x98, 0xef, + 0xb8, 0xc4, 0x43, 0x96, 0x73, 0xe0, 0x24, 0xdc, 0x72, 0xaf, 0xc0, 0xc3, 0x55, 0x18, 0xc6, 0x3b, + 0xd5, 0x68, 0xe4, 0x58, 0x61, 0xf3, 0xe4, 0x54, 0xcc, 0x2c, 0x38, 0x82, 0x53, 0x57, 0xf7, 0xee, + 0x1a, 0x55, 0x73, 0x57, 0x6d, 0x77, 0xf4, 0x7a, 0x2d, 0xb7, 0x26, 0x14, 0x4e, 0x4e, 0xc5, 0xdc, + 0x4d, 0xb9, 0x85, 0xf4, 0x87, 0x4f, 0x45, 0x46, 0x33, 0xce, 0xa6, 0x45, 0xf6, 0x7c, 0x5a, 0x64, + 0xbf, 0x4d, 0x8b, 0xec, 0xc7, 0xcb, 0x22, 0x73, 0x7e, 0x59, 0x64, 0xbe, 0x5c, 0x16, 0x99, 0xf7, + 0xdb, 0x7d, 0x87, 0x0e, 0x26, 0xbd, 0xd0, 0x31, 0x4a, 0x3d, 0xb6, 0xd1, 0x1e, 0xa2, 0x87, 0xd8, + 0x1f, 0x2a, 0xc9, 0xee, 0x3d, 0xfa, 0x6d, 0xfb, 0x46, 0x6b, 0xb0, 0xb7, 0x1e, 0xed, 0xc1, 0x17, + 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x55, 0x9e, 0x0c, 0x42, 0xa5, 0x05, 0x00, 0x00, } func (m *HandshakeMetadata) Marshal() (dAtA []byte, err error) { @@ -807,8 +807,8 @@ func (m *ValidatorSetChangePacketData) Size() (n int) { n += 1 + sovWire(uint64(m.ValsetUpdateID)) } if len(m.SlashAcks) > 0 { - for _, s := range m.SlashAcks { - l = len(s) + for _, b := range m.SlashAcks { + l = len(b) n += 1 + l + sovWire(uint64(l)) } } @@ -1350,7 +1350,7 @@ func (m *ValidatorSetChangePacketData) Unmarshal(dAtA []byte) error { if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SlashAcks", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowWire @@ -1360,23 +1360,23 @@ func (m *ValidatorSetChangePacketData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthWire } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthWire } if postIndex > l { return io.ErrUnexpectedEOF } - m.SlashAcks = append(m.SlashAcks, string(dAtA[iNdEx:postIndex])) + m.SlashAcks = append(m.SlashAcks, make([]byte, postIndex-iNdEx)) + copy(m.SlashAcks[len(m.SlashAcks)-1], dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/appchain/coordinator/keeper/height.go b/x/appchain/coordinator/keeper/height.go index 8740c57b0..f54698aeb 100644 --- a/x/appchain/coordinator/keeper/height.go +++ b/x/appchain/coordinator/keeper/height.go @@ -19,3 +19,26 @@ func (k Keeper) GetHeightForChainVscID(ctx sdk.Context, chainID string, vscID ui // if store.Has(key) is false will return a height of 0 return sdk.BigEndianToUint64(store.Get(key)) } + +// SetVscIDForChain stores the vscID corresponding to a chainID +func (k Keeper) SetVscIDForChain(ctx sdk.Context, chainID string, vscID uint64) { + store := ctx.KVStore(k.storeKey) + key := types.VscIDForChainKey(chainID) + store.Set(key, sdk.Uint64ToBigEndian(vscID)) +} + +// GetVscIDForChain gets the vscID corresponding to a chainID +func (k Keeper) GetVscIDForChain(ctx sdk.Context, chainID string) uint64 { + store := ctx.KVStore(k.storeKey) + key := types.VscIDForChainKey(chainID) + return sdk.BigEndianToUint64(store.Get(key)) +} + +// IncrementVscIDForChain increments the vscID corresponding to a chainID, and +// stores/returns the new vscID +func (k Keeper) IncrementVscIDForChain(ctx sdk.Context, chainID string) uint64 { + vscID := k.GetVscIDForChain(ctx, chainID) + vscID++ + k.SetVscIDForChain(ctx, chainID, vscID) + return vscID +} diff --git a/x/appchain/coordinator/keeper/ibc_client.go b/x/appchain/coordinator/keeper/ibc_client.go index fff348c0d..4fff13073 100644 --- a/x/appchain/coordinator/keeper/ibc_client.go +++ b/x/appchain/coordinator/keeper/ibc_client.go @@ -16,6 +16,43 @@ import ( ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ) +// ActivateScheduledChains activates the scheduled chains for the given epoch. +func (k Keeper) ActivateScheduledChains(ctx sdk.Context, epochIdentifier string, epochNumber int64) { + executable := k.GetPendingSubChains(ctx, epochIdentifier, uint64(epochNumber)) + for _, subscriber := range executable.List { + cctx, writeFn, err := k.CreateClientForSubscriberInCachedCtx(ctx, subscriber) + if err != nil { + k.Logger(ctx).Error( + "error creating client for subscriber", + "chainID", subscriber.ChainID, + "error", err, + ) + _, addr := k.avsKeeper.IsAVSByChainID(ctx, subscriber.ChainID) + if err := k.avsKeeper.DeleteAVSInfo(ctx, addr); err != nil { + // should never happen + k.Logger(ctx).Error( + "subscriber AVS not deleted", + "chainID", subscriber, + "error", err, + ) + } + continue + } + // copy over the events from the cached ctx + ctx.EventManager().EmitEvents(cctx.EventManager().Events()) + writeFn() + k.Logger(ctx).Info( + "subscriber chain started", + "chainID", subscriber, + // we start at the current block and do not allow scheduling. this is the same + // as any other AVS. + "spawn time", ctx.BlockTime().UTC(), + ) + } + // clear pending queue, including those that errored out. + k.ClearPendingSubChains(ctx, epochIdentifier, uint64(epochNumber)) +} + // CreateClientForSubscriberInCachedCtx is a wrapper function around CreateClientForSubscriber. func (k Keeper) CreateClientForSubscriberInCachedCtx( ctx sdk.Context, @@ -36,7 +73,7 @@ func (k Keeper) CreateClientForSubscriber( subscriberParams := req.SubscriberParams // we always deploy a new client for the subscriber chain for our module // technically, the below can never happen but it is guarded in ICS-20 and therefore, here. - if _, found := k.GetClientForChain(ctx, chainID); found { + if _, found := k.GetClientForChain(ctx, chainID); found { // IBC related // client already exists return types.ErrDuplicateSubChain.Wrapf("chainID: %s", chainID) } @@ -46,7 +83,7 @@ func (k Keeper) CreateClientForSubscriber( clientState.ChainId = chainID // TODO(mm): Make this configurable for switchover use case clientState.LatestHeight = clienttypes.Height{ - RevisionNumber: clienttypes.ParseChainID(chainID), + RevisionNumber: clienttypes.ParseChainID(chainID), // IBC related RevisionHeight: 1, } subscriberUnbondingPeriod := subscriberParams.UnbondingPeriod @@ -70,9 +107,6 @@ func (k Keeper) CreateClientForSubscriber( } // this state can be pruned after the initial handshake occurs. k.SetSubscriberGenesis(ctx, chainID, subscriberGenesis) - k.SetSubSlashFractionDowntime(ctx, chainID, subscriberParams.SlashFractionDowntime) - k.SetSubSlashFractionDoubleSign(ctx, chainID, subscriberParams.SlashFractionDoubleSign) - k.SetSubDowntimeJailDuration(ctx, chainID, subscriberParams.DowntimeJailDuration) consensusState := ibctmtypes.NewConsensusState( ctx.BlockTime(), commitmenttypes.NewMerkleRoot([]byte(ibctmtypes.SentinelRoot)), @@ -96,6 +130,13 @@ func (k Keeper) CreateClientForSubscriber( // reverse lookup from chainID to timeout k.SetChainInitTimeout(ctx, chainID, initTimeoutPeriod) + // if the chain doesn't initialize in time, the following items will be cleared. + // same for timeout or error. + k.SetSubSlashFractionDowntime(ctx, chainID, subscriberParams.SlashFractionDowntime) + k.SetSubSlashFractionDoubleSign(ctx, chainID, subscriberParams.SlashFractionDoubleSign) + k.SetSubDowntimeJailDuration(ctx, chainID, subscriberParams.DowntimeJailDuration) + k.SetMaxValidatorsForChain(ctx, chainID, req.MaxValidators) + k.Logger(ctx).Info( "subscriber chain registered (client created)", "chainId", chainID, @@ -133,7 +174,6 @@ func (k Keeper) MakeSubscriberGenesis( params := k.GetParams(ctx) chainID := req.ChainID k.Logger(ctx).Info("Creating genesis state for subscriber chain", "chainID", chainID) - chainIDWithoutRevision := utils.ChainIDWithoutRevision(chainID) coordinatorUnbondingPeriod := k.stakingKeeper.UnbondingTime(ctx) // client state clientState := params.TemplateClient @@ -160,10 +200,9 @@ func (k Keeper) MakeSubscriberGenesis( err, chainID, ) } - // all consensus key related operations are indexed by chainIDWithoutRevision - operators, keys := k.operatorKeeper.GetActiveOperatorsForChainID(ctx, chainIDWithoutRevision) + operators, keys := k.operatorKeeper.GetActiveOperatorsForChainID(ctx, chainID) powers, err := k.operatorKeeper.GetVotePowerForChainID( - ctx, operators, chainIDWithoutRevision, + ctx, operators, chainID, ) if err != nil { k.Logger(ctx).Error("error getting vote power for chain", "error", err) @@ -181,10 +220,21 @@ func (k Keeper) MakeSubscriberGenesis( break } wrappedKey := keys[i] + validator, err := commontypes.NewSubscriberValidator( + wrappedKey.ToConsAddr(), power, wrappedKey.ToSdkKey(), + ) + if err != nil { + // cannot happen, but just in case add this check. + // simply skip the validator if it does. + continue + } validatorUpdates = append(validatorUpdates, abci.ValidatorUpdate{ PubKey: *wrappedKey.ToTmProtoKey(), Power: power, }) + // at the time of genesis, all validators are stored since there is no + // existing validator set to take a diff with. + k.SetSubscriberValidatorForChain(ctx, chainID, validator) } if len(validatorUpdates) == 0 { return nil, nil, errorsmod.Wrapf( diff --git a/x/appchain/coordinator/keeper/identifiers.go b/x/appchain/coordinator/keeper/identifiers.go index 6cb1c2b5a..dbc511162 100644 --- a/x/appchain/coordinator/keeper/identifiers.go +++ b/x/appchain/coordinator/keeper/identifiers.go @@ -31,6 +31,21 @@ func (k Keeper) DeleteClientForChain(ctx sdk.Context, chainID string) { store.Delete(types.ClientForChainKey(chainID)) } +// GetAllChainsWithClients gets all chain ids that have an ibc client id. +func (k Keeper) GetAllChainsWithClients(ctx sdk.Context) []string { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, []byte{types.ClientForChainBytePrefix}) + defer iterator.Close() + + var chains []string + for ; iterator.Valid(); iterator.Next() { + chainID := string(iterator.Key()[1:]) + chains = append(chains, chainID) + } + + return chains +} + // SetChannelForChain sets the ibc channel id for a given chain id. func (k Keeper) SetChannelForChain(ctx sdk.Context, chainID string, channelID string) { store := ctx.KVStore(k.storeKey) @@ -47,6 +62,22 @@ func (k Keeper) GetChannelForChain(ctx sdk.Context, chainID string) (string, boo return string(bytes), true } +// GetAllChainsWithChannels gets all chain ids that have an ibc channel id, on top of the +// client id. +func (k Keeper) GetAllChainsWithChannels(ctx sdk.Context) []string { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, []byte{types.ChannelForChainBytePrefix}) + defer iterator.Close() + + var chains []string + for ; iterator.Valid(); iterator.Next() { + chainID := string(iterator.Key()[1:]) + chains = append(chains, chainID) + } + + return chains +} + // SetChainForChannel sets the chain id for a given channel id. func (k Keeper) SetChainForChannel(ctx sdk.Context, channelID string, chainID string) { store := ctx.KVStore(k.storeKey) diff --git a/x/appchain/coordinator/keeper/impl_delegation_hooks.go b/x/appchain/coordinator/keeper/impl_delegation_hooks.go new file mode 100644 index 000000000..3c17bc94c --- /dev/null +++ b/x/appchain/coordinator/keeper/impl_delegation_hooks.go @@ -0,0 +1,87 @@ +package keeper + +import ( + "fmt" + + delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// DelegationHooksWrapper is the wrapper structure that implements the delegation hooks for the +// dogfood keeper. +type DelegationHooksWrapper struct { + keeper *Keeper +} + +// Interface guard +var _ delegationtypes.DelegationHooks = DelegationHooksWrapper{} + +// DelegationHooks returns the delegation hooks wrapper. It follows the "accept interfaces, +// return concretes" pattern. +func (k *Keeper) DelegationHooks() DelegationHooksWrapper { + return DelegationHooksWrapper{k} +} + +// AfterDelegation is called after a delegation is made. +func (wrapper DelegationHooksWrapper) AfterDelegation( + sdk.Context, sdk.AccAddress, +) { + // we do nothing here, since the vote power for all operators is calculated + // in the end separately. even if we knew the amount of the delegation, the + // exchange rate at the end of the epoch is unknown. +} + +// AfterUndelegationStarted is called after an undelegation is started. +func (wrapper DelegationHooksWrapper) AfterUndelegationStarted( + ctx sdk.Context, operator sdk.AccAddress, recordKey []byte, +) error { + logger := wrapper.keeper.Logger(ctx) + // given the operator, find the chainIDs for which they are (1) opted in, or (2) in the process of opting out. + // (1) simply let the undelegation mature when it matures on the subscriber chain. + // (2) the undelegation should mature when the operator's opt out matures on the subscriber chain. + // within the undelegation situation, the previous keys don't matter, because + // they will be replaced anyway. hence, we only need to check the current keys. + chainIDs := wrapper.keeper.operatorKeeper.GetChainIDsForOperator(ctx, operator) + // TODO: above only returns the chainIDs for which the operator is opted-in, but + // not those for which the operator is in the process of opting out. this will be + // resolved in the unbonding duration calculation pull request and hopefully, + // meaningfully unified. + for _, chainID := range chainIDs { + found, wrappedKey, _ := wrapper.keeper.operatorKeeper.GetOperatorConsKeyForChainID( + ctx, operator, chainID, + ) + if !found { + logger.Debug( + "operator not opted in; ignoring", + "operator", operator, + "chainID", chainID, + ) + continue + } + var nextVscID uint64 + if wrapper.keeper.operatorKeeper.IsOperatorRemovingKeyFromChainID( + ctx, operator, chainID, + ) { + nextVscID = wrapper.keeper.GetMaturityVscIDForChainIDConsAddr(ctx, chainID, wrappedKey.ToConsAddr()) + if nextVscID == 0 { + logger.Error( + "undelegation maturity epoch not set", + "operator", operator, + "chainID", chainID, + "consAddr", wrappedKey.ToConsAddr(), + "recordKey", fmt.Sprintf("%x", recordKey), + ) + // move on to the next chainID + continue + } + } else { + nextVscID = wrapper.keeper.GetVscIDForChain(ctx, chainID) + 1 + } + wrapper.keeper.AppendUndelegationToRelease(ctx, chainID, nextVscID, recordKey) + // increment the count for each such chainID + if err := wrapper.keeper.delegationKeeper.IncrementUndelegationHoldCount(ctx, recordKey); err != nil { + return err + } + } + return nil +} diff --git a/x/appchain/coordinator/keeper/impl_epochs_hooks.go b/x/appchain/coordinator/keeper/impl_epochs_hooks.go index 5ee43d80f..3e7bfcc90 100644 --- a/x/appchain/coordinator/keeper/impl_epochs_hooks.go +++ b/x/appchain/coordinator/keeper/impl_epochs_hooks.go @@ -1,7 +1,6 @@ package keeper import ( - "github.com/ExocoreNetwork/exocore/utils" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -25,50 +24,28 @@ func (k *Keeper) EpochsHooks() EpochsHooksWrapper { func (wrapper EpochsHooksWrapper) AfterEpochEnd( ctx sdk.Context, identifier string, epoch int64, ) { - // whenever an epoch ends, we should iterate over the list of pending subscriber chains - // to be activated, and then activate them. once activated, we should move them from - // the pending list to the active list. - executable := wrapper.keeper.GetPendingSubChains(ctx, identifier, uint64(epoch)) - for _, subscriber := range executable.List { - cctx, writeFn, err := wrapper.keeper.CreateClientForSubscriberInCachedCtx(ctx, subscriber) - if err != nil { - // within this block, we use the ctx and not the cctx, since the cctx's job is solely - // to guard the client creation. - // no re-attempts will be made for this subscriber - ctx.Logger().Error( - "subscriber client not created", - "chainID", subscriber, - "error", err, - ) - // clear the registered AVS. remember that this module stores - // the chainID with the revision but the AVS module stores it without. - chainID := utils.ChainIDWithoutRevision(subscriber.ChainID) - // always guaranteed to exist - _, addr := wrapper.keeper.avsKeeper.IsAVSByChainID(ctx, chainID) - if err := wrapper.keeper.avsKeeper.DeleteAVSInfo(ctx, addr); err != nil { - // should never happen - ctx.Logger().Error( - "subscriber AVS not deleted", - "chainID", subscriber, - "error", err, - ) - } - continue - } - // copy over the events from the cached ctx - ctx.EventManager().EmitEvents(cctx.EventManager().Events()) - writeFn() - wrapper.keeper.Logger(ctx).Info( - "subscriber chain started", - "chainID", subscriber, - // we start at the current block and do not allow scheduling. this is the same - // as any other AVS. - "spawn time", ctx.BlockTime().UTC(), - ) - } - // delete those that were executed (including those that failed) - wrapper.keeper.ClearPendingSubChains(ctx, identifier, uint64(epoch)) - // next, we iterate over the active list and queue the validator set update for them. + // start any chains that are due to start, by creating their genesis state. + wrapper.keeper.ActivateScheduledChains(ctx, identifier, epoch) + + // slashing is applied during the epoch, so we don't have to do anything about that here. + // note that slashing should flow through to this keeper via a hook and the impact + // should be applied to the validator set. first, it should freeze the oracle round, + // then, it should calculate the USD power, then, it should find the new x/dogfood + // validator set and lastly, it should find the new appchain validator set for the + // impacted chains. + + // next, we remove any chains that didn't respond in time: either to the validator + // set update or to the initialization protocol. the removal is undertaken before + // generating the validator set update to save resources. + wrapper.keeper.RemoveTimedoutSubscribers(ctx, identifier, epoch) + + // last, we iterate over the active list and queue the validator set update for them. + // interchain-security does this in EndBlock, but we can do it now because our validator + // set is independent of the coordinator chain's. + wrapper.keeper.QueueValidatorUpdatesForEpochID(ctx, identifier, epoch) + // send the queued validator updates. the `epoch` is used for scheduling the VSC timeouts + // and nothing else. it has no bearing on the actual validator set. + wrapper.keeper.SendQueuedValidatorUpdates(ctx, epoch) } // BeforeEpochStart is called before an epoch starts. diff --git a/x/appchain/coordinator/keeper/impl_operator_hooks.go b/x/appchain/coordinator/keeper/impl_operator_hooks.go new file mode 100644 index 000000000..b6dd53f91 --- /dev/null +++ b/x/appchain/coordinator/keeper/impl_operator_hooks.go @@ -0,0 +1,73 @@ +package keeper + +import ( + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// OperatorHooksWrapper is the wrapper structure that implements the operator hooks for the +// coordinator keeper. +type OperatorHooksWrapper struct { + keeper *Keeper +} + +// Interface guards +var _ operatortypes.OperatorHooks = OperatorHooksWrapper{} + +func (k *Keeper) OperatorHooks() OperatorHooksWrapper { + return OperatorHooksWrapper{k} +} + +// AfterOperatorKeySet is the implementation of the operator hooks. +func (h OperatorHooksWrapper) AfterOperatorKeySet( + sdk.Context, sdk.AccAddress, string, exocoretypes.WrappedConsKey, +) { + // no-op +} + +// AfterOperatorKeyReplaced is the implementation of the operator hooks. +func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( + ctx sdk.Context, operatorAccAddress sdk.AccAddress, + oldKey exocoretypes.WrappedConsKey, newKey exocoretypes.WrappedConsKey, + chainID string, +) { + consAddr := oldKey.ToConsAddr() + _, found := h.keeper.GetSubscriberValidatorForChain(ctx, chainID, consAddr) + if found { + // schedule this consensus address for pruning at the maturity of the packet containing this vscID that will + // go out at the end of this epoch. + nextVscID := h.keeper.GetVscIDForChain(ctx, chainID) + 1 + h.keeper.AppendConsAddrToPrune(ctx, chainID, nextVscID, consAddr) + // reverse lookup + h.keeper.SetMaturityVscIDForChainIDConsAddr(ctx, chainID, consAddr, nextVscID) + } else { + // delete the reverse lookup of old cons addr + chain id -> operator addr, since it was never an active + // validator. + h.keeper.operatorKeeper.DeleteOperatorAddressForChainIDAndConsAddr( + ctx, chainID, consAddr, + ) + } +} + +// AfterOperatorKeyRemovalInitiated is the implementation of the operator hooks. +func (h OperatorHooksWrapper) AfterOperatorKeyRemovalInitiated( + ctx sdk.Context, operator sdk.AccAddress, chainID string, key exocoretypes.WrappedConsKey, +) { + consAddr := key.ToConsAddr() + _, found := h.keeper.GetSubscriberValidatorForChain(ctx, chainID, consAddr) + if found { + // schedule this consensus address for pruning at the maturity of the packet containing this vscID that will + // go out at the end of this epoch. + nextVscID := h.keeper.GetVscIDForChain(ctx, chainID) + 1 + h.keeper.AppendConsAddrToPrune(ctx, chainID, nextVscID, consAddr) + // reverse lookup + h.keeper.SetMaturityVscIDForChainIDConsAddr(ctx, chainID, consAddr, nextVscID) + } else { + // delete the reverse lookup of old cons addr + chain id -> operator addr, since it was never an active + // validator. + h.keeper.operatorKeeper.DeleteOperatorAddressForChainIDAndConsAddr( + ctx, chainID, consAddr, + ) + } +} diff --git a/x/appchain/coordinator/keeper/keeper.go b/x/appchain/coordinator/keeper/keeper.go index 354bd1f35..d783c2267 100644 --- a/x/appchain/coordinator/keeper/keeper.go +++ b/x/appchain/coordinator/keeper/keeper.go @@ -20,6 +20,7 @@ type Keeper struct { epochsKeeper types.EpochsKeeper operatorKeeper types.OperatorKeeper stakingKeeper types.StakingKeeper + delegationKeeper types.DelegationKeeper clientKeeper commontypes.ClientKeeper portKeeper commontypes.PortKeeper scopedKeeper commontypes.ScopedKeeper @@ -36,6 +37,7 @@ func NewKeeper( epochsKeeper types.EpochsKeeper, operatorKeeper types.OperatorKeeper, stakingKeeper types.StakingKeeper, + delegationKeeper types.DelegationKeeper, clientKeeper commontypes.ClientKeeper, portKeeper commontypes.PortKeeper, scopedKeeper commontypes.ScopedKeeper, @@ -50,6 +52,7 @@ func NewKeeper( epochsKeeper: epochsKeeper, operatorKeeper: operatorKeeper, stakingKeeper: stakingKeeper, + delegationKeeper: delegationKeeper, clientKeeper: clientKeeper, portKeeper: portKeeper, scopedKeeper: scopedKeeper, diff --git a/x/appchain/coordinator/keeper/register.go b/x/appchain/coordinator/keeper/register.go index 1cab3bb7a..a1ad73057 100644 --- a/x/appchain/coordinator/keeper/register.go +++ b/x/appchain/coordinator/keeper/register.go @@ -39,7 +39,7 @@ func (k Keeper) AddSubscriberChain( UnbondingPeriod: uint64(unbondingEpochs), // estimated MinSelfDelegation: req.MinSelfDelegationUsd, EpochIdentifier: req.EpochIdentifier, - ChainID: req.ChainID, + ChainID: req.ChainID, // use the one with the version intentionally // TODO: remove the owner role and make it controllable by subscriber-governance AvsOwnerAddress: []string{req.FromAddress}, }); err != nil { diff --git a/x/appchain/coordinator/keeper/relay.go b/x/appchain/coordinator/keeper/relay.go index 4ee8bdb0b..c93d5389a 100644 --- a/x/appchain/coordinator/keeper/relay.go +++ b/x/appchain/coordinator/keeper/relay.go @@ -159,7 +159,7 @@ func (k Keeper) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet) err } // stop chain and release unbondings k.Logger(ctx).Info( - "packet timeout, removing the consumer", + "packet timeout, removing the subscriber", "chainID", chainID, ) return k.StopSubscriberChain(ctx, chainID, false) diff --git a/x/appchain/coordinator/keeper/slash.go b/x/appchain/coordinator/keeper/slash.go index 7caaf572b..f5525ff72 100644 --- a/x/appchain/coordinator/keeper/slash.go +++ b/x/appchain/coordinator/keeper/slash.go @@ -3,7 +3,6 @@ package keeper import ( "time" - "github.com/ExocoreNetwork/exocore/utils" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" types "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -55,8 +54,7 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data commonty // #nosec G703 // already validated slashProportionDecimal, _ := sdk.NewDecFromStr(slashProportion) jailDuration := k.GetSubDowntimeJailDuration(ctx, chainID) - chainIDWithoutRevision := utils.ChainIDWithoutRevision(chainID) - _, avsAddress := k.avsKeeper.IsAVSByChainID(ctx, chainIDWithoutRevision) + _, avsAddress := k.avsKeeper.IsAVSByChainID(ctx, chainID) // the slashing hook should trigger a validator set update for all affected AVSs. since the `chainID` is one of them // we should make sure we are well set up for that update. we will include an ack of the slash packet in the next // validator set update; record that here. @@ -88,7 +86,18 @@ func (k Keeper) GetSlashAcks(ctx sdk.Context, chainID string) types.ConsensusAdd func (k Keeper) SetSlashAcks(ctx sdk.Context, chainID string, consAddresses types.ConsensusAddresses) { store := ctx.KVStore(k.storeKey) key := types.SlashAcksKey(chainID) - store.Set(key, k.cdc.MustMarshal(&consAddresses)) + if len(consAddresses.List) == 0 { + store.Delete(key) + } else { + store.Set(key, k.cdc.MustMarshal(&consAddresses)) + } +} + +// ConsumeSlashAcks consumes the slashing acknowledgments for a chain, to be sent in the next validator set update. +func (k Keeper) ConsumeSlashAcks(ctx sdk.Context, chainID string) [][]byte { + ret := k.GetSlashAcks(ctx, chainID) + k.SetSlashAcks(ctx, chainID, types.ConsensusAddresses{}) + return ret.List } // TODO: these fields should be in the AVS keeper instead. diff --git a/x/appchain/coordinator/keeper/timeout.go b/x/appchain/coordinator/keeper/timeout.go index 53157388c..f6da051c1 100644 --- a/x/appchain/coordinator/keeper/timeout.go +++ b/x/appchain/coordinator/keeper/timeout.go @@ -84,3 +84,90 @@ func (k Keeper) DeleteChainInitTimeout(ctx sdk.Context, chainID string) { store := ctx.KVStore(k.storeKey) store.Delete(types.ChainInitTimeoutKey(chainID)) } + +// SetVscTimeout stores the epoch by the end of which a response to a VSC must be received. +func (k Keeper) SetVscTimeout( + ctx sdk.Context, chainID string, vscID uint64, timeout epochstypes.Epoch, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.VscTimeoutKey(chainID, vscID), k.cdc.MustMarshal(&timeout)) +} + +// GetVscTimeout returns the epoch by the end of which a response to a VSC must be received. +func (k Keeper) GetVscTimeout( + ctx sdk.Context, chainID string, vscID uint64, +) (timeout epochstypes.Epoch, found bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.VscTimeoutKey(chainID, vscID)) + if bz == nil { + return timeout, false + } + k.cdc.MustUnmarshal(bz, &timeout) + return timeout, true +} + +// GetFirstVscTimeout returns the first epoch by the end of which a response to a VSC must be received. +func (k Keeper) GetFirstVscTimeout( + ctx sdk.Context, chainID string, +) (timeout epochstypes.Epoch, found bool) { + store := ctx.KVStore(k.storeKey) + partialKey := append( + []byte{types.VscTimeoutBytePrefix}, + []byte(chainID)..., + ) + iterator := sdk.KVStorePrefixIterator(store, partialKey) + defer iterator.Close() + + if iterator.Valid() { + _, _, err := types.ParseVscTimeoutKey(iterator.Key()) + if err != nil { + return timeout, false + } + bz := iterator.Value() + k.cdc.MustUnmarshal(bz, &timeout) + return timeout, true + } + return timeout, false +} + +// DeleteVscTimeout deletes the epoch by the end of which a response to a VSC must be received. +func (k Keeper) DeleteVscTimeout(ctx sdk.Context, chainID string, vscID uint64) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.VscTimeoutKey(chainID, vscID)) +} + +// RemoveTimedoutSubscribers removes the subscribers that are timed out at the end of the current epoch. +// epochNumber passed is the current epoch number, which is ending. +func (k Keeper) RemoveTimedoutSubscribers(ctx sdk.Context, epochIdentifier string, epochNumber int64) { + // init timeout chains + epoch := epochstypes.NewEpoch(uint64(epochNumber), epochIdentifier) + chains := k.GetChainsToInitTimeout(ctx, epoch) + for _, chainID := range chains.List { + if err := k.StopSubscriberChain(ctx, chainID, true); err != nil { + k.Logger(ctx).Error("failed to stop subscriber chain", "chainID", chainID, "error", err) + continue + } + k.DeleteChainInitTimeout(ctx, chainID) // prune + } + // vsc timeout chains + vscChains := k.GetAllChainsWithChannels(ctx) + for _, chainID := range vscChains { + timeout, found := k.GetFirstVscTimeout(ctx, chainID) + if !found { + continue + } + if timeout.EpochIdentifier == epochIdentifier && timeout.EpochNumber <= uint64(epochNumber) { + k.Logger(ctx).Info( + "VSC timed out, removing subscriber", + "chainID", chainID, + "epochIdentifier", timeout.EpochIdentifier, + "epochNumber", timeout.EpochNumber, + ) + if err := k.StopSubscriberChain(ctx, chainID, true); err != nil { + k.Logger(ctx).Error("failed to stop subscriber chain", "chainID", chainID, "error", err) + continue + } + k.DeleteVscTimeout(ctx, chainID, timeout.EpochNumber) // prune + } + } +} diff --git a/x/appchain/coordinator/keeper/unbonding.go b/x/appchain/coordinator/keeper/unbonding.go new file mode 100644 index 000000000..239cb2a24 --- /dev/null +++ b/x/appchain/coordinator/keeper/unbonding.go @@ -0,0 +1,108 @@ +package keeper + +import ( + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// AppendConsAddrToPrune appends a consensus address to the list of consensus addresses +// that will be pruned when the validator set update containing the given vscID is matured +// by the chainID. +func (k Keeper) AppendConsAddrToPrune( + ctx sdk.Context, chainID string, vscID uint64, consKey sdk.ConsAddress, +) { + prev := k.GetConsAddrsToPrune(ctx, chainID, vscID) + prev.List = append(prev.List, consKey) + k.SetConsAddrsToPrune(ctx, chainID, vscID, prev) +} + +// GetConsAddrsToPrune returns the list of consensus addresses that will be pruned when the +// validator set update containing the given vscID is matured by the chainID. +func (k Keeper) GetConsAddrsToPrune( + ctx sdk.Context, chainID string, vscID uint64, +) (res types.ConsensusAddresses) { + store := ctx.KVStore(k.storeKey) + key := types.ConsAddrsToPruneKey(chainID, vscID) + k.cdc.MustUnmarshal(store.Get(key), &res) + return res +} + +// SetConsAddrsToPrune sets the list of consensus addresses that will be pruned when the +// validator set update containing the given vscID is matured by the chainID. +func (k Keeper) SetConsAddrsToPrune( + ctx sdk.Context, chainID string, vscID uint64, addrs types.ConsensusAddresses, +) { + store := ctx.KVStore(k.storeKey) + key := types.ConsAddrsToPruneKey(chainID, vscID) + if len(addrs.List) == 0 { + store.Delete(key) + return + } + store.Set(key, k.cdc.MustMarshal(&addrs)) +} + +// SetMaturityVscIDForChainIDConsAddr sets the vscID for the given chainID and consensus address. +// When the vscID matures on the chainID, the consensus address will be pruned. +func (k Keeper) SetMaturityVscIDForChainIDConsAddr( + ctx sdk.Context, chainID string, consAddr sdk.ConsAddress, vscID uint64, +) { + store := ctx.KVStore(k.storeKey) + key := types.MaturityVscIDForChainIDConsAddrKey(chainID, consAddr) + store.Set(key, sdk.Uint64ToBigEndian(vscID)) +} + +// GetMaturityVscIDForChainIDConsAddr returns the vscID for the given chainID and consensus address. +// The vscID is used to prune the consensus address when the vscID matures on the chainID. +func (k Keeper) GetMaturityVscIDForChainIDConsAddr( + ctx sdk.Context, chainID string, consAddr sdk.ConsAddress, +) uint64 { + store := ctx.KVStore(k.storeKey) + key := types.MaturityVscIDForChainIDConsAddrKey(chainID, consAddr) + bz := store.Get(key) + return sdk.BigEndianToUint64(bz) +} + +// DeleteMaturityVscIDForChainIDConsAddr deletes the vscID for the given chainID and consensus address. +// The vscID is used to prune the consensus address when the vscID matures on the chainID. +func (k Keeper) DeleteMaturityVscIDForChainIDConsAddr( + ctx sdk.Context, chainID string, consAddr sdk.ConsAddress, +) { + store := ctx.KVStore(k.storeKey) + key := types.MaturityVscIDForChainIDConsAddrKey(chainID, consAddr) + store.Delete(key) +} + +// AppendUndelegationToRelease appends an undelegation record to the list of undelegations to release +// when the validator set update containing the given vscID is matured by the chainID. +func (k Keeper) AppendUndelegationToRelease( + ctx sdk.Context, chainID string, vscID uint64, recordKey []byte, +) { + prev := k.GetUndelegationsToRelease(ctx, chainID, vscID) + prev.List = append(prev.List, recordKey) + k.SetUndelegationsToRelease(ctx, chainID, vscID, prev) +} + +// GetUndelegationsToRelease returns the list of undelegations to release when the validator set update +// containing the given vscID is matured by the chainID. +func (k Keeper) GetUndelegationsToRelease( + ctx sdk.Context, chainID string, vscID uint64, +) (res types.UndelegationRecordKeys) { + store := ctx.KVStore(k.storeKey) + key := types.UndelegationsToReleaseKey(chainID, vscID) + k.cdc.MustUnmarshal(store.Get(key), &res) + return res +} + +// SetUndelegationsToRelease sets the list of undelegations to release when the validator set update +// containing the given vscID is matured by the chainID. +func (k Keeper) SetUndelegationsToRelease( + ctx sdk.Context, chainID string, vscID uint64, keys types.UndelegationRecordKeys, +) { + store := ctx.KVStore(k.storeKey) + key := types.UndelegationsToReleaseKey(chainID, vscID) + if len(keys.List) == 0 { + store.Delete(key) + return + } + store.Set(key, k.cdc.MustMarshal(&keys)) +} diff --git a/x/appchain/coordinator/keeper/validator_set_update.go b/x/appchain/coordinator/keeper/validator_set_update.go new file mode 100644 index 000000000..e802984fb --- /dev/null +++ b/x/appchain/coordinator/keeper/validator_set_update.go @@ -0,0 +1,257 @@ +package keeper + +import ( + "fmt" + + exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + "github.com/ExocoreNetwork/exocore/utils" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" +) + +// QueueValidatorUpdatesForEpochID queues all the validator updates to be sent to the subscriber +// chains at the end of the epoch. After this function, call SendQueuedValidatorUpdates, which +// will actually send the updates. +func (k Keeper) QueueValidatorUpdatesForEpochID( + ctx sdk.Context, epochID string, epochNumber int64, +) { + // Get all the chains that need to be updated + chainIDs := k.avsKeeper.GetEpochEndChainIDs(ctx, epochID, epochNumber) + for _, chainID := range chainIDs { + cctx, writeCache, err := k.QueueValidatorUpdatesForChainIDInCachedCtx(ctx, chainID) + if err != nil { + k.Logger(ctx).Error( + "error queuing validator updates for chain", + "chainID", chainID, + "error", err, + ) + continue + } + // copy over the events from the cached ctx + ctx.EventManager().EmitEvents(cctx.EventManager().Events()) + writeCache() + } +} + +// QueueValidatorUpdatesForChainIDInCachedCtx is a wrapper function around QueueValidatorUpdatesForChainID. +func (k Keeper) QueueValidatorUpdatesForChainIDInCachedCtx( + ctx sdk.Context, chainID string, +) (cctx sdk.Context, writeCache func(), err error) { + cctx, writeCache = ctx.CacheContext() + err = k.QueueValidatorUpdatesForChainID(cctx, chainID) + return +} + +// QueueValidatorUpdatesForChainID queues all the validator updates to be sent to the subscriber, saving the +// updates as individual validators as well. +func (k Keeper) QueueValidatorUpdatesForChainID( + ctx sdk.Context, chainID string, +) error { + // Get the current validator set for the chain, which is sorted + // by the consensus address (bytes). This sorting is okay to use + prevList := k.GetAllSubscriberValidatorsForChain(ctx, chainID) + // to check whether the new set has a changed vote power, convert to map. + prevMap := make(map[string]int64, len(prevList)) + for _, val := range prevList { + // we are okay to use ConsAddress here even though the bech32 prefix + // is different, because we don't print the address. + prevMap[sdk.ConsAddress(val.ConsAddress).String()] = val.Power + } + operators, keys := k.operatorKeeper.GetActiveOperatorsForChainID(ctx, chainID) + powers, err := k.operatorKeeper.GetVotePowerForChainID( + ctx, operators, chainID, + ) + if err != nil { + k.Logger(ctx).Error( + "error getting vote power for chain", + "chainID", chainID, + "error", err, + ) + // skip this chain, if consecutive failures are reported, it will eventually be + // timed out and then dropped. + return err + } + operators, keys, powers = utils.SortByPower(operators, keys, powers) + maxVals := k.GetMaxValidatorsForChain(ctx, chainID) + // double the capacity assuming that all validators are removed and an entirely new + // set of validators is added. + validatorUpdates := make([]abci.ValidatorUpdate, 0, maxVals*2) + for i := range operators { + if i >= int(maxVals) { + break + } + power := powers[i] + if power < 1 { + break + } + wrappedKey := keys[i] + addressString := wrappedKey.ToConsAddr().String() + prevPower, found := prevMap[addressString] + if found { + if prevPower != power { + validatorUpdates = append(validatorUpdates, abci.ValidatorUpdate{ + PubKey: *wrappedKey.ToTmProtoKey(), + Power: power, + }) + } + delete(prevMap, addressString) + validator, err := commontypes.NewSubscriberValidator( + wrappedKey.ToConsAddr(), power, wrappedKey.ToSdkKey(), + ) + if err != nil { + // should never happen, but just in case. + // don't skip the chain though, instead, skip the validator. + continue + } + k.SetSubscriberValidatorForChain(ctx, chainID, validator) + } else { + // new key, add it to the list. + validatorUpdates = append(validatorUpdates, abci.ValidatorUpdate{ + PubKey: *wrappedKey.ToTmProtoKey(), + Power: power, + }) + validator, err := commontypes.NewSubscriberValidator( + wrappedKey.ToConsAddr(), power, wrappedKey.ToSdkKey(), + ) + if err != nil { + // should never happen, but just in case. + // don't skip the chain though, instead, skip the validator. + continue + } + k.SetSubscriberValidatorForChain(ctx, chainID, validator) + } + } + // if there is any element in the prevList, which is still in prevMap, that element + // needs to have a vote power of 0 queued. + for _, validator := range prevList { + pubKey, err := validator.ConsPubKey() + if err != nil { + k.Logger(ctx).Error( + "error deserializing consensus public key", + "chainID", chainID, + "error", err, + ) + return err + } + wrappedKey := exocoretypes.NewWrappedConsKeyFromSdkKey(pubKey) + // alternatively, the below could be replaced by wrappedKey.ToConsAddr(), but + // since we generated this address when saving it, we can use it directly. + consAddress := sdk.ConsAddress(validator.ConsAddress) + if _, found := prevMap[consAddress.String()]; found { + validatorUpdates = append(validatorUpdates, abci.ValidatorUpdate{ + PubKey: *wrappedKey.ToTmProtoKey(), + Power: 0, + }) + k.DeleteSubscriberValidatorForChain(ctx, chainID, consAddress) + } + } + // default is 0 for the subscriber genesis. any updates will start with 1. + // increment gets the value of 0, increments it to 1, stores it and returns it. + vscID := k.IncrementVscIDForChain(ctx, chainID) + data := commontypes.NewVscPacketData( + validatorUpdates, vscID, k.ConsumeSlashAcks(ctx, chainID), + ) + k.AppendPendingVscPacket(ctx, chainID, data) + return nil +} + +// SendQueuedValidatorUpdates sends the queued validator set updates to the subscriber chains. +// It only sends them if a client + channel for that chain are set up. Otherwise, no action +// is taken. Since it is called immediately after queuing the updates, it is guaranteed that +// only the updates from the queue (or prior) are sent. In other words, there is no possibility +// for updates from a different epoch will be sent. Hence, we simply iterate over all (active) +// chains. +func (k Keeper) SendQueuedValidatorUpdates(ctx sdk.Context, epochNumber int64) { + chainIDs := k.GetAllChainsWithChannels(ctx) + for _, chainID := range chainIDs { + // a channel is guaranteed to exist. + channelID, _ := k.GetChannelForChain(ctx, chainID) + packets := k.GetPendingVscPackets(ctx, chainID) + k.SendVscPacketsToChain(ctx, chainID, channelID, packets.List, epochNumber) + } +} + +// SendVscPacketsToChain sends the validator set change packets to the subscriber chain. +func (k Keeper) SendVscPacketsToChain( + ctx sdk.Context, chainID string, channelID string, + packets []commontypes.ValidatorSetChangePacketData, + epochNumber int64, +) { + params := k.GetParams(ctx) + for i := range packets { + data := packets[i] + // send packet over IBC + err := commontypes.SendIBCPacket( + ctx, + k.scopedKeeper, + k.channelKeeper, + channelID, // source channel id + commontypes.CoordinatorPortID, // source port id + commontypes.ModuleCdc.MustMarshalJSON(&data), // packet data + params.IBCTimeoutPeriod, + ) + if err != nil { + if clienttypes.ErrClientNotActive.Is(err) { + // IBC client is expired! + // leave the packet data stored to be sent once the client is upgraded + // the client cannot expire during iteration (in the middle of a block) + k.Logger(ctx).Info( + "IBC client is expired, cannot send VSC, leaving packet data stored:", + "chainID", chainID, + "vscID", data.ValsetUpdateID, + ) + return + } + // Not able to send packet over IBC! + k.Logger(ctx).Error( + "cannot send VSC, removing subscriber", + "chainID", chainID, + "vscID", data.ValsetUpdateID, + "err", err.Error(), + ) + // If this happens, most likely the subscriber is malicious; remove it + err := k.StopSubscriberChain(ctx, chainID, true) + if err != nil { + panic(fmt.Errorf("subscriber chain failed to stop: %w", err)) + } + return + } + // even when the epoch identifier is `minute` and that of the `timeoutPeriod` is hour + // the latter is used. this is because the `timeout` runs on a different schedule. + timeoutPeriod := params.VSCTimeoutPeriod + timeoutPeriod.EpochNumber += uint64(epochNumber) + 1 // 1 extra for the ended epoch + k.SetVscTimeout(ctx, chainID, data.ValsetUpdateID, timeoutPeriod) + } + k.SetPendingVscPackets(ctx, chainID, types.ValidatorSetChangePackets{}) +} + +// AppendPendingVscPacket appends a validator set change packet to the pending list, indexed by the chainID. +func (k Keeper) AppendPendingVscPacket(ctx sdk.Context, chainID string, data commontypes.ValidatorSetChangePacketData) { + prev := k.GetPendingVscPackets(ctx, chainID) + prev.List = append(prev.List, data) + k.SetPendingVscPackets(ctx, chainID, prev) +} + +// GetPendingVscPackets gets the pending validator set change packets for a chain. +func (k Keeper) GetPendingVscPackets(ctx sdk.Context, chainID string) types.ValidatorSetChangePackets { + store := ctx.KVStore(k.storeKey) + var data types.ValidatorSetChangePackets + key := types.ChainIDToVscPacketsKey(chainID) + value := store.Get(key) + k.cdc.MustUnmarshal(value, &data) + return data +} + +// SetPendingVscPackets sets the pending validator set change packets for a chain. +func (k Keeper) SetPendingVscPackets(ctx sdk.Context, chainID string, data types.ValidatorSetChangePackets) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIDToVscPacketsKey(chainID) + if len(data.List) == 0 { + store.Delete(key) + } else { + store.Set(key, k.cdc.MustMarshal(&data)) + } +} diff --git a/x/appchain/coordinator/keeper/validators.go b/x/appchain/coordinator/keeper/validators.go new file mode 100644 index 000000000..7ad2d903f --- /dev/null +++ b/x/appchain/coordinator/keeper/validators.go @@ -0,0 +1,83 @@ +package keeper + +import ( + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SetSubscriberValidatorForChain sets the subscriber validator for a chain. +// Storing this historical information allows us to minimize the number/size of +// validator set updates sent to the subscriber by skipping the keys for which +// there is no change in vote power. +func (k Keeper) SetSubscriberValidatorForChain( + ctx sdk.Context, chainID string, validator commontypes.SubscriberValidator, +) { + store := ctx.KVStore(k.storeKey) + key := types.SubscriberValidatorKey(chainID, validator.ConsAddress) + bz := k.cdc.MustMarshal(&validator) + store.Set(key, bz) +} + +// GetSubscriberValidatorForChain gets the subscriber validator for a chain. +func (k Keeper) GetSubscriberValidatorForChain( + ctx sdk.Context, chainID string, consAddress []byte, +) (validator commontypes.SubscriberValidator, found bool) { + store := ctx.KVStore(k.storeKey) + key := types.SubscriberValidatorKey(chainID, consAddress) + if !store.Has(key) { + return validator, false + } + bz := store.Get(key) + k.cdc.MustUnmarshal(bz, &validator) + return validator, true +} + +// GetAllSubscriberValidatorsForChain gets all subscriber validators for a chain, ordered +// by the consensus address bytes. +func (k Keeper) GetAllSubscriberValidatorsForChain( + ctx sdk.Context, chainID string, +) (validators []commontypes.SubscriberValidator) { + store := ctx.KVStore(k.storeKey) + partialKey := types.SubscriberValidatorKey(chainID, nil) + iterator := sdk.KVStorePrefixIterator(store, partialKey) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var validator commontypes.SubscriberValidator + k.cdc.MustUnmarshal(iterator.Value(), &validator) + validators = append(validators, validator) + } + + return validators +} + +// DeleteSubscriberValidatorForChain deletes the subscriber validator for a chain, given +// the consensus address. +func (k Keeper) DeleteSubscriberValidatorForChain( + ctx sdk.Context, chainID string, consAddress []byte, +) { + store := ctx.KVStore(k.storeKey) + key := types.SubscriberValidatorKey(chainID, consAddress) + store.Delete(key) +} + +// SetMaxValidatorsForChain sets the maximum number of validators for a chain. +func (k Keeper) SetMaxValidatorsForChain( + ctx sdk.Context, chainID string, maxValidators uint32, +) { + store := ctx.KVStore(k.storeKey) + key := types.MaxValidatorsKey(chainID) + store.Set(key, sdk.Uint64ToBigEndian(uint64(maxValidators))) +} + +// GetMaxValidatorsForChain gets the maximum number of validators for a chain. +func (k Keeper) GetMaxValidatorsForChain( + ctx sdk.Context, chainID string, +) uint32 { + store := ctx.KVStore(k.storeKey) + key := types.MaxValidatorsKey(chainID) + bz := store.Get(key) + // #nosec G115 // we stored it, we trust it + return uint32(sdk.BigEndianToUint64(bz)) +} diff --git a/x/appchain/coordinator/types/coordinator.pb.go b/x/appchain/coordinator/types/coordinator.pb.go index 433406ead..c986f2f56 100644 --- a/x/appchain/coordinator/types/coordinator.pb.go +++ b/x/appchain/coordinator/types/coordinator.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + types "github.com/ExocoreNetwork/exocore/x/appchain/common/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -162,10 +163,104 @@ func (m *ConsensusAddresses) GetList() [][]byte { return nil } +// ValidatorSetChangePackets is a helper structure to store a list of packets +type ValidatorSetChangePackets struct { + // list is the list of packets to be sent to the subscriber chain. + List []types.ValidatorSetChangePacketData `protobuf:"bytes,1,rep,name=list,proto3" json:"list"` +} + +func (m *ValidatorSetChangePackets) Reset() { *m = ValidatorSetChangePackets{} } +func (m *ValidatorSetChangePackets) String() string { return proto.CompactTextString(m) } +func (*ValidatorSetChangePackets) ProtoMessage() {} +func (*ValidatorSetChangePackets) Descriptor() ([]byte, []int) { + return fileDescriptor_fb7bb04617dc0e61, []int{3} +} +func (m *ValidatorSetChangePackets) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatorSetChangePackets) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ValidatorSetChangePackets.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ValidatorSetChangePackets) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatorSetChangePackets.Merge(m, src) +} +func (m *ValidatorSetChangePackets) XXX_Size() int { + return m.Size() +} +func (m *ValidatorSetChangePackets) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatorSetChangePackets.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatorSetChangePackets proto.InternalMessageInfo + +func (m *ValidatorSetChangePackets) GetList() []types.ValidatorSetChangePacketData { + if m != nil { + return m.List + } + return nil +} + +// UndelegationRecordKeys is a collection of undelegation record keys. +type UndelegationRecordKeys struct { + // list is the list of undelegation record keys. + List [][]byte `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` +} + +func (m *UndelegationRecordKeys) Reset() { *m = UndelegationRecordKeys{} } +func (m *UndelegationRecordKeys) String() string { return proto.CompactTextString(m) } +func (*UndelegationRecordKeys) ProtoMessage() {} +func (*UndelegationRecordKeys) Descriptor() ([]byte, []int) { + return fileDescriptor_fb7bb04617dc0e61, []int{4} +} +func (m *UndelegationRecordKeys) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UndelegationRecordKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UndelegationRecordKeys.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UndelegationRecordKeys) XXX_Merge(src proto.Message) { + xxx_messageInfo_UndelegationRecordKeys.Merge(m, src) +} +func (m *UndelegationRecordKeys) XXX_Size() int { + return m.Size() +} +func (m *UndelegationRecordKeys) XXX_DiscardUnknown() { + xxx_messageInfo_UndelegationRecordKeys.DiscardUnknown(m) +} + +var xxx_messageInfo_UndelegationRecordKeys proto.InternalMessageInfo + +func (m *UndelegationRecordKeys) GetList() [][]byte { + if m != nil { + return m.List + } + return nil +} + func init() { proto.RegisterType((*PendingSubscriberChainRequests)(nil), "exocore.appchain.coordinator.v1.PendingSubscriberChainRequests") proto.RegisterType((*ChainIDs)(nil), "exocore.appchain.coordinator.v1.ChainIDs") proto.RegisterType((*ConsensusAddresses)(nil), "exocore.appchain.coordinator.v1.ConsensusAddresses") + proto.RegisterType((*ValidatorSetChangePackets)(nil), "exocore.appchain.coordinator.v1.ValidatorSetChangePackets") + proto.RegisterType((*UndelegationRecordKeys)(nil), "exocore.appchain.coordinator.v1.UndelegationRecordKeys") } func init() { @@ -173,25 +268,29 @@ func init() { } var fileDescriptor_fb7bb04617dc0e61 = []byte{ - // 278 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x90, 0x31, 0x4f, 0xc3, 0x30, - 0x10, 0x85, 0x13, 0x51, 0x21, 0x08, 0x4c, 0x11, 0x03, 0xea, 0xe0, 0xa2, 0x4e, 0x9d, 0x6c, 0x05, - 0x76, 0x10, 0x2d, 0x0c, 0x2c, 0x08, 0x85, 0x05, 0xd8, 0x12, 0xe7, 0xe4, 0x5a, 0x80, 0x2f, 0xf8, - 0x9c, 0x12, 0xc4, 0x9f, 0xe0, 0x67, 0x75, 0xec, 0xc8, 0x84, 0x50, 0xf2, 0x47, 0x50, 0x93, 0x56, - 0x0a, 0x52, 0xa5, 0x6e, 0x67, 0xdf, 0x7b, 0xdf, 0x3d, 0xbd, 0x20, 0x82, 0x12, 0x25, 0x5a, 0x10, - 0x49, 0x9e, 0xcb, 0x69, 0xa2, 0x8d, 0x90, 0x88, 0x36, 0xd3, 0x26, 0x71, 0x68, 0xc5, 0x2c, 0xea, - 0x3e, 0x79, 0x6e, 0xd1, 0x61, 0x38, 0x58, 0x59, 0xf8, 0xda, 0xc2, 0xbb, 0x9a, 0x59, 0xd4, 0x1f, - 0x6d, 0x63, 0xba, 0xb2, 0x45, 0xf5, 0x8f, 0x14, 0x2a, 0x6c, 0x46, 0xb1, 0x9c, 0xda, 0xdf, 0xe1, - 0x67, 0xc0, 0xee, 0xc0, 0x64, 0xda, 0xa8, 0xfb, 0x22, 0x25, 0x69, 0x75, 0x0a, 0x76, 0xb2, 0xe4, - 0xc4, 0xf0, 0x56, 0x00, 0x39, 0x0a, 0x1f, 0x83, 0xde, 0x8b, 0x26, 0x77, 0xec, 0x9f, 0xec, 0x8c, - 0x0e, 0x4e, 0x2f, 0xf8, 0x96, 0x44, 0x3c, 0x06, 0xa5, 0xc9, 0x81, 0xdd, 0xcc, 0x1b, 0xf7, 0xe6, - 0x3f, 0x03, 0x2f, 0x6e, 0x90, 0x43, 0x16, 0xec, 0x35, 0xbb, 0x9b, 0x2b, 0x0a, 0xc3, 0xce, 0x99, - 0xfd, 0xd5, 0x7e, 0x14, 0x84, 0x13, 0x34, 0x04, 0x86, 0x0a, 0xba, 0xcc, 0x32, 0x0b, 0x44, 0xf0, - 0x5f, 0x79, 0xd8, 0x2a, 0xc7, 0x0f, 0xf3, 0x8a, 0xf9, 0x8b, 0x8a, 0xf9, 0xbf, 0x15, 0xf3, 0xbf, - 0x6a, 0xe6, 0x2d, 0x6a, 0xe6, 0x7d, 0xd7, 0xcc, 0x7b, 0x3a, 0x57, 0xda, 0x4d, 0x8b, 0x94, 0x4b, - 0x7c, 0x15, 0xd7, 0x6d, 0xf4, 0x5b, 0x70, 0xef, 0x68, 0x9f, 0xc5, 0xba, 0xba, 0x72, 0x73, 0x79, - 0xee, 0x23, 0x07, 0x4a, 0x77, 0x9b, 0x9e, 0xce, 0xfe, 0x02, 0x00, 0x00, 0xff, 0xff, 0x12, 0xc7, - 0x0f, 0x6b, 0xbd, 0x01, 0x00, 0x00, + // 352 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0xcf, 0x4a, 0xc3, 0x40, + 0x10, 0x87, 0x13, 0x2c, 0xa2, 0xd1, 0x53, 0x10, 0xd1, 0x1e, 0xb6, 0x52, 0x10, 0x7a, 0x90, 0x84, + 0xea, 0xc5, 0x93, 0x62, 0x5b, 0x0f, 0x22, 0x48, 0x49, 0x51, 0xd4, 0xdb, 0x26, 0x19, 0xb6, 0x4b, + 0xdb, 0x9d, 0xb8, 0xbb, 0xe9, 0x1f, 0x7c, 0x09, 0x1f, 0xab, 0xc7, 0x1e, 0x3d, 0x89, 0xb4, 0x2f, + 0x22, 0x9b, 0xa6, 0xd0, 0x42, 0xa4, 0xb7, 0x4d, 0xf6, 0x37, 0xdf, 0x7c, 0xb3, 0xe3, 0xd4, 0x61, + 0x8c, 0x11, 0x4a, 0xf0, 0x69, 0x92, 0x44, 0x5d, 0xca, 0x85, 0x1f, 0x21, 0xca, 0x98, 0x0b, 0xaa, + 0x51, 0xfa, 0xc3, 0xfa, 0xfa, 0xa7, 0x97, 0x48, 0xd4, 0xe8, 0x56, 0xf2, 0x12, 0x6f, 0x55, 0xe2, + 0xad, 0x67, 0x86, 0xf5, 0xf2, 0x79, 0x01, 0x73, 0x30, 0x40, 0x61, 0x70, 0x23, 0x2e, 0x61, 0xc9, + 0x29, 0xd7, 0xb6, 0xb5, 0xd6, 0xe3, 0x3c, 0x79, 0xc4, 0x90, 0x61, 0x76, 0xf4, 0xcd, 0x69, 0xf9, + 0xb7, 0xfa, 0xe9, 0x90, 0x36, 0x88, 0x98, 0x0b, 0xd6, 0x49, 0x43, 0x15, 0x49, 0x1e, 0x82, 0x6c, + 0x1a, 0x4e, 0x00, 0x1f, 0x29, 0x28, 0xad, 0xdc, 0x37, 0xa7, 0xd4, 0xe7, 0x4a, 0x9f, 0xd8, 0x67, + 0x3b, 0xb5, 0x83, 0xcb, 0x5b, 0x6f, 0x8b, 0xb8, 0x17, 0x00, 0xe3, 0x4a, 0x83, 0x2c, 0xe6, 0x35, + 0x4a, 0xd3, 0x9f, 0x8a, 0x15, 0x64, 0xc8, 0x2a, 0x71, 0xf6, 0xb2, 0xbb, 0x87, 0x96, 0x72, 0xdd, + 0xb5, 0x36, 0xfb, 0xf9, 0x7d, 0xcd, 0x71, 0x9b, 0x28, 0x14, 0x08, 0x95, 0xaa, 0xbb, 0x38, 0x96, + 0xa0, 0x14, 0x6c, 0x26, 0x0f, 0xf3, 0x24, 0x3a, 0xa7, 0x2f, 0xb4, 0xcf, 0x63, 0x23, 0xd1, 0x01, + 0xdd, 0xec, 0x52, 0xc1, 0xa0, 0x4d, 0xa3, 0x1e, 0x68, 0xe5, 0x06, 0x1b, 0x13, 0x5c, 0x17, 0x4d, + 0x60, 0x5e, 0xd6, 0xc8, 0xff, 0x07, 0x69, 0x51, 0x4d, 0x37, 0xd4, 0x2f, 0x9c, 0xe3, 0x67, 0x11, + 0x43, 0x1f, 0x18, 0xd5, 0x1c, 0x45, 0x00, 0x11, 0xca, 0xf8, 0x11, 0x26, 0x85, 0x7a, 0x8d, 0xd7, + 0xe9, 0x9c, 0xd8, 0xb3, 0x39, 0xb1, 0x7f, 0xe7, 0xc4, 0xfe, 0x5a, 0x10, 0x6b, 0xb6, 0x20, 0xd6, + 0xf7, 0x82, 0x58, 0xef, 0x37, 0x8c, 0xeb, 0x6e, 0x1a, 0x1a, 0x05, 0xff, 0x7e, 0xe9, 0xf5, 0x04, + 0x7a, 0x84, 0xb2, 0xe7, 0xaf, 0x36, 0x3b, 0x2e, 0xde, 0xad, 0x9e, 0x24, 0xa0, 0xc2, 0xdd, 0x6c, + 0x8d, 0x57, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9c, 0xfc, 0xdf, 0xf1, 0x83, 0x02, 0x00, 0x00, } func (m *PendingSubscriberChainRequests) Marshal() (dAtA []byte, err error) { @@ -295,6 +394,75 @@ func (m *ConsensusAddresses) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ValidatorSetChangePackets) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatorSetChangePackets) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatorSetChangePackets) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.List) > 0 { + for iNdEx := len(m.List) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.List[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCoordinator(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *UndelegationRecordKeys) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UndelegationRecordKeys) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UndelegationRecordKeys) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.List) > 0 { + for iNdEx := len(m.List) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.List[iNdEx]) + copy(dAtA[i:], m.List[iNdEx]) + i = encodeVarintCoordinator(dAtA, i, uint64(len(m.List[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintCoordinator(dAtA []byte, offset int, v uint64) int { offset -= sovCoordinator(v) base := offset @@ -351,6 +519,36 @@ func (m *ConsensusAddresses) Size() (n int) { return n } +func (m *ValidatorSetChangePackets) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.List) > 0 { + for _, e := range m.List { + l = e.Size() + n += 1 + l + sovCoordinator(uint64(l)) + } + } + return n +} + +func (m *UndelegationRecordKeys) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.List) > 0 { + for _, b := range m.List { + l = len(b) + n += 1 + l + sovCoordinator(uint64(l)) + } + } + return n +} + func sovCoordinator(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -605,6 +803,172 @@ func (m *ConsensusAddresses) Unmarshal(dAtA []byte) error { } return nil } +func (m *ValidatorSetChangePackets) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatorSetChangePackets: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatorSetChangePackets: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field List", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCoordinator + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCoordinator + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.List = append(m.List, types.ValidatorSetChangePacketData{}) + if err := m.List[len(m.List)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCoordinator(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCoordinator + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UndelegationRecordKeys) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UndelegationRecordKeys: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UndelegationRecordKeys: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field List", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCoordinator + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCoordinator + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCoordinator + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.List = append(m.List, make([]byte, postIndex-iNdEx)) + copy(m.List[len(m.List)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCoordinator(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCoordinator + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipCoordinator(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/appchain/coordinator/types/expected_keepers.go b/x/appchain/coordinator/types/expected_keepers.go index 9316adb6b..c737704df 100644 --- a/x/appchain/coordinator/types/expected_keepers.go +++ b/x/appchain/coordinator/types/expected_keepers.go @@ -16,6 +16,7 @@ type AVSKeeper interface { RegisterAVSWithChainID(sdk.Context, *avstypes.AVSRegisterOrDeregisterParams) (common.Address, error) IsAVSByChainID(sdk.Context, string) (bool, common.Address) DeleteAVSInfo(sdk.Context, common.Address) error + GetEpochEndChainIDs(sdk.Context, string, int64) []string } // EpochsKeeper represents the expected keeper interface for the epochs module. @@ -30,6 +31,8 @@ type StakingKeeper interface { // OperatorKeeper represents the expected keeper interface for the operator module. type OperatorKeeper interface { + GetOperatorConsKeyForChainID(sdk.Context, sdk.AccAddress, string) (bool, types.WrappedConsKey, error) + IsOperatorRemovingKeyFromChainID(sdk.Context, sdk.AccAddress, string) bool GetActiveOperatorsForChainID(sdk.Context, string) ([]sdk.AccAddress, []types.WrappedConsKey) GetVotePowerForChainID(sdk.Context, []sdk.AccAddress, string) ([]int64, error) GetOperatorAddressForChainIDAndConsAddr( @@ -47,4 +50,11 @@ type OperatorKeeper interface { height uint64, fraction sdk.Dec, infraction stakingtypes.Infraction, jailDuration time.Duration, ) + GetChainIDsForOperator(sdk.Context, sdk.AccAddress) []string +} + +// DelegationKeeper represents the expected keeper interface for the delegation module. +type DelegationKeeper interface { + IncrementUndelegationHoldCount(sdk.Context, []byte) error + DecrementUndelegationHoldCount(sdk.Context, []byte) error } diff --git a/x/appchain/coordinator/types/keys.go b/x/appchain/coordinator/types/keys.go index 925271c11..6ffbb1cd3 100644 --- a/x/appchain/coordinator/types/keys.go +++ b/x/appchain/coordinator/types/keys.go @@ -1,6 +1,9 @@ package types import ( + "bytes" + fmt "fmt" + "github.com/ExocoreNetwork/exocore/utils" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -62,6 +65,22 @@ const ( HeightToChainVscIDBytePrefix // SlashAcksBytePrefix is the prefix for the slashing acks key SlashAcksBytePrefix + // SubscriberValidatorBytePrefix is the prefix for the subscriber validator key + SubscriberValidatorBytePrefix + // MaxValidatorsBytePrefix is the prefix for the max validators key + MaxValidatorsBytePrefix + // VscIDForChainBytePrefix is the prefix to go from chainID to vscID + VscIDForChainBytePrefix + // ChainIDToVscPacketsBytePrefix is the prefix for the vsc packets key for a chainID + ChainIDToVscPacketsBytePrefix + // VscTimeoutBytePrefix is the prefix for the vsc timeout key + VscTimeoutBytePrefix + // ConsKeysToPruneBytePrefix is the prefix for the consensus keys to prune key + ConsKeysToPruneBytePrefix + // MaturityVscIDForChainIDConsAddrBytePrefix is the prefix for the vsc id for chain cons addr key + MaturityVscIDForChainIDConsAddrBytePrefix + // UndelegationsToReleaseBytePrefix is the prefix for the undelegations to release key + UndelegationsToReleaseBytePrefix ) // ParamsKey returns the key under which the coordinator module's parameters are stored. @@ -111,10 +130,10 @@ func SubscriberGenesisKey(chainID string) []byte { // InitTimeoutEpochKey returns the key under which the list of chains which will timeout (if not // initialized by then) at the beginning of the epoch is stored. func InitTimeoutEpochKey(epoch epochstypes.Epoch) []byte { - return utils.AppendMany( - []byte{InitTimeoutBytePrefix}, - []byte(epoch.EpochIdentifier), - sdk.Uint64ToBigEndian(epoch.EpochNumber), + return utils.AppendMany( // safe to do, since... + []byte{InitTimeoutBytePrefix}, // size 1 + []byte(epoch.EpochIdentifier), // size unknown + sdk.Uint64ToBigEndian(epoch.EpochNumber), // size 8 ) } @@ -161,3 +180,87 @@ func SlashAcksKey(chainID string) []byte { []byte(chainID)..., ) } + +// SubscriberValidatorKey returns the key for the subscriber validator +// It is used to store the validator object for the subscriber chain, indexed by +// prefix + len(chainID) + chainID + consensusAddr +func SubscriberValidatorKey(chainID string, consensusAddr []byte) []byte { + return utils.AppendMany( + []byte{SubscriberValidatorBytePrefix}, + utils.ChainIDWithLenKey(chainID), + consensusAddr, + ) +} + +// MaxValidatorsKey returns the key for the max validators +func MaxValidatorsKey(chainID string) []byte { + return append([]byte{MaxValidatorsBytePrefix}, []byte(chainID)...) +} + +// VscIDForChainKey returns the key for the vsc id to chain +func VscIDForChainKey(chainID string) []byte { + return append([]byte{VscIDForChainBytePrefix}, []byte(chainID)...) +} + +// ChainIDToVscPacketsKey returns the key for the vsc packets for a chain +func ChainIDToVscPacketsKey(chainID string) []byte { + return append([]byte{ChainIDToVscPacketsBytePrefix}, []byte(chainID)...) +} + +// VscTimeoutKey returns the key for the vsc timeout +func VscTimeoutKey(chainID string, vscID uint64) []byte { + return utils.AppendMany( + []byte{VscTimeoutBytePrefix}, + []byte(chainID), + sdk.Uint64ToBigEndian(vscID), + ) +} + +// ParseVscTimeoutKey parses the chainID and vscID from the key of the format +// prefix + chainID + vscID +func ParseVscTimeoutKey(bz []byte) (chainID string, vscID uint64, err error) { + return ParseChainIDAndUintIDKey(VscTimeoutBytePrefix, bz) +} + +// ParseChainIDAndUintIDKey returns the chain ID and uint ID for a ChainIdAndUintId key +func ParseChainIDAndUintIDKey(prefix byte, bz []byte) (string, uint64, error) { + expectedPrefix := []byte{prefix} + prefixL := len(expectedPrefix) + if len(bz) < prefixL+8 { // for uint64 + return "", 0, fmt.Errorf("invalid key length; expected at least %d bytes, got: %d", prefixL+8, len(bz)) + } + if prefix := bz[:prefixL]; !bytes.Equal(prefix, expectedPrefix) { + return "", 0, fmt.Errorf("invalid prefix; expected: %X, got: %X", expectedPrefix, prefix) + } + uintID := sdk.BigEndianToUint64(bz[len(bz)-8:]) + chainID := string(bz[prefixL : len(bz)-8]) + return chainID, uintID, nil +} + +// ConsAddrsToPruneKey returns the key for the consensus keys to prune, indexed by the +// chainID + vscID as the key. +func ConsAddrsToPruneKey(chainID string, vscID uint64) []byte { + return utils.AppendMany( + []byte{ConsKeysToPruneBytePrefix}, + []byte(chainID), + sdk.Uint64ToBigEndian(vscID), + ) +} + +// MaturityVscIDForChainIDConsAddrKey returns the key for the vsc id for chain cons addr +func MaturityVscIDForChainIDConsAddrKey(chainID string, consAddr sdk.ConsAddress) []byte { + return utils.AppendMany( + []byte{MaturityVscIDForChainIDConsAddrBytePrefix}, + []byte(chainID), + consAddr.Bytes(), + ) +} + +// UndelegationsToReleaseKey returns the key for the undelegations to release +func UndelegationsToReleaseKey(chainID string, vscID uint64) []byte { + return utils.AppendMany( + []byte{UndelegationsToReleaseBytePrefix}, + []byte(chainID), + sdk.Uint64ToBigEndian(vscID), + ) +} diff --git a/x/appchain/subscriber/keeper/genesis.go b/x/appchain/subscriber/keeper/genesis.go index e5afd41c4..b9497e22a 100644 --- a/x/appchain/subscriber/keeper/genesis.go +++ b/x/appchain/subscriber/keeper/genesis.go @@ -20,7 +20,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, gs types.GenesisState) []abci.Valid // around switchover is not yet fully designed. panic("switchover use case not supported yet") } - k.SetParams(ctx, gs.Params) + k.SetSubscriberParams(ctx, gs.Params) k.SetPort(ctx, commontypes.SubscriberPortID) // only bind to the port if the capability keeper hasn't done so already if !k.IsBound(ctx, commontypes.SubscriberPortID) { @@ -43,6 +43,6 @@ func (k Keeper) InitGenesis(ctx sdk.Context, gs types.GenesisState) []abci.Valid func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { return &types.GenesisState{ - Params: k.GetParams(ctx), + Params: k.GetSubscriberParams(ctx), } } diff --git a/x/appchain/subscriber/keeper/grpc_query.go b/x/appchain/subscriber/keeper/grpc_query.go index 70954845d..e0db3a20b 100644 --- a/x/appchain/subscriber/keeper/grpc_query.go +++ b/x/appchain/subscriber/keeper/grpc_query.go @@ -21,5 +21,5 @@ func (k Keeper) QueryParams( } ctx := sdk.UnwrapSDKContext(goCtx) - return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil + return &types.QueryParamsResponse{Params: k.GetSubscriberParams(ctx)}, nil } diff --git a/x/appchain/subscriber/keeper/impl_sdk.go b/x/appchain/subscriber/keeper/impl_sdk.go new file mode 100644 index 000000000..6f925e0ed --- /dev/null +++ b/x/appchain/subscriber/keeper/impl_sdk.go @@ -0,0 +1,162 @@ +package keeper + +import ( + "time" + + "cosmossdk.io/math" + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" +) + +// This file contains the implementations of the Comos SDK level expected keepers +// for the subscriber's Keeper. This allows us to use the subscriber's keeper +// as an input into the slashing and the evidence modules. These modules then +// handle the slashing calls so that we do not have to implement them separately. +// Note that the subscriber chain is deemed to be trusted because the coordinator +// will not verify the evidence any further. An upgrade overcoming this has just +// been merged into interchain-security, which we can pick up later. +// https://github.com/orgs/cosmos/projects/28/views/11?pane=issue&itemId=21248976 + +// interface guards +var _ slashingtypes.StakingKeeper = Keeper{} +var _ evidencetypes.StakingKeeper = Keeper{} +var _ clienttypes.StakingKeeper = Keeper{} +var _ genutiltypes.StakingKeeper = Keeper{} + +// GetParams returns an empty staking params. It is used by the interfaces above, but the returned +// value is never examined. +func (k Keeper) GetParams(ctx sdk.Context) stakingtypes.Params { + return stakingtypes.Params{} +} + +// This function is used by the slashing module to store the validator public keys into the +// state. These were previously verified in the evidence module but have since been removed. +func (k Keeper) IterateValidators(sdk.Context, + func(index int64, validator stakingtypes.ValidatorI) (stop bool)) { + // no op +} + +// simply unimplemented because it is not needed +func (k Keeper) Validator(ctx sdk.Context, addr sdk.ValAddress) stakingtypes.ValidatorI { + panic("unimplemented on this keeper") +} + +// ValidatorByConsAddr returns an empty validator +func (k Keeper) ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI { + /* + NOTE: + + The evidence module will call this function when it handles equivocation evidence. + The returned value must not be nil and must not have an UNBONDED validator status, + or evidence will reject it. + + Also, the slashing module will call this function when it observes downtime. In that case + the only requirement on the returned value is that it isn't null. + */ + return stakingtypes.Validator{} +} + +// Calls SlashWithInfractionReason with Infraction_INFRACTION_UNSPECIFIED. +// It should not be called anywhere. +func (k Keeper) Slash( + ctx sdk.Context, + addr sdk.ConsAddress, + infractionHeight, power int64, + slashFactor sdk.Dec, +) math.Int { + return k.SlashWithInfractionReason( + ctx, addr, infractionHeight, + power, slashFactor, + stakingtypes.Infraction_INFRACTION_UNSPECIFIED, + ) +} + +// Slash queues a slashing request for the the coordinator chain. +// All queued slashing requests will be cleared in EndBlock. +// Called by slashing keeper. +func (k Keeper) SlashWithInfractionReason( + ctx sdk.Context, + addr sdk.ConsAddress, + infractionHeight, power int64, + slashFactor sdk.Dec, + infraction stakingtypes.Infraction, +) math.Int { + if infraction == stakingtypes.Infraction_INFRACTION_UNSPECIFIED { + return math.ZeroInt() + } + + // get VSC ID for infraction height + vscID := k.GetValsetUpdateIDForHeight(ctx, infractionHeight) + + k.Logger(ctx).Debug( + "vscID obtained from mapped infraction height", + "infraction height", infractionHeight, + "vscID", vscID, + ) + + // this is the most important step in the function + // everything else is just here to implement StakingKeeper interface + // IBC packets are created from slash data and sent to the coordinator during EndBlock + k.QueueSlashPacket( + ctx, + abci.Validator{ + Address: addr.Bytes(), + Power: power, + }, + vscID, infraction, + ) + + // Only return to comply with the interface restriction + return math.ZeroInt() +} + +// Unimplemented because jailing happens on the coordinator chain. +func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) {} + +// Same as above. +func (k Keeper) Unjail(sdk.Context, sdk.ConsAddress) {} + +// Cannot delegate on this chain, and this should not be called by either the subscriber or the +// coordinator. +func (k Keeper) Delegation( + sdk.Context, + sdk.AccAddress, + sdk.ValAddress, +) stakingtypes.DelegationI { + panic("unimplemented on this keeper") +} + +// Unused by evidence and slashing. However, I have set it up to report the correct number +// anyway. Alternatively we could panic here as well. +func (k Keeper) MaxValidators(ctx sdk.Context) uint32 { + return k.GetParams(ctx).MaxValidators +} + +// In interchain-security, this does seem to have been implemented. However, I did not see +// the validators being persisted in the first place so I just returned an empty list. +// I also did not see this being used anywhere within the slashing module. +func (k Keeper) GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) { + return []stakingtypes.Validator{} +} + +// IsJailed returns the outstanding slashing flag for the given validator adddress +func (k Keeper) IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool { + return k.HasOutstandingDowntime(ctx, addr) +} + +func (k Keeper) UnbondingTime(ctx sdk.Context) time.Duration { + return k.GetUnbondingPeriod(ctx) +} + +// implement interface method needed for x/genutil in sdk v47 +// returns empty updates and err +func (k Keeper) ApplyAndReturnValidatorSetUpdates( + sdk.Context, +) (updates []abci.ValidatorUpdate, err error) { + return +} diff --git a/x/appchain/subscriber/keeper/keeper.go b/x/appchain/subscriber/keeper/keeper.go index 1bb985d95..0c330a7dd 100644 --- a/x/appchain/subscriber/keeper/keeper.go +++ b/x/appchain/subscriber/keeper/keeper.go @@ -15,36 +15,47 @@ import ( ) type Keeper struct { - cdc codec.BinaryCodec - storeKey storetypes.StoreKey - scopedKeeper commontypes.ScopedKeeper - portKeeper commontypes.PortKeeper - clientKeeper commontypes.ClientKeeper - connectionKeeper commontypes.ConnectionKeeper - channelKeeper commontypes.ChannelKeeper - ibcCoreKeeper commontypes.IBCCoreKeeper + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + accountKeeper commontypes.AccountKeeper + bankKeeper commontypes.BankKeeper + scopedKeeper commontypes.ScopedKeeper + portKeeper commontypes.PortKeeper + clientKeeper commontypes.ClientKeeper + connectionKeeper commontypes.ConnectionKeeper + channelKeeper commontypes.ChannelKeeper + ibcCoreKeeper commontypes.IBCCoreKeeper + ibcTransferKeeper commontypes.IBCTransferKeeper + feeCollectorName string } // NewKeeper creates a new subscriber keeper. func NewKeeper( cdc codec.BinaryCodec, storeKey storetypes.StoreKey, + accountKeeper commontypes.AccountKeeper, + bankKeeper commontypes.BankKeeper, scopedKeeper commontypes.ScopedKeeper, portKeeper commontypes.PortKeeper, clientKeeper commontypes.ClientKeeper, connectionKeeper commontypes.ConnectionKeeper, channelKeeper commontypes.ChannelKeeper, ibcCoreKeeper commontypes.IBCCoreKeeper, + ibcTransferKeeper commontypes.IBCTransferKeeper, + feeCollectorName string, ) Keeper { return Keeper{ - cdc: cdc, - storeKey: storeKey, - scopedKeeper: scopedKeeper, - portKeeper: portKeeper, - clientKeeper: clientKeeper, - connectionKeeper: connectionKeeper, - channelKeeper: channelKeeper, - ibcCoreKeeper: ibcCoreKeeper, + cdc: cdc, + storeKey: storeKey, + accountKeeper: accountKeeper, + scopedKeeper: scopedKeeper, + portKeeper: portKeeper, + clientKeeper: clientKeeper, + connectionKeeper: connectionKeeper, + channelKeeper: channelKeeper, + ibcCoreKeeper: ibcCoreKeeper, + ibcTransferKeeper: ibcTransferKeeper, + feeCollectorName: feeCollectorName, } } @@ -92,15 +103,15 @@ func (k Keeper) ClaimCapability( // at the end of this block. func (k Keeper) GetPendingChanges( ctx sdk.Context, -) (*commontypes.ValidatorSetChangePacketData, bool) { +) *commontypes.ValidatorSetChangePacketData { store := ctx.KVStore(k.storeKey) bz := store.Get(types.PendingChangesKey()) if bz == nil { - return nil, false + return nil } var res *commontypes.ValidatorSetChangePacketData k.cdc.MustUnmarshal(bz, res) - return res, true + return res } // SetPendingChanges sets the pending validator set changes that will be applied @@ -114,6 +125,13 @@ func (k Keeper) SetPendingChanges( store.Set(types.PendingChangesKey(), bz) } +// DeletePendingChanges deletes the pending validator set changes that will be applied +// at the end of this block. +func (k Keeper) DeletePendingChanges(ctx sdk.Context) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.PendingChangesKey()) +} + // SetPacketMaturityTime sets the maturity time for a given received VSC packet id func (k Keeper) SetPacketMaturityTime( ctx sdk.Context, vscID uint64, maturityTime time.Time, @@ -124,11 +142,39 @@ func (k Keeper) SetPacketMaturityTime( MaturityTime: maturityTime, } store.Set( - types.PacketMaturityTimeKey(vscID, maturityTime), + types.PacketMaturityTimeKey(maturityTime, vscID), k.cdc.MustMarshal(maturingVSCPacket), ) } +// GetElapsedVscPackets returns all VSC packets that have matured as of the current block time +func (k Keeper) GetElapsedVscPackets(ctx sdk.Context) []types.MaturingVSCPacket { + store := ctx.KVStore(k.storeKey) + prefix := []byte{types.PacketMaturityTimeBytePrefix} + iterator := sdk.KVStorePrefixIterator(store, prefix) + defer iterator.Close() + + var ret []types.MaturingVSCPacket + for ; iterator.Valid(); iterator.Next() { + var packet types.MaturingVSCPacket + k.cdc.MustUnmarshal(iterator.Value(), &packet) + // since these are stored in order of maturity time, we can break early + if ctx.BlockTime().Before(packet.MaturityTime) { + break + } + ret = append(ret, packet) + } + return ret +} + +// DeletePacketMaturityTime deletes the maturity time for a given received VSC packet id +func (k Keeper) DeletePacketMaturityTime( + ctx sdk.Context, vscID uint64, maturityTime time.Time, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.PacketMaturityTimeKey(maturityTime, vscID)) +} + // DeleteOutstandingDowntime deletes the outstanding downtime flag for the given validator // consensus address func (k Keeper) DeleteOutstandingDowntime( @@ -137,3 +183,19 @@ func (k Keeper) DeleteOutstandingDowntime( store := ctx.KVStore(k.storeKey) store.Delete(types.OutstandingDowntimeKey(consAddress)) } + +// SetOutstandingDowntime sets the outstanding downtime flag for the given validator +func (k Keeper) SetOutstandingDowntime( + ctx sdk.Context, consAddress sdk.ConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.OutstandingDowntimeKey(consAddress), []byte{1}) +} + +// HasOutstandingDowntime returns true if the given validator has an outstanding downtime +func (k Keeper) HasOutstandingDowntime( + ctx sdk.Context, consAddress sdk.ConsAddress, +) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.OutstandingDowntimeKey(consAddress)) +} diff --git a/x/appchain/subscriber/keeper/params.go b/x/appchain/subscriber/keeper/params.go index 7480eb7dd..65484717f 100644 --- a/x/appchain/subscriber/keeper/params.go +++ b/x/appchain/subscriber/keeper/params.go @@ -8,16 +8,16 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// SetParams sets the appchain coordinator parameters. +// SetSubscriberParams sets the appchain subscriber parameters. // The caller must ensure that the params are valid. -func (k Keeper) SetParams(ctx sdk.Context, params commontypes.SubscriberParams) { +func (k Keeper) SetSubscriberParams(ctx sdk.Context, params commontypes.SubscriberParams) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(¶ms) store.Set(types.ParamsKey(), bz) } -// GetParams gets the appchain coordinator parameters. -func (k Keeper) GetParams(ctx sdk.Context) (res commontypes.SubscriberParams) { +// GetSubscriberParams gets the appchain subscriber parameters. +func (k Keeper) GetSubscriberParams(ctx sdk.Context) (res commontypes.SubscriberParams) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ParamsKey()) k.cdc.MustUnmarshal(bz, &res) @@ -29,24 +29,24 @@ func (k Keeper) GetParams(ctx sdk.Context) (res commontypes.SubscriberParams) { // This is because the genesis is generated by the coordinator chain based mostly // on the registration transaction. func (k Keeper) SetCoordinatorFeePoolAddrStr(ctx sdk.Context, addrStr string) { - params := k.GetParams(ctx) + params := k.GetSubscriberParams(ctx) params.CoordinatorFeePoolAddrStr = addrStr - k.SetParams(ctx, params) + k.SetSubscriberParams(ctx, params) } // GetDistributionTransmissionChannel gets the distribution transmission channel. func (k Keeper) GetDistributionTransmissionChannel(ctx sdk.Context) string { - return k.GetParams(ctx).DistributionTransmissionChannel + return k.GetSubscriberParams(ctx).DistributionTransmissionChannel } // SetDistributionTransmissionChannel sets the distribution transmission channel. func (k Keeper) SetDistributionTransmissionChannel(ctx sdk.Context, channel string) { - params := k.GetParams(ctx) + params := k.GetSubscriberParams(ctx) params.DistributionTransmissionChannel = channel - k.SetParams(ctx, params) + k.SetSubscriberParams(ctx, params) } // GetUnbondingPeriod gets the unbonding period. func (k Keeper) GetUnbondingPeriod(ctx sdk.Context) time.Duration { - return k.GetParams(ctx).UnbondingPeriod + return k.GetSubscriberParams(ctx).UnbondingPeriod } diff --git a/x/appchain/subscriber/keeper/queue.go b/x/appchain/subscriber/keeper/queue.go new file mode 100644 index 000000000..d339466fb --- /dev/null +++ b/x/appchain/subscriber/keeper/queue.go @@ -0,0 +1,91 @@ +package keeper + +import ( + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// getAndIncrementPendingPacketsIdx returns the current pending packets index and increments it. +func (k Keeper) getAndIncrementPendingPacketsIdx(ctx sdk.Context) (toReturn uint64) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.PendingPacketsIndexKey()) + if bz != nil { + toReturn = sdk.BigEndianToUint64(bz) + } + toStore := toReturn + 1 + store.Set(types.PendingPacketsIndexKey(), sdk.Uint64ToBigEndian(toStore)) + return toReturn +} + +// AppendPendingPacket appends a packet to the pending packets queue, indexed by the current index. +func (k Keeper) AppendPendingPacket( + ctx sdk.Context, + packetType commontypes.SubscriberPacketDataType, + packet commontypes.WrappedSubscriberPacketData, +) { + store := ctx.KVStore(k.storeKey) + // it is appended to a key with idx value, and not an overall array + idx := k.getAndIncrementPendingPacketsIdx(ctx) + key := types.PendingDataPacketsKey(idx) + wrapped := commontypes.NewSubscriberPacketData(packetType, packet) + bz := k.cdc.MustMarshal(&wrapped) + store.Set(key, bz) +} + +// GetPendingPackets returns ALL the pending packets from the store without indexes. +func (k Keeper) GetPendingPackets(ctx sdk.Context) []commontypes.SubscriberPacketData { + ppWithIndexes := k.GetAllPendingPacketsWithIdx(ctx) + var ppList []commontypes.SubscriberPacketData + for _, ppWithIndex := range ppWithIndexes { + ppList = append(ppList, ppWithIndex.SubscriberPacketData) + } + return ppList +} + +// GetAllPendingPacketsWithIdx returns ALL pending packet data from the store +// with indexes relevant to the pending packets queue. +func (k Keeper) GetAllPendingPacketsWithIdx(ctx sdk.Context) []types.SubscriberPacketDataWithIdx { + packets := []types.SubscriberPacketDataWithIdx{} + store := ctx.KVStore(k.storeKey) + // Note: PendingDataPacketsBytePrefix is the correct prefix, NOT PendingDataPacketsByteKey. + // See consistency with PendingDataPacketsKey(). + iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingDataPacketsBytePrefix}) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var packet commontypes.SubscriberPacketData + bz := iterator.Value() + k.cdc.MustUnmarshal(bz, &packet) + packetWithIdx := types.SubscriberPacketDataWithIdx{ + SubscriberPacketData: packet, + // index stored in key after prefix, see PendingDataPacketsKey() + Idx: sdk.BigEndianToUint64(iterator.Key()[1:]), + } + packets = append(packets, packetWithIdx) + } + return packets +} + +// DeletePendingDataPackets deletes pending data packets with given indexes +func (k Keeper) DeletePendingDataPackets(ctx sdk.Context, idxs ...uint64) { + store := ctx.KVStore(k.storeKey) + for _, idx := range idxs { + store.Delete(types.PendingDataPacketsKey(idx)) + } +} + +// DeleteAllPendingDataPackets deletes all pending data packets from the store. +func (k Keeper) DeleteAllPendingDataPackets(ctx sdk.Context) { + store := ctx.KVStore(k.storeKey) + // Note: PendingDataPacketsBytePrefix is the correct prefix, NOT PendingDataPacketsByteKey. + // See consistency with PendingDataPacketsKey(). + iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingDataPacketsBytePrefix}) + keysToDel := [][]byte{} + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + for _, key := range keysToDel { + store.Delete(key) + } +} diff --git a/x/appchain/subscriber/keeper/relay.go b/x/appchain/subscriber/keeper/relay.go index d2c035015..e387ff36d 100644 --- a/x/appchain/subscriber/keeper/relay.go +++ b/x/appchain/subscriber/keeper/relay.go @@ -2,13 +2,17 @@ package keeper import ( "fmt" + "strconv" errorsmod "cosmossdk.io/errors" "github.com/ExocoreNetwork/exocore/utils" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" ) @@ -49,7 +53,7 @@ func (k Keeper) OnRecvVSCPacket( // the changes are received within blocks, but can only be forwarded to // Tendermint during EndBlock. hence, get the changes received so far, append to them // and save them back - currentChanges, _ := k.GetPendingChanges(ctx) + currentChanges := k.GetPendingChanges(ctx) pendingChanges := utils.AccumulateChanges( currentChanges.ValidatorUpdates, data.ValidatorUpdates, @@ -84,16 +88,7 @@ func (k Keeper) OnRecvVSCPacket( // TODO(mm): since this packet is only received when there are validator set changes // there is some additional lag between the slashing occurrence on the coordinator // and deletion of this flag on the subscriber. does it matter? - for _, addr := range data.GetSlashAcks() { - consAddr, err := sdk.ConsAddressFromBech32(addr) - if err != nil { - k.Logger(ctx).Error( - "failed to parse consensus address", - "address", addr, "error", err, - ) - // returning an error will cause the coordinator to drop us - continue - } + for _, consAddr := range data.GetSlashAcks() { k.DeleteOutstandingDowntime(ctx, consAddr) } @@ -104,7 +99,7 @@ func (k Keeper) OnRecvVSCPacket( "len slash acks", len(data.SlashAcks), ) // Acknowledge the packet - return channeltypes.NewResultAcknowledgement([]byte{byte(1)}) + return commontypes.NewResultAcknowledgementWithLog(ctx, commontypes.VscPacketHandledResult) } // OnAcknowledgementPacket processes an acknowledgement packet @@ -143,3 +138,168 @@ func (k Keeper) OnAcknowledgementPacket( } return nil } + +// QueueVscMaturedPackets queues all VSC packets that have matured as of the current block time, +// to be sent to the coordinator chain at the end of the block. +func (k Keeper) QueueVscMaturedPackets( + ctx sdk.Context, +) { + for _, packet := range k.GetElapsedVscPackets(ctx) { + vscPacket := commontypes.NewVscMaturedPacketData(packet.ID) + k.AppendPendingPacket( + ctx, commontypes.VscMaturedPacket, + &commontypes.SubscriberPacketData_VscMaturedPacketData{ + VscMaturedPacketData: vscPacket, + }, + ) + k.DeletePacketMaturityTime(ctx, packet.ID, packet.MaturityTime) + + k.Logger(ctx).Info("VSCMaturedPacket enqueued", "vscID", vscPacket.ValsetUpdateID) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeVSCMatured, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(commontypes.AttributeChainID, ctx.ChainID()), + sdk.NewAttribute( + types.AttributeSubscriberHeight, + strconv.Itoa(int(ctx.BlockHeight())), + ), + sdk.NewAttribute( + commontypes.AttributeValSetUpdateID, + strconv.Itoa(int(packet.ID)), + ), + sdk.NewAttribute(types.AttributeTimestamp, ctx.BlockTime().String()), + ), + ) + } +} + +// QueueSlashPacket queues a slashing request to be sent to the coordinator chain at the end of the block. +func (k Keeper) QueueSlashPacket( + ctx sdk.Context, + validator abci.Validator, + valsetUpdateID uint64, + infraction stakingtypes.Infraction, +) { + consAddr := sdk.ConsAddress(validator.Address) + downtime := infraction == stakingtypes.Infraction_INFRACTION_DOWNTIME + + // return if an outstanding downtime request is set for the validator + if downtime && k.HasOutstandingDowntime(ctx, consAddr) { + return + } + + if downtime { + // set outstanding downtime to not send multiple + // slashing requests for the same downtime infraction + k.SetOutstandingDowntime(ctx, consAddr) + } + + // construct slash packet data + slashPacket := commontypes.NewSlashPacketData(validator, valsetUpdateID, infraction) + + // append the Slash packet data to pending data packets + k.AppendPendingPacket( + ctx, + commontypes.SlashPacket, + &commontypes.SubscriberPacketData_SlashPacketData{ + SlashPacketData: slashPacket, + }, + ) + + k.Logger(ctx).Info( + "SlashPacket enqueued", + "vscID", slashPacket.ValsetUpdateID, + "validator cons addr", fmt.Sprintf("%X", slashPacket.Validator.Address), + "infraction", slashPacket.Infraction, + ) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeSubscriberSlashRequest, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute( + commontypes.AttributeValidatorAddress, + fmt.Sprintf("%X", slashPacket.Validator.Address), + ), + sdk.NewAttribute( + commontypes.AttributeValSetUpdateID, + strconv.Itoa(int(valsetUpdateID)), + ), + sdk.NewAttribute(commontypes.AttributeInfractionType, infraction.String()), + ), + ) +} + +// IsChannelClosed returns a boolean whether a given channel is in the CLOSED state +func (k Keeper) IsChannelClosed(ctx sdk.Context, channelID string) bool { + channel, found := k.channelKeeper.GetChannel(ctx, commontypes.SubscriberPortID, channelID) + return !found || channel.State == channeltypes.CLOSED +} + +// SendPackets sends all pending packets to the coordinator chain +func (k Keeper) SendPackets(ctx sdk.Context) { + // find destination + channelID, ok := k.GetCoordinatorChannel(ctx) + if !ok { + return + } + // find packets, which will be returned sorted by index + pending := k.GetAllPendingPacketsWithIdx(ctx) + idxsForDeletion := []uint64{} + timeoutPeriod := k.GetSubscriberParams(ctx).IBCTimeoutPeriod + for _, p := range pending { + // Send packet over IBC + err := commontypes.SendIBCPacket( + ctx, + k.scopedKeeper, + k.channelKeeper, + channelID, // source channel id + commontypes.SubscriberPortID, // source port id + commontypes.ModuleCdc.MustMarshalJSON(&p.SubscriberPacketData), + timeoutPeriod, + ) + if err != nil { + if clienttypes.ErrClientNotActive.Is(err) { + // IBC client is expired! + // leave the packet data stored to be sent once the client is upgraded + k.Logger(ctx).Info( + "IBC client is expired, cannot send IBC packet; leaving packet data stored:", + "type", p.Type.String(), + ) + return + } + // Not able to send packet over IBC! + // Leave the packet data stored for the sent to be retried in the next block. + // Note that if VSCMaturedPackets are not sent for long enough, the coordinator + // will remove the subscriber anyway. + k.Logger(ctx).Error( + "cannot send IBC packet; leaving packet data stored:", + "type", p.Type.String(), "err", err.Error(), + ) + return + } else { + if p.Type == commontypes.VscMaturedPacket { + id := p.GetVscMaturedPacketData().ValsetUpdateID + k.Logger(ctx).Info( + "IBC packet sent", + "type", p.Type.String(), + "id", id, + ) + } else { + data := p.GetSlashPacketData() + addr := data.Validator.Address + k.Logger(ctx).Info( + "IBC packet sent", + "type", p.Type.String(), + "addr", addr, + ) + } + } + // Otherwise the vsc matured will be deleted + idxsForDeletion = append(idxsForDeletion, p.Idx) + } + // Delete pending packets that were successfully sent and did not return an error from SendIBCPacket + k.DeletePendingDataPackets(ctx, idxsForDeletion...) +} diff --git a/x/appchain/subscriber/keeper/rewards.go b/x/appchain/subscriber/keeper/rewards.go new file mode 100644 index 000000000..77773b47a --- /dev/null +++ b/x/appchain/subscriber/keeper/rewards.go @@ -0,0 +1,202 @@ +package keeper + +import ( + "strconv" + + "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" + sdk "github.com/cosmos/cosmos-sdk/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" +) + +// EndBlockSendRewards distributes the rewards minted / collected so far amongst the coordinator and the subscriber. +func (k Keeper) EndBlockSendRewards(ctx sdk.Context) { + k.SplitRewardsInternally(ctx) + if !k.shouldSendRewardsToCoordinator(ctx) { + return + } + // Try to send rewards to coordinator + cachedCtx, writeCache := ctx.CacheContext() + if err := k.SendRewardsToCoordinator(cachedCtx); err != nil { + k.Logger(ctx).Error("attempt to sent rewards to coordinator failed", "error", err) + } else { + // The cached context is created with a new EventManager so we merge the event + // into the original context + ctx.EventManager().EmitEvents(cachedCtx.EventManager().Events()) + // write cache + writeCache() + } + + // Update LastRewardTransmissionHeight + k.SetLastRewardTransmissionHeight(ctx, ctx.BlockHeight()) +} + +// DistributeRewardsInternally "distributes" the rewards within the subscriber chain by earmarking the rewards for +// the coordinator in a separate account. +func (k Keeper) SplitRewardsInternally(ctx sdk.Context) { + // source address, the local fee pool + subscriberFeePoolAddr := k.accountKeeper.GetModuleAccount( + ctx, k.feeCollectorName, + ).GetAddress() + // get all tokens in the fee pool - we distribute them all but transfer + // only the reward denomination + fpTokens := k.bankKeeper.GetAllBalances(ctx, subscriberFeePoolAddr) + if fpTokens.Empty() { + k.Logger(ctx).Error("no tokens in fee pool") + return + } + // fraction + frac, err := sdk.NewDecFromStr(k.GetSubscriberParams(ctx).SubscriberRedistributionFraction) + if err != nil { + // should not happen since we validated this in the params + panic(err) + } + // multiply all tokens by fraction + decFPTokens := sdk.NewDecCoinsFromCoins(fpTokens...) + subsRedistrTokens, _ := decFPTokens.MulDec(frac).TruncateDecimal() + if subsRedistrTokens.Empty() { + k.Logger(ctx).Error("no tokens (fractional) to distribute") + // we can safely return from here since nothing has been distributed so far + // so there is nothing to revert + return + } + // send them from the fee pool to queue for local distribution + // TODO(mm): implement SubscriberRedistributeName local distribution logic + // on what basis? + err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, k.feeCollectorName, + types.SubscriberRedistributeName, subsRedistrTokens) + if err != nil { + // It is the common behavior in cosmos-sdk to panic if SendCoinsFromModuleToModule + // returns error. + panic(err) + } + // send the remaining tokens to the coordinator fee pool on the subscriber + remainingTokens := fpTokens.Sub(subsRedistrTokens...) + err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, k.feeCollectorName, + types.SubscriberToSendToCoordinatorName, remainingTokens) + if err != nil { + // It is the common behavior in cosmos-sdk to panic if SendCoinsFromModuleToModule + // returns error. + panic(err) + } +} + +// Check whether it's time to send rewards to coordinator +func (k Keeper) shouldSendRewardsToCoordinator(ctx sdk.Context) bool { + bpdt := k.GetSubscriberParams(ctx).BlocksPerDistributionTransmission + curHeight := ctx.BlockHeight() + ltbh := k.GetLastRewardTransmissionHeight(ctx) + diff := curHeight - ltbh + shouldSend := diff >= bpdt + return shouldSend +} + +// GetLastRewardTransmissionHeight returns the height of the last reward transmission +func (k Keeper) GetLastRewardTransmissionHeight( + ctx sdk.Context, +) int64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.LastRewardTransmissionHeightKey()) + return int64(sdk.BigEndianToUint64(bz)) +} + +// SetLastRewardTransmissionHeight sets the height of the last reward transmission +func (k Keeper) SetLastRewardTransmissionHeight( + ctx sdk.Context, + height int64, +) { + store := ctx.KVStore(k.storeKey) + store.Set( + types.LastRewardTransmissionHeightKey(), + sdk.Uint64ToBigEndian(uint64(height)), + ) +} + +// SendRewardsToCoordinator attempts to send to the coordinator (via IBC) +// all the block rewards allocated for the coordinator +func (k Keeper) SendRewardsToCoordinator(ctx sdk.Context) error { + sourceChannelID := k.GetDistributionTransmissionChannel(ctx) + transferChannel, found := k.channelKeeper.GetChannel( + ctx, transfertypes.PortID, sourceChannelID, + ) + if !found || transferChannel.State != channeltypes.OPEN { + k.Logger(ctx).Error("WARNING: cannot send rewards to coordinator;", + "transmission channel not in OPEN state", "channelID", sourceChannelID) + return nil + } + // due to timing it may happen that the channel is in TRYOPEN state + // on the counterparty, and in that case the transfer will fail. + // this is mitigated by having a sufficiently large reward distribution time + // and setting up the appchain-1 channel before the first distribution takes place. + // for localnet, i am using a value of 10 which is a bit low, but the subsequent + // distributions will be fine. another option is to create the channel immediately + // after a distribution is queued. that way, the channel will be open by the time + // of the next distribution. + + // get params for sending rewards + params := k.GetSubscriberParams(ctx) + toSendToCoordinatorAddr := k.accountKeeper.GetModuleAccount(ctx, + types.SubscriberToSendToCoordinatorName).GetAddress() // sender address + coordinatorAddr := params.CoordinatorFeePoolAddrStr // receiver address + timeoutHeight := clienttypes.ZeroHeight() + timeoutTimestamp := uint64(ctx.BlockTime().Add(params.IBCTimeoutPeriod).UnixNano()) + + denom := params.RewardDenom + balance := k.bankKeeper.GetBalance(ctx, toSendToCoordinatorAddr, denom) + + // if the balance is not zero, + if !balance.IsZero() { + packetTransfer := &transfertypes.MsgTransfer{ + SourcePort: transfertypes.PortID, + SourceChannel: sourceChannelID, + Token: balance, + Sender: toSendToCoordinatorAddr.String(), // subscriber address to send from + Receiver: coordinatorAddr, // coordinator fee pool address to send to + TimeoutHeight: timeoutHeight, // timeout height disabled + TimeoutTimestamp: timeoutTimestamp, + Memo: "subscriber chain rewards distribution", + } + // validate MsgTransfer before calling Transfer() + err := packetTransfer.ValidateBasic() + if err != nil { + return err + } + _, err = k.ibcTransferKeeper.Transfer(ctx, packetTransfer) + if err != nil { + return err + } + } else { + k.Logger(ctx).Error("cannot send rewards to coordinator", + "balance is zero", "denom", denom) + return nil + } + + k.Logger(ctx).Error("sent block rewards to coordinator", + "amount", balance.String(), + "denom", denom, + ) + currentHeight := ctx.BlockHeight() + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeFeeDistribution, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute( + types.AttributeDistributionCurrentHeight, + strconv.Itoa(int(currentHeight)), + ), + sdk.NewAttribute( + types.AttributeDistributionNextHeight, + strconv.Itoa(int(currentHeight+params.BlocksPerDistributionTransmission)), + ), + sdk.NewAttribute( + types.AttributeDistributionFraction, + params.SubscriberRedistributionFraction, + ), + sdk.NewAttribute(types.AttributeDistributionValue, balance.String()), + sdk.NewAttribute(types.AttributeDistributionDenom, denom), + ), + ) + + return nil +} diff --git a/x/appchain/subscriber/keeper/validators.go b/x/appchain/subscriber/keeper/validators.go index 3c247fb35..fd2ebb0cc 100644 --- a/x/appchain/subscriber/keeper/validators.go +++ b/x/appchain/subscriber/keeper/validators.go @@ -4,9 +4,11 @@ import ( "fmt" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" types "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) // SetValsetUpdateIDForHeight sets the valset update ID for a given height @@ -20,14 +22,14 @@ func (k Keeper) SetValsetUpdateIDForHeight( // GetValsetUpdateIDForHeight gets the valset update ID for a given height func (k Keeper) GetValsetUpdateIDForHeight( ctx sdk.Context, height int64, -) (uint64, bool) { +) uint64 { store := ctx.KVStore(k.storeKey) key := types.ValsetUpdateIDKey(height) if !store.Has(key) { - return 0, false + return 0 } bz := store.Get(key) - return sdk.BigEndianToUint64(bz), true + return sdk.BigEndianToUint64(bz) } // ApplyValidatorChanges is a wrapper function that returns the provided validator set @@ -53,20 +55,20 @@ func (k Keeper) ApplyValidatorChanges( panic(fmt.Sprintf("invalid pubkey %s", change.PubKey)) } consAddress := wrappedKey.ToConsAddr() - val, found := k.GetSubscriberChainValidator(ctx, consAddress) + val, found := k.GetSubscriberValidator(ctx, consAddress) switch found { case true: if change.Power < 1 { logger.Info("deleting validator", "consAddress", consAddress) - k.DeleteSubscriberChainValidator(ctx, consAddress) + k.DeleteSubscriberValidator(ctx, consAddress) } else { logger.Info("updating validator", "consAddress", consAddress) val.Power = change.Power - k.SetSubscriberChainValidator(ctx, val) + k.SetSubscriberValidator(ctx, val) } case false: if change.Power > 0 { - ocVal, err := types.NewSubscriberChainValidator( + ocVal, err := commontypes.NewSubscriberValidator( consAddress, change.Power, wrappedKey.ToSdkKey(), ) if err != nil { @@ -75,7 +77,7 @@ func (k Keeper) ApplyValidatorChanges( continue } logger.Info("adding validator", "consAddress", consAddress) - k.SetSubscriberChainValidator(ctx, ocVal) + k.SetSubscriberValidator(ctx, ocVal) ret = append(ret, change) } else { // edge case: we received an update for 0 power @@ -93,22 +95,22 @@ func (k Keeper) ApplyValidatorChanges( return ret } -// SetSubscriberChainValidator stores a validator based on the pub key derived address. -func (k Keeper) SetSubscriberChainValidator( - ctx sdk.Context, validator types.SubscriberChainValidator, +// SetSubscriberValidator stores a validator based on the pub key derived address. +func (k Keeper) SetSubscriberValidator( + ctx sdk.Context, validator commontypes.SubscriberValidator, ) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&validator) - store.Set(types.SubscriberChainValidatorKey(validator.ConsAddress), bz) + store.Set(types.SubscriberValidatorKey(validator.ConsAddress), bz) } -// GetSubscriberChainValidator gets a validator based on the pub key derived (consensus) address. -func (k Keeper) GetSubscriberChainValidator( +// GetSubscriberValidator gets a validator based on the pub key derived (consensus) address. +func (k Keeper) GetSubscriberValidator( ctx sdk.Context, addr sdk.ConsAddress, -) (validator types.SubscriberChainValidator, found bool) { +) (validator commontypes.SubscriberValidator, found bool) { store := ctx.KVStore(k.storeKey) - v := store.Get(types.SubscriberChainValidatorKey(addr)) + v := store.Get(types.SubscriberValidatorKey(addr)) if v == nil { return } @@ -118,25 +120,122 @@ func (k Keeper) GetSubscriberChainValidator( return } -// DeleteSubscriberChainValidator deletes a validator based on the pub key derived address. -func (k Keeper) DeleteSubscriberChainValidator(ctx sdk.Context, addr sdk.ConsAddress) { +// DeleteSubscriberValidator deletes a validator based on the pub key derived address. +func (k Keeper) DeleteSubscriberValidator(ctx sdk.Context, addr sdk.ConsAddress) { store := ctx.KVStore(k.storeKey) - store.Delete(types.SubscriberChainValidatorKey(addr)) + store.Delete(types.SubscriberValidatorKey(addr)) } -// GetAllSubscriberChainValidators returns all validators in the store. -func (k Keeper) GetAllSubscriberChainValidators( +// GetAllSubscriberValidators returns all validators in the store. +func (k Keeper) GetAllSubscriberValidators( ctx sdk.Context, -) (validators []types.SubscriberChainValidator) { +) (validators []commontypes.SubscriberValidator) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.SubscriberChainValidatorBytePrefix}) + iterator := sdk.KVStorePrefixIterator(store, []byte{types.SubscriberValidatorBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { - val := types.SubscriberChainValidator{} + val := commontypes.SubscriberValidator{} k.cdc.MustUnmarshal(iterator.Value(), &val) validators = append(validators, val) } return validators } + +// GetHistoricalInfo gets the historical info at a given height +func (k Keeper) GetHistoricalInfo( + ctx sdk.Context, + height int64, +) (stakingtypes.HistoricalInfo, bool) { + store := ctx.KVStore(k.storeKey) + key := types.HistoricalInfoKey(height) + + value := store.Get(key) + if value == nil { + return stakingtypes.HistoricalInfo{}, false + } + + return stakingtypes.MustUnmarshalHistoricalInfo(k.cdc, value), true +} + +// SetHistoricalInfo sets the historical info at a given height +func (k Keeper) SetHistoricalInfo( + ctx sdk.Context, + height int64, + hi *stakingtypes.HistoricalInfo, +) { + store := ctx.KVStore(k.storeKey) + key := types.HistoricalInfoKey(height) + value := k.cdc.MustMarshal(hi) + + store.Set(key, value) +} + +// DeleteHistoricalInfo deletes the historical info at a given height +func (k Keeper) DeleteHistoricalInfo(ctx sdk.Context, height int64) { + store := ctx.KVStore(k.storeKey) + key := types.HistoricalInfoKey(height) + + store.Delete(key) +} + +// TrackHistoricalInfo saves the latest historical-info and deletes the oldest +// heights that are below pruning height +func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) { + numHistoricalEntries := int64(k.GetParams(ctx).HistoricalEntries) + + // Prune store to ensure we only have parameter-defined historical entries. + // In most cases, this will involve removing a single historical entry. + // In the rare scenario when the historical entries gets reduced to a lower value k' + // from the original value k. k - k' entries must be deleted from the store. + // Since the entries to be deleted are always in a continuous range, we can iterate + // over the historical entries starting from the most recent version to be pruned + // and then return at the first empty entry. + for i := ctx.BlockHeight() - numHistoricalEntries; i >= 0; i-- { + _, found := k.GetHistoricalInfo(ctx, i) + if found { + k.DeleteHistoricalInfo(ctx, i) + } else { + break + } + } + + // if there is no need to persist historicalInfo, return + if numHistoricalEntries == 0 { + return + } + + // Create HistoricalInfo struct + lastVals := []stakingtypes.Validator{} + for _, v := range k.GetAllSubscriberValidators(ctx) { + pk, err := v.ConsPubKey() + if err != nil { + // This should never happen as the pubkey is assumed + // to be stored correctly in ApplyCCValidatorChanges. + panic(err) + } + val, err := stakingtypes.NewValidator(nil, pk, stakingtypes.Description{}) + if err != nil { + // This should never happen as the pubkey is assumed + // to be stored correctly in ApplyCCValidatorChanges. + panic(err) + } + + // Set validator to bonded status + val.Status = stakingtypes.Bonded + // Compute tokens from voting power + val.Tokens = sdk.TokensFromConsensusPower( + v.Power, sdk.DefaultPowerReduction, + ) + lastVals = append(lastVals, val) + } + + // Create historical info entry which sorts the validator set by voting power + historicalEntry := stakingtypes.NewHistoricalInfo( + ctx.BlockHeader(), lastVals, sdk.DefaultPowerReduction, + ) + + // Set latest HistoricalInfo at current height + k.SetHistoricalInfo(ctx, ctx.BlockHeight(), &historicalEntry) +} diff --git a/x/appchain/subscriber/module.go b/x/appchain/subscriber/module.go index 3c8072218..73374df0f 100644 --- a/x/appchain/subscriber/module.go +++ b/x/appchain/subscriber/module.go @@ -163,10 +163,50 @@ func (AppModule) ConsensusVersion() uint64 { return 1 } // BeginBlock contains the logic that is automatically triggered at the beginning of each block func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { - am.keeper.BeginBlock(ctx) + channelId, found := am.keeper.GetCoordinatorChannel(ctx) + if found && am.keeper.IsChannelClosed(ctx, channelId) { + // we are now PoA + am.keeper.Logger(ctx). + Error("coordinator channel is closed, we are now PoA", "channelId", channelId) + } + + // get height of the yet-to-be-made block + height := ctx.BlockHeight() + // this should either be the last known vscId + // or the one set by the last processed vsc packet + // since that processing applies to the next block + vscID := am.keeper.GetValsetUpdateIDForHeight(ctx, height) + am.keeper.SetValsetUpdateIDForHeight(ctx, height+1, vscID) + am.keeper.Logger(ctx).Debug( + "block height was mapped to vscID", + "height", height, "vscID", vscID, + ) + + am.keeper.TrackHistoricalInfo(ctx) } // EndBlock contains the logic that is automatically triggered at the end of each block func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return am.keeper.EndBlock(ctx) + // send rewards to coordinator + am.keeper.EndBlockSendRewards(ctx) + + // queue maturity packets to coordinator + am.keeper.QueueVscMaturedPackets(ctx) + // remember that slash packets are queued in the subscriber module + // by the slashing and evidence modules when a slashing event is observed by them + + // broadcast queued packets to coordinator + am.keeper.SendPackets(ctx) + + // apply validator changes and then delete them + data := am.keeper.GetPendingChanges(ctx) + if len(data.ValidatorUpdates) == 0 { + return []abci.ValidatorUpdate{} + } + updates := am.keeper.ApplyValidatorChanges(ctx, data.ValidatorUpdates) + am.keeper.DeletePendingChanges(ctx) + if len(updates) > 0 { + am.keeper.Logger(ctx).Info("applying validator updates", "updates", updates) + } + return updates } diff --git a/x/appchain/subscriber/module_ibc.go b/x/appchain/subscriber/module_ibc.go index eac59d418..e743b3b03 100644 --- a/x/appchain/subscriber/module_ibc.go +++ b/x/appchain/subscriber/module_ibc.go @@ -153,7 +153,8 @@ func (im IBCModule) OnChanOpenAck( } var md commontypes.HandshakeMetadata - // no k.cdc.MustUnmarshal available here, so we use this way. + // Marshal by coordinator and Unmarshal by subscriber. Don't use `must`, + // because we don't trust the source since it wasn't generated here. if err := (&md).Unmarshal([]byte(counterpartyMetadata)); err != nil { return errorsmod.Wrapf( commontypes.ErrInvalidHandshakeMetadata, diff --git a/x/appchain/subscriber/types/events.go b/x/appchain/subscriber/types/events.go index 0363af2f1..21952f56b 100644 --- a/x/appchain/subscriber/types/events.go +++ b/x/appchain/subscriber/types/events.go @@ -1,5 +1,16 @@ package types const ( + EventTypeFeeDistribution = "fee_distribution" EventTypeFeeTransferChannelOpened = "fee_transfer_channel_opened" + EventTypeSubscriberSlashRequest = "subscriber_slash_request" + EventTypeVSCMatured = "vsc_matured" + + AttributeDistributionCurrentHeight = "distribution_current_height" + AttributeDistributionDenom = "distribution_denom" + AttributeDistributionFraction = "distribution_fraction" + AttributeDistributionNextHeight = "distribution_next_height" + AttributeDistributionValue = "distribution_value" + AttributeSubscriberHeight = "subscriber_height" + AttributeTimestamp = "timestamp" ) diff --git a/x/appchain/subscriber/types/keys.go b/x/appchain/subscriber/types/keys.go index 8c4c4c0a9..b5f90f12c 100644 --- a/x/appchain/subscriber/types/keys.go +++ b/x/appchain/subscriber/types/keys.go @@ -46,8 +46,8 @@ const ( CoordinatorClientIDBytePrefix // ValsetUpdateIDBytePrefix is the prefix for the valset update ID key ValsetUpdateIDBytePrefix - // SubscriberChainValidatorBytePrefix is the prefix for the subscriber chain validator key - SubscriberChainValidatorBytePrefix + // SubscriberValidatorBytePrefix is the prefix for the subscriber validator key + SubscriberValidatorBytePrefix // CoordinatorChannelBytePrefix is the prefix for the coordinator channel key CoordinatorChannelBytePrefix // PendingChangesBytePrefix is the prefix for the pending changes key @@ -56,6 +56,14 @@ const ( PacketMaturityTimeBytePrefix // OutstandingDowntimeBytePrefix is the prefix for the outstanding downtime key OutstandingDowntimeBytePrefix + // PendingPacketsIndexBytePrefix is the prefix for the pending packets index key + PendingPacketsIndexBytePrefix + // PendingDataPacketsBytePrefix is the prefix for the pending data packets key + PendingDataPacketsBytePrefix + // HistoricalInfoBytePrefix is the prefix for the historical info key + HistoricalInfoBytePrefix + // LastRewardTransmissionHeightBytePrefix is the prefix for the last reward transmission height key + LastRewardTransmissionHeightBytePrefix ) // ParamsKey returns the key for the params @@ -81,10 +89,10 @@ func ValsetUpdateIDKey(height int64) []byte { ) } -// SubscriberChainValidatorKey returns the key for the subscriber chain validator +// SubscriberValidatorKey returns the key for the subscriber chain validator // against the provided address. -func SubscriberChainValidatorKey(address sdk.ConsAddress) []byte { - return append([]byte{SubscriberChainValidatorBytePrefix}, address...) +func SubscriberValidatorKey(address sdk.ConsAddress) []byte { + return append([]byte{SubscriberValidatorBytePrefix}, address...) } // CoordinatorChannelKey returns the key for which the ibc channel id to the coordinator chain @@ -99,7 +107,7 @@ func PendingChangesKey() []byte { } // PacketMaturityTimeKey returns the key for the packet maturity time -func PacketMaturityTimeKey(vscID uint64, maturityTime time.Time) []byte { +func PacketMaturityTimeKey(maturityTime time.Time, vscID uint64) []byte { return utils.AppendMany( []byte{PacketMaturityTimeBytePrefix}, sdk.FormatTimeBytes(maturityTime), @@ -111,3 +119,23 @@ func PacketMaturityTimeKey(vscID uint64, maturityTime time.Time) []byte { func OutstandingDowntimeKey(consAddress sdk.ConsAddress) []byte { return append([]byte{OutstandingDowntimeBytePrefix}, consAddress.Bytes()...) } + +// PendingPacketsIndexKey returns the key for the pending packets index +func PendingPacketsIndexKey() []byte { + return []byte{PendingPacketsIndexBytePrefix} +} + +// PendingDataPacketsKey returns the key for the pending data packets +func PendingDataPacketsKey(idx uint64) []byte { + return append([]byte{PendingDataPacketsBytePrefix}, sdk.Uint64ToBigEndian(idx)...) +} + +// HistoricalInfoKey returns the key for the historical info +func HistoricalInfoKey(height int64) []byte { + return append([]byte{HistoricalInfoBytePrefix}, sdk.Uint64ToBigEndian(uint64(height))...) +} + +// LastRewardTransmissionHeightKey is the key for the last reward transmission height +func LastRewardTransmissionHeightKey() []byte { + return []byte{LastRewardTransmissionHeightBytePrefix} +} diff --git a/x/appchain/subscriber/types/subscriber.pb.go b/x/appchain/subscriber/types/subscriber.pb.go deleted file mode 100644 index ad56c953d..000000000 --- a/x/appchain/subscriber/types/subscriber.pb.go +++ /dev/null @@ -1,433 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: exocore/appchain/subscriber/v1/subscriber.proto - -package types - -import ( - fmt "fmt" - _ "github.com/cosmos/cosmos-proto" - types "github.com/cosmos/cosmos-sdk/codec/types" - _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// SubscriberChainValidator is a validator structure on the subscriber chain. -type SubscriberChainValidator struct { - // address, as derived from the consensus key. No correlation with the operator - // address on Exocore. - ConsAddress []byte `protobuf:"bytes,1,opt,name=cons_address,json=consAddress,proto3" json:"cons_address,omitempty"` - // power is the vote power of the validator - Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` - // pubkey is the consensus public key of the validator, as a Protobuf Any. - // this type is chosen to match the x/staking/validator type. - Pubkey *types.Any `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" yaml:"consensus_pubkey"` -} - -func (m *SubscriberChainValidator) Reset() { *m = SubscriberChainValidator{} } -func (m *SubscriberChainValidator) String() string { return proto.CompactTextString(m) } -func (*SubscriberChainValidator) ProtoMessage() {} -func (*SubscriberChainValidator) Descriptor() ([]byte, []int) { - return fileDescriptor_1c15efc73dd829e9, []int{0} -} -func (m *SubscriberChainValidator) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SubscriberChainValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SubscriberChainValidator.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *SubscriberChainValidator) XXX_Merge(src proto.Message) { - xxx_messageInfo_SubscriberChainValidator.Merge(m, src) -} -func (m *SubscriberChainValidator) XXX_Size() int { - return m.Size() -} -func (m *SubscriberChainValidator) XXX_DiscardUnknown() { - xxx_messageInfo_SubscriberChainValidator.DiscardUnknown(m) -} - -var xxx_messageInfo_SubscriberChainValidator proto.InternalMessageInfo - -func (m *SubscriberChainValidator) GetConsAddress() []byte { - if m != nil { - return m.ConsAddress - } - return nil -} - -func (m *SubscriberChainValidator) GetPower() int64 { - if m != nil { - return m.Power - } - return 0 -} - -func (m *SubscriberChainValidator) GetPubkey() *types.Any { - if m != nil { - return m.Pubkey - } - return nil -} - -func init() { - proto.RegisterType((*SubscriberChainValidator)(nil), "exocore.appchain.subscriber.v1.SubscriberChainValidator") -} - -func init() { - proto.RegisterFile("exocore/appchain/subscriber/v1/subscriber.proto", fileDescriptor_1c15efc73dd829e9) -} - -var fileDescriptor_1c15efc73dd829e9 = []byte{ - // 325 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x51, 0x31, 0x4f, 0x02, 0x31, - 0x18, 0xa5, 0x12, 0x19, 0x0e, 0xa6, 0xcb, 0x25, 0x1e, 0x0c, 0x15, 0x99, 0x58, 0x6c, 0x83, 0x6c, - 0x26, 0x0e, 0x60, 0x9c, 0x4c, 0x8c, 0xc1, 0x44, 0x13, 0x17, 0xd2, 0x96, 0x7a, 0x5c, 0x80, 0xfb, - 0x9a, 0xf6, 0x0e, 0xe8, 0xbf, 0xf0, 0xc7, 0x18, 0x7f, 0x83, 0x71, 0x62, 0x74, 0x32, 0x06, 0xfe, - 0x81, 0xbf, 0xc0, 0x1c, 0x3d, 0x08, 0x83, 0x5b, 0xdf, 0xeb, 0xf7, 0x5e, 0x5f, 0xbf, 0xe7, 0x51, - 0xb9, 0x04, 0x01, 0x5a, 0x52, 0xa6, 0x94, 0x18, 0xb3, 0x38, 0xa1, 0x26, 0xe3, 0x46, 0xe8, 0x98, - 0x4b, 0x4d, 0xe7, 0x9d, 0x03, 0x44, 0x94, 0x86, 0x14, 0x7c, 0x5c, 0x08, 0xc8, 0x4e, 0x40, 0x0e, - 0x46, 0xe6, 0x9d, 0x46, 0x5d, 0x80, 0x99, 0x81, 0x19, 0x6e, 0xa7, 0xa9, 0x03, 0x4e, 0xda, 0x08, - 0x22, 0x88, 0xc0, 0xf1, 0xf9, 0xa9, 0x60, 0xeb, 0x11, 0x40, 0x34, 0x95, 0x74, 0x8b, 0x78, 0xf6, - 0x42, 0x59, 0x62, 0xdd, 0x55, 0xeb, 0x1d, 0x79, 0xe1, 0xc3, 0xde, 0xfd, 0x3a, 0x7f, 0xed, 0x91, - 0x4d, 0xe3, 0x11, 0x4b, 0x41, 0xfb, 0x67, 0x5e, 0x4d, 0x40, 0x62, 0x86, 0x6c, 0x34, 0xd2, 0xd2, - 0x98, 0x10, 0x35, 0x51, 0xbb, 0x36, 0xa8, 0xe6, 0x5c, 0xcf, 0x51, 0x7e, 0xe0, 0x1d, 0x2b, 0x58, - 0x48, 0x1d, 0x1e, 0x35, 0x51, 0xbb, 0x3c, 0x70, 0xc0, 0x67, 0x5e, 0x45, 0x65, 0x7c, 0x22, 0x6d, - 0x58, 0x6e, 0xa2, 0x76, 0xf5, 0x22, 0x20, 0x2e, 0x01, 0xd9, 0x25, 0x20, 0xbd, 0xc4, 0xf6, 0xbb, - 0xbf, 0xdf, 0xa7, 0x27, 0x96, 0xcd, 0xa6, 0x97, 0xad, 0xdc, 0x52, 0x26, 0x26, 0x33, 0x43, 0xa7, - 0x6b, 0x7d, 0xbe, 0x9d, 0x07, 0xc5, 0xcf, 0x84, 0xb6, 0x2a, 0x05, 0x72, 0x9f, 0xf1, 0x5b, 0x69, - 0x07, 0x85, 0x71, 0xff, 0xe9, 0x63, 0x8d, 0xd1, 0x6a, 0x8d, 0xd1, 0xcf, 0x1a, 0xa3, 0xd7, 0x0d, - 0x2e, 0xad, 0x36, 0xb8, 0xf4, 0xb5, 0xc1, 0xa5, 0xe7, 0xab, 0x28, 0x4e, 0xc7, 0x19, 0x27, 0x02, - 0x66, 0xf4, 0xc6, 0x6d, 0xf2, 0x4e, 0xa6, 0x0b, 0xd0, 0x93, 0x7d, 0x13, 0xcb, 0x7f, 0xbb, 0x48, - 0xad, 0x92, 0x86, 0x57, 0xb6, 0x19, 0xbb, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x38, 0x5d, - 0x69, 0xb7, 0x01, 0x00, 0x00, -} - -func (m *SubscriberChainValidator) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SubscriberChainValidator) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SubscriberChainValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Pubkey != nil { - { - size, err := m.Pubkey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSubscriber(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Power != 0 { - i = encodeVarintSubscriber(dAtA, i, uint64(m.Power)) - i-- - dAtA[i] = 0x10 - } - if len(m.ConsAddress) > 0 { - i -= len(m.ConsAddress) - copy(dAtA[i:], m.ConsAddress) - i = encodeVarintSubscriber(dAtA, i, uint64(len(m.ConsAddress))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintSubscriber(dAtA []byte, offset int, v uint64) int { - offset -= sovSubscriber(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *SubscriberChainValidator) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ConsAddress) - if l > 0 { - n += 1 + l + sovSubscriber(uint64(l)) - } - if m.Power != 0 { - n += 1 + sovSubscriber(uint64(m.Power)) - } - if m.Pubkey != nil { - l = m.Pubkey.Size() - n += 1 + l + sovSubscriber(uint64(l)) - } - return n -} - -func sovSubscriber(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozSubscriber(x uint64) (n int) { - return sovSubscriber(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *SubscriberChainValidator) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubscriber - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SubscriberChainValidator: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SubscriberChainValidator: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsAddress", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubscriber - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSubscriber - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSubscriber - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConsAddress = append(m.ConsAddress[:0], dAtA[iNdEx:postIndex]...) - if m.ConsAddress == nil { - m.ConsAddress = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType) - } - m.Power = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubscriber - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Power |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pubkey", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubscriber - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSubscriber - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubscriber - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pubkey == nil { - m.Pubkey = &types.Any{} - } - if err := m.Pubkey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSubscriber(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubscriber - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipSubscriber(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSubscriber - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSubscriber - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSubscriber - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthSubscriber - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupSubscriber - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthSubscriber - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthSubscriber = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowSubscriber = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupSubscriber = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/appchain/subscriber/types/types.go b/x/appchain/subscriber/types/types.go index ab1254f4c..edc465b46 100644 --- a/x/appchain/subscriber/types/types.go +++ b/x/appchain/subscriber/types/types.go @@ -1 +1,11 @@ package types + +import ( + commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" +) + +// SubscriberPacketDataWithIdx is a wrapper struct for SubscriberPacketData with an index. +type SubscriberPacketDataWithIdx struct { + commontypes.SubscriberPacketData + Idx uint64 +} diff --git a/x/avs/keeper/avs.go b/x/avs/keeper/avs.go index 01e22c5d4..5f865a2f5 100644 --- a/x/avs/keeper/avs.go +++ b/x/avs/keeper/avs.go @@ -7,7 +7,6 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - "github.com/ExocoreNetwork/exocore/utils" "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ethereum/go-ethereum/common" "github.com/evmos/evmos/v14/x/evm/statedb" @@ -80,6 +79,20 @@ func (k *Keeper) GetEpochEndAVSs(ctx sdk.Context, epochIdentifier string, ending return avsList } +// GetEpochEndChainIDs returns a list of chainIDs for AVSs which are scheduled to start at the end of the +// current epoch, or the beginning of the next one. The chainIDs used are without the revision number. +func (k Keeper) GetEpochEndChainIDs(ctx sdk.Context, epochIdentifier string, endingEpochNumber int64) []string { + avsList := k.GetEpochEndAVSs(ctx, epochIdentifier, endingEpochNumber) + var chainIDs []string + for _, avsAddr := range avsList { + chainID, found := k.GetChainIDByAVSAddr(ctx, avsAddr) + if found { + chainIDs = append(chainIDs, chainID) + } + } + return chainIDs +} + // GetAVSInfoByTaskAddress returns the AVS which containing this task address func (k *Keeper) GetAVSInfoByTaskAddress(ctx sdk.Context, taskAddr string) types.AVSInfo { avs := types.AVSInfo{} @@ -113,13 +126,15 @@ func (k *Keeper) GetTaskChallengeEpochEndAVSs(ctx sdk.Context, epochIdentifier s // AssetIDs, EpochsUntilUnbonded, EpochIdentifier, MinSelfDelegation and StartingEpoch. // This will ensure compatibility with all of the related AVS functions, like // GetEpochEndAVSs, GetAVSSupportedAssets, and GetAVSMinimumSelfDelegation. +// The caller must use a chainID without the revision number if the AVS is intended +// to outlive the upgrades, for example, the x/dogfood AVS. The same cannot be said +// for x/appchain AVSs wherein the post-upgrade operators may not be the same. func (k Keeper) RegisterAVSWithChainID( oCtx sdk.Context, params *types.AVSRegisterOrDeregisterParams, ) (avsAddr common.Address, err error) { // guard against errors ctx, writeFunc := oCtx.CacheContext() // remove the version number and validate - params.ChainID = utils.ChainIDWithoutRevision(params.ChainID) if len(params.ChainID) == 0 { return common.Address{}, errorsmod.Wrap(types.ErrNotNull, "RegisterAVSWithChainID: chainID is null") } diff --git a/x/dogfood/keeper/genesis.go b/x/dogfood/keeper/genesis.go index f943cc6ba..46c122c60 100644 --- a/x/dogfood/keeper/genesis.go +++ b/x/dogfood/keeper/genesis.go @@ -4,6 +4,7 @@ import ( "fmt" exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + "github.com/ExocoreNetwork/exocore/utils" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" "github.com/ExocoreNetwork/exocore/x/dogfood/types" abci "github.com/cometbft/cometbft/abci/types" @@ -35,13 +36,15 @@ func (k Keeper) InitGenesis( var avsAddr common.Address var err error // the avs module will remove the revision by itself + chainIDWithoutRevision := utils.ChainIDWithoutRevision(ctx.ChainID()) + // the caller must provide the accurate chainID: with or without revision if avsAddr, err = k.avsKeeper.RegisterAVSWithChainID(ctx, &avstypes.AVSRegisterOrDeregisterParams{ - AvsName: ctx.ChainID(), + AvsName: chainIDWithoutRevision, AssetID: genState.Params.AssetIDs, UnbondingPeriod: uint64(genState.Params.EpochsUntilUnbonded), MinSelfDelegation: genState.Params.MinSelfDelegation.Uint64(), EpochIdentifier: epochID, - ChainID: ctx.ChainID(), + ChainID: chainIDWithoutRevision, }); err != nil { panic(fmt.Errorf("could not create the dogfood AVS: %s", err)) } diff --git a/x/operator/keeper/consensus_keys.go b/x/operator/keeper/consensus_keys.go index 50818f03b..886de5250 100644 --- a/x/operator/keeper/consensus_keys.go +++ b/x/operator/keeper/consensus_keys.go @@ -16,7 +16,8 @@ import ( ) // This file indexes by chainID and not the avs address. -// The caller must ensure that the chainID is without the revision number. +// The chainID may or may not have a revision, depending on whether the AVS is +// expected to outlast its upgrades, particularly with the same set of operators. func (k *Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) @@ -427,7 +428,7 @@ func (k Keeper) DeleteOperatorAddressForChainIDAndConsAddr( // ClearPreviousConsensusKeys clears the previous consensus public key for all operators // of the specified chain. func (k Keeper) ClearPreviousConsensusKeys(ctx sdk.Context, chainID string) { - partialKey := types.ChainIDWithLenKey(chainID) + partialKey := utils.ChainIDWithLenKey(chainID) store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator( store, diff --git a/x/operator/keeper/operator.go b/x/operator/keeper/operator.go index 5b7990d07..fedd4f74a 100644 --- a/x/operator/keeper/operator.go +++ b/x/operator/keeper/operator.go @@ -194,6 +194,20 @@ func (k *Keeper) GetOptedInAVSForOperator(ctx sdk.Context, operatorAddr string) return avsList, nil } +func (k *Keeper) GetChainIDsForOperator(ctx sdk.Context, operatorAddr string) ([]string, error) { + addrs, err := k.GetOptedInAVSForOperator(ctx, operatorAddr) + if err != nil { + return nil, err + } + chainIDs := make([]string, 0, len(addrs)) + for _, addr := range addrs { + if chainID, found := k.avsKeeper.GetChainIDByAVSAddr(ctx, addr); found { + chainIDs = append(chainIDs, chainID) + } + } + return chainIDs, nil +} + func (k *Keeper) GetOptedInOperatorListByAVS(ctx sdk.Context, avsAddr string) ([]string, error) { // get all opted-in info store := prefix.NewStore(ctx.KVStore(k.storeKey), operatortypes.KeyPrefixOperatorOptedAVSInfo) diff --git a/x/operator/keeper/opt.go b/x/operator/keeper/opt.go index ac71ebedc..b61cd1fd1 100644 --- a/x/operator/keeper/opt.go +++ b/x/operator/keeper/opt.go @@ -98,12 +98,12 @@ func (k *Keeper) OptOut(ctx sdk.Context, operatorAddress sdk.AccAddress, avsAddr return delegationtypes.ErrOperatorIsFrozen } // check if it is the chain-type AVS - chainIDWithoutRevision, isChainAvs := k.avsKeeper.GetChainIDByAVSAddr(ctx, avsAddr) + chainID, isChainAvs := k.avsKeeper.GetChainIDByAVSAddr(ctx, avsAddr) // set up the deferred function to remove key and write cache defer func() { if err == nil && isChainAvs { // store.Delete... doesn't fail - k.InitiateOperatorKeyRemovalForChainID(ctx, operatorAddress, chainIDWithoutRevision) + k.InitiateOperatorKeyRemovalForChainID(ctx, operatorAddress, chainID) } }() diff --git a/x/operator/keeper/slash.go b/x/operator/keeper/slash.go index 2bfdaa9aa..384d3d976 100644 --- a/x/operator/keeper/slash.go +++ b/x/operator/keeper/slash.go @@ -178,6 +178,7 @@ func (k Keeper) SlashWithInfractionReason( ctx sdk.Context, addr sdk.AccAddress, infractionHeight, power int64, slashFactor sdk.Dec, infraction stakingtypes.Infraction, ) sdkmath.Int { + // for x/dogfood, we use the chainIDWithoutRevision as the chainID chainID := utils.ChainIDWithoutRevision(ctx.ChainID()) isAvs, avsAddr := k.avsKeeper.IsAVSByChainID(ctx, chainID) if !isAvs { diff --git a/x/operator/types/keys.go b/x/operator/types/keys.go index 52c71cb73..8af3de9a8 100644 --- a/x/operator/types/keys.go +++ b/x/operator/types/keys.go @@ -95,7 +95,7 @@ func init() { } func AddrAndChainIDKey(prefix byte, addr sdk.AccAddress, chainID string) []byte { - partialKey := ChainIDWithLenKey(chainID) + partialKey := utils.ChainIDWithLenKey(chainID) return utils.AppendMany( // Append the prefix []byte{prefix}, @@ -108,7 +108,7 @@ func AddrAndChainIDKey(prefix byte, addr sdk.AccAddress, chainID string) []byte } func ChainIDAndAddrKey(prefix byte, chainID string, addr sdk.AccAddress) []byte { - partialKey := ChainIDWithLenKey(chainID) + partialKey := utils.ChainIDWithLenKey(chainID) return utils.AppendMany( // Append the prefix []byte{prefix}, @@ -143,15 +143,19 @@ func KeyForChainIDAndOperatorToConsKey(chainID string, addr sdk.AccAddress) []by func KeyForChainIDAndConsKeyToOperator(chainID string, addr sdk.ConsAddress) []byte { return utils.AppendMany( []byte{BytePrefixForChainIDAndConsKeyToOperator}, - ChainIDWithLenKey(chainID), + utils.ChainIDWithLenKey(chainID), addr, ) } func KeyForOperatorKeyRemovalForChainID(addr sdk.AccAddress, chainID string) []byte { return utils.AppendMany( - []byte{BytePrefixForOperatorKeyRemovalForChainID}, addr, - ChainIDWithLenKey(chainID), + []byte{BytePrefixForOperatorKeyRemovalForChainID}, + addr, + // TODO: it may be possible to just use the chainID here without the length. + // This is because the chainID is at the end of the key and we can just iterate + // over all keys with the same operator address. + utils.ChainIDWithLenKey(chainID), ) } diff --git a/x/operator/types/utils.go b/x/operator/types/utils.go deleted file mode 100644 index 38ad58667..000000000 --- a/x/operator/types/utils.go +++ /dev/null @@ -1,20 +0,0 @@ -package types - -import ( - "github.com/ExocoreNetwork/exocore/utils" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// ChainIDWithLenKey returns the key with the following format: -// bytePrefix | len(chainId) | chainId -// This is similar to Solidity's ABI encoding. -func ChainIDWithLenKey(chainID string) []byte { - chainIDL := len(chainID) - return utils.AppendMany( - // Append the chainID length - // #nosec G701 - sdk.Uint64ToBigEndian(uint64(chainIDL)), - // Append the chainID - []byte(chainID), - ) -} From 075fccfa02f960739020f5c496b80b96fca969db Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 10 Sep 2024 18:31:33 +0000 Subject: [PATCH 45/52] fix: golang lint --- .../coordinator/keeper/impl_operator_hooks.go | 6 ++-- x/appchain/subscriber/keeper/impl_sdk.go | 23 +++++++------ x/appchain/subscriber/keeper/keeper.go | 1 + x/appchain/subscriber/keeper/queue.go | 2 +- x/appchain/subscriber/keeper/relay.go | 34 +++++++++---------- x/appchain/subscriber/module.go | 6 ++-- x/dogfood/keeper/impl_sdk.go | 8 +++-- 7 files changed, 44 insertions(+), 36 deletions(-) diff --git a/x/appchain/coordinator/keeper/impl_operator_hooks.go b/x/appchain/coordinator/keeper/impl_operator_hooks.go index b6dd53f91..aa527e1f1 100644 --- a/x/appchain/coordinator/keeper/impl_operator_hooks.go +++ b/x/appchain/coordinator/keeper/impl_operator_hooks.go @@ -28,8 +28,8 @@ func (h OperatorHooksWrapper) AfterOperatorKeySet( // AfterOperatorKeyReplaced is the implementation of the operator hooks. func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( - ctx sdk.Context, operatorAccAddress sdk.AccAddress, - oldKey exocoretypes.WrappedConsKey, newKey exocoretypes.WrappedConsKey, + ctx sdk.Context, _ sdk.AccAddress, + oldKey exocoretypes.WrappedConsKey, _ exocoretypes.WrappedConsKey, chainID string, ) { consAddr := oldKey.ToConsAddr() @@ -52,7 +52,7 @@ func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( // AfterOperatorKeyRemovalInitiated is the implementation of the operator hooks. func (h OperatorHooksWrapper) AfterOperatorKeyRemovalInitiated( - ctx sdk.Context, operator sdk.AccAddress, chainID string, key exocoretypes.WrappedConsKey, + ctx sdk.Context, _ sdk.AccAddress, chainID string, key exocoretypes.WrappedConsKey, ) { consAddr := key.ToConsAddr() _, found := h.keeper.GetSubscriberValidatorForChain(ctx, chainID, consAddr) diff --git a/x/appchain/subscriber/keeper/impl_sdk.go b/x/appchain/subscriber/keeper/impl_sdk.go index 6f925e0ed..c563ccb9a 100644 --- a/x/appchain/subscriber/keeper/impl_sdk.go +++ b/x/appchain/subscriber/keeper/impl_sdk.go @@ -23,26 +23,29 @@ import ( // https://github.com/orgs/cosmos/projects/28/views/11?pane=issue&itemId=21248976 // interface guards -var _ slashingtypes.StakingKeeper = Keeper{} -var _ evidencetypes.StakingKeeper = Keeper{} -var _ clienttypes.StakingKeeper = Keeper{} -var _ genutiltypes.StakingKeeper = Keeper{} +var ( + _ slashingtypes.StakingKeeper = Keeper{} + _ evidencetypes.StakingKeeper = Keeper{} + _ clienttypes.StakingKeeper = Keeper{} + _ genutiltypes.StakingKeeper = Keeper{} +) // GetParams returns an empty staking params. It is used by the interfaces above, but the returned // value is never examined. -func (k Keeper) GetParams(ctx sdk.Context) stakingtypes.Params { +func (k Keeper) GetParams(sdk.Context) stakingtypes.Params { return stakingtypes.Params{} } // This function is used by the slashing module to store the validator public keys into the // state. These were previously verified in the evidence module but have since been removed. func (k Keeper) IterateValidators(sdk.Context, - func(index int64, validator stakingtypes.ValidatorI) (stop bool)) { + func(int64, stakingtypes.ValidatorI) bool, +) { // no op } // simply unimplemented because it is not needed -func (k Keeper) Validator(ctx sdk.Context, addr sdk.ValAddress) stakingtypes.ValidatorI { +func (k Keeper) Validator(sdk.Context, sdk.ValAddress) stakingtypes.ValidatorI { panic("unimplemented on this keeper") } @@ -83,7 +86,7 @@ func (k Keeper) SlashWithInfractionReason( ctx sdk.Context, addr sdk.ConsAddress, infractionHeight, power int64, - slashFactor sdk.Dec, + _ sdk.Dec, infraction stakingtypes.Infraction, ) math.Int { if infraction == stakingtypes.Infraction_INFRACTION_UNSPECIFIED { @@ -116,7 +119,7 @@ func (k Keeper) SlashWithInfractionReason( } // Unimplemented because jailing happens on the coordinator chain. -func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) {} +func (k Keeper) Jail(sdk.Context, sdk.ConsAddress) {} // Same as above. func (k Keeper) Unjail(sdk.Context, sdk.ConsAddress) {} @@ -140,7 +143,7 @@ func (k Keeper) MaxValidators(ctx sdk.Context) uint32 { // In interchain-security, this does seem to have been implemented. However, I did not see // the validators being persisted in the first place so I just returned an empty list. // I also did not see this being used anywhere within the slashing module. -func (k Keeper) GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) { +func (k Keeper) GetAllValidators(sdk.Context) []stakingtypes.Validator { return []stakingtypes.Validator{} } diff --git a/x/appchain/subscriber/keeper/keeper.go b/x/appchain/subscriber/keeper/keeper.go index 0c330a7dd..87bd2f846 100644 --- a/x/appchain/subscriber/keeper/keeper.go +++ b/x/appchain/subscriber/keeper/keeper.go @@ -48,6 +48,7 @@ func NewKeeper( cdc: cdc, storeKey: storeKey, accountKeeper: accountKeeper, + bankKeeper: bankKeeper, scopedKeeper: scopedKeeper, portKeeper: portKeeper, clientKeeper: clientKeeper, diff --git a/x/appchain/subscriber/keeper/queue.go b/x/appchain/subscriber/keeper/queue.go index d339466fb..4aeea11f3 100644 --- a/x/appchain/subscriber/keeper/queue.go +++ b/x/appchain/subscriber/keeper/queue.go @@ -36,7 +36,7 @@ func (k Keeper) AppendPendingPacket( // GetPendingPackets returns ALL the pending packets from the store without indexes. func (k Keeper) GetPendingPackets(ctx sdk.Context) []commontypes.SubscriberPacketData { ppWithIndexes := k.GetAllPendingPacketsWithIdx(ctx) - var ppList []commontypes.SubscriberPacketData + ppList := make([]commontypes.SubscriberPacketData, 0) for _, ppWithIndex := range ppWithIndexes { ppList = append(ppList, ppWithIndex.SubscriberPacketData) } diff --git a/x/appchain/subscriber/keeper/relay.go b/x/appchain/subscriber/keeper/relay.go index e387ff36d..63d498cb2 100644 --- a/x/appchain/subscriber/keeper/relay.go +++ b/x/appchain/subscriber/keeper/relay.go @@ -249,7 +249,8 @@ func (k Keeper) SendPackets(ctx sdk.Context) { pending := k.GetAllPendingPacketsWithIdx(ctx) idxsForDeletion := []uint64{} timeoutPeriod := k.GetSubscriberParams(ctx).IBCTimeoutPeriod - for _, p := range pending { + for i := range pending { + p := pending[i] // Send packet over IBC err := commontypes.SendIBCPacket( ctx, @@ -279,23 +280,22 @@ func (k Keeper) SendPackets(ctx sdk.Context) { "type", p.Type.String(), "err", err.Error(), ) return + } + if p.Type == commontypes.VscMaturedPacket { + id := p.GetVscMaturedPacketData().ValsetUpdateID + k.Logger(ctx).Info( + "IBC packet sent", + "type", p.Type.String(), + "id", id, + ) } else { - if p.Type == commontypes.VscMaturedPacket { - id := p.GetVscMaturedPacketData().ValsetUpdateID - k.Logger(ctx).Info( - "IBC packet sent", - "type", p.Type.String(), - "id", id, - ) - } else { - data := p.GetSlashPacketData() - addr := data.Validator.Address - k.Logger(ctx).Info( - "IBC packet sent", - "type", p.Type.String(), - "addr", addr, - ) - } + data := p.GetSlashPacketData() + addr := data.Validator.Address + k.Logger(ctx).Info( + "IBC packet sent", + "type", p.Type.String(), + "addr", addr, + ) } // Otherwise the vsc matured will be deleted idxsForDeletion = append(idxsForDeletion, p.Idx) diff --git a/x/appchain/subscriber/module.go b/x/appchain/subscriber/module.go index 73374df0f..d2c6a51a2 100644 --- a/x/appchain/subscriber/module.go +++ b/x/appchain/subscriber/module.go @@ -163,11 +163,11 @@ func (AppModule) ConsensusVersion() uint64 { return 1 } // BeginBlock contains the logic that is automatically triggered at the beginning of each block func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { - channelId, found := am.keeper.GetCoordinatorChannel(ctx) - if found && am.keeper.IsChannelClosed(ctx, channelId) { + channelID, found := am.keeper.GetCoordinatorChannel(ctx) + if found && am.keeper.IsChannelClosed(ctx, channelID) { // we are now PoA am.keeper.Logger(ctx). - Error("coordinator channel is closed, we are now PoA", "channelId", channelId) + Error("coordinator channel is closed, we are now PoA", "channelId", channelID) } // get height of the yet-to-be-made block diff --git a/x/dogfood/keeper/impl_sdk.go b/x/dogfood/keeper/impl_sdk.go index 67f750b08..4d436f4aa 100644 --- a/x/dogfood/keeper/impl_sdk.go +++ b/x/dogfood/keeper/impl_sdk.go @@ -146,7 +146,9 @@ func (k Keeper) Delegation( // This interface is only used for unjail to retrieve the self delegation value, // so the delegator and validator are the same. operator := delegator - operatorUSDValues, err := k.operatorKeeper.GetOrCalculateOperatorUSDValues(ctx, operator, avstypes.ChainIDWithoutRevision(ctx.ChainID())) + operatorUSDValues, err := k.operatorKeeper.GetOrCalculateOperatorUSDValues( + ctx, operator, utils.ChainIDWithoutRevision(ctx.ChainID()), + ) if err != nil { k.Logger(ctx).Error( "Delegation: failed to get or calculate the operator USD values", @@ -157,7 +159,9 @@ func (k Keeper) Delegation( return stakingtypes.Delegation{ DelegatorAddress: delegator.String(), ValidatorAddress: validator.String(), - Shares: sdk.TokensFromConsensusPower(operatorUSDValues.SelfUSDValue.TruncateInt64(), sdk.DefaultPowerReduction).ToLegacyDec(), + Shares: sdk.TokensFromConsensusPower( + operatorUSDValues.SelfUSDValue.TruncateInt64(), sdk.DefaultPowerReduction, + ).ToLegacyDec(), } } From 985e6063417337e2021c4b28562c7b3306237587 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 13 Oct 2024 15:32:23 +0000 Subject: [PATCH 46/52] fix: respond to AI comments --- .../appchain/subscriber/v1/genesis.proto | 2 +- utils/utils.go | 11 ++- x/appchain/common/types/types.go | 22 ++++-- x/appchain/common/types/wire.go | 4 +- x/appchain/coordinator/keeper/slash.go | 12 ++- x/appchain/coordinator/module_ibc.go | 2 + .../coordinator/types/expected_keepers.go | 10 ++- x/appchain/subscriber/keeper/connection.go | 6 +- x/appchain/subscriber/keeper/keeper.go | 6 +- x/appchain/subscriber/keeper/validators.go | 16 ++-- x/appchain/subscriber/module_ibc.go | 3 +- x/appchain/subscriber/types/genesis.pb.go | 76 +++++++++---------- 12 files changed, 97 insertions(+), 73 deletions(-) diff --git a/proto/exocore/appchain/subscriber/v1/genesis.proto b/proto/exocore/appchain/subscriber/v1/genesis.proto index 07fb8384b..af0bc9a7c 100644 --- a/proto/exocore/appchain/subscriber/v1/genesis.proto +++ b/proto/exocore/appchain/subscriber/v1/genesis.proto @@ -31,7 +31,7 @@ message GenesisState { // The key used is prefix + time + vscId. message MaturingVSCPacket { // vsc_id is the id of the VSC that is maturing. - uint64 vsc_id = 1 [ (gogoproto.customname) = "ID" ]; + uint64 vsc_id = 1 [ (gogoproto.customname) = "ValidatorSetChangeID" ]; // maturity_time is the time at which the VSC will mature. google.protobuf.Timestamp maturity_time = 2 [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; diff --git a/utils/utils.go b/utils/utils.go index 8339f4f24..d20814e59 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -218,14 +218,13 @@ func SortByPower( func AccumulateChanges( currentChanges, newChanges []abci.ValidatorUpdate, ) []abci.ValidatorUpdate { - // get only unieque updates + // get only unique updates m := make(map[string]abci.ValidatorUpdate) - for i := 0; i < len(currentChanges); i++ { - m[currentChanges[i].PubKey.String()] = currentChanges[i] + for _, change := range currentChanges { + m[change.PubKey.String()] = change } - for i := 0; i < len(newChanges); i++ { - // overwrite with new power - m[newChanges[i].PubKey.String()] = newChanges[i] + for _, change := range newChanges { + m[change.PubKey.String()] = change } // convert to list diff --git a/x/appchain/common/types/types.go b/x/appchain/common/types/types.go index 6b5466099..f88c54c5c 100644 --- a/x/appchain/common/types/types.go +++ b/x/appchain/common/types/types.go @@ -5,14 +5,24 @@ import ( channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) -// NewErrorAcknowledgementWithLog creates an error acknowledgement with a log message. -func NewErrorAcknowledgementWithLog(ctx sdk.Context, err error) channeltypes.Acknowledgement { - ctx.Logger().Error("IBC ErrorAcknowledgement constructed", "error", err) - return channeltypes.NewErrorAcknowledgement(err) -} +const maxLogSize = 1024 // NewResultAcknowledgementWithLog creates a result acknowledgement with a log message. func NewResultAcknowledgementWithLog(ctx sdk.Context, res []byte) channeltypes.Acknowledgement { - ctx.Logger().Info("IBC ResultAcknowledgement constructed", "res", res) + logRes := res + if len(res) > maxLogSize { + logRes = append(res[:maxLogSize], []byte("... (truncated)")...) + } + ctx.Logger().Info( + "IBC ResultAcknowledgement constructed", + "res_size", len(res), + "res_preview", string(logRes), + ) return channeltypes.NewResultAcknowledgement(res) } + +// NewErrorAcknowledgementWithLog creates an error acknowledgement with a log message. +func NewErrorAcknowledgementWithLog(ctx sdk.Context, err error) channeltypes.Acknowledgement { + ctx.Logger().Error("IBC ErrorAcknowledgement constructed", "error", err) + return channeltypes.NewErrorAcknowledgement(err) +} diff --git a/x/appchain/common/types/wire.go b/x/appchain/common/types/wire.go index bef4e3aac..7e1de8754 100644 --- a/x/appchain/common/types/wire.go +++ b/x/appchain/common/types/wire.go @@ -17,8 +17,8 @@ func (vdt SlashPacketData) Validate() error { return ErrInvalidPacketData.Wrapf("invalid validator: %s", err.Error()) } // vdt.Validator.Power must be positive - if vdt.Validator.Power == 0 { - return ErrInvalidPacketData.Wrap("validator power cannot be zero") + if vdt.Validator.Power <= 0 { + return ErrInvalidPacketData.Wrap("validator power must be positive") } // ValsetUpdateId can be zero for the first validator set, so we don't validate it here. if vdt.Infraction != stakingtypes.Infraction_INFRACTION_DOWNTIME { diff --git a/x/appchain/coordinator/keeper/slash.go b/x/appchain/coordinator/keeper/slash.go index 7caaf572b..44914965e 100644 --- a/x/appchain/coordinator/keeper/slash.go +++ b/x/appchain/coordinator/keeper/slash.go @@ -56,15 +56,21 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data commonty slashProportionDecimal, _ := sdk.NewDecFromStr(slashProportion) jailDuration := k.GetSubDowntimeJailDuration(ctx, chainID) chainIDWithoutRevision := utils.ChainIDWithoutRevision(chainID) + // `found` is always true, since we already validated the chainID _, avsAddress := k.avsKeeper.IsAVSByChainID(ctx, chainIDWithoutRevision) // the slashing hook should trigger a validator set update for all affected AVSs. since the `chainID` is one of them // we should make sure we are well set up for that update. we will include an ack of the slash packet in the next // validator set update; record that here. k.AppendSlashAck(ctx, chainID, consAddress) - k.operatorKeeper.ApplySlashForHeight( + if err := k.operatorKeeper.ApplySlashForHeight( ctx, operatorAccAddress, avsAddress.String(), height, slashProportionDecimal, data.Infraction, jailDuration, - ) + ); err != nil { + k.Logger(ctx).Error( + "failed to apply slash for height", + "chainID", chainID, "height", height, "consAddress", consAddress, "error", err, + ) + } } // AppendSlashAck appends a slashing acknowledgment for a chain, to be sent in the next validator set update. @@ -77,7 +83,7 @@ func (k Keeper) AppendSlashAck(ctx sdk.Context, chainID string, consAddress sdk. // GetSlashAcks gets the slashing acknowledgments for a chain, to be sent in the next validator set update. func (k Keeper) GetSlashAcks(ctx sdk.Context, chainID string) types.ConsensusAddresses { store := ctx.KVStore(k.storeKey) - var consAddresses types.ConsensusAddresses + consAddresses := types.ConsensusAddresses{} key := types.SlashAcksKey(chainID) value := store.Get(key) k.cdc.MustUnmarshal(value, &consAddresses) diff --git a/x/appchain/coordinator/module_ibc.go b/x/appchain/coordinator/module_ibc.go index 7496bdfe9..009b3bba0 100644 --- a/x/appchain/coordinator/module_ibc.go +++ b/x/appchain/coordinator/module_ibc.go @@ -225,6 +225,8 @@ func (im IBCModule) OnRecvPacket( ack = commontypes.NewErrorAcknowledgementWithLog(ctx, err) } else if res != nil { ack = commontypes.NewResultAcknowledgementWithLog(ctx, res) + } else { + ack = commontypes.NewResultAcknowledgementWithLog(ctx, nil) } ctx.EventManager().EmitEvent( diff --git a/x/appchain/coordinator/types/expected_keepers.go b/x/appchain/coordinator/types/expected_keepers.go index 9316adb6b..4affc0fd8 100644 --- a/x/appchain/coordinator/types/expected_keepers.go +++ b/x/appchain/coordinator/types/expected_keepers.go @@ -3,7 +3,7 @@ package types import ( time "time" - types "github.com/ExocoreNetwork/exocore/types/keys" + keytypes "github.com/ExocoreNetwork/exocore/types/keys" avstypes "github.com/ExocoreNetwork/exocore/x/avs/types" epochstypes "github.com/ExocoreNetwork/exocore/x/epochs/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,7 +13,9 @@ import ( // AVSKeeper represents the expected keeper interface for the AVS module. type AVSKeeper interface { - RegisterAVSWithChainID(sdk.Context, *avstypes.AVSRegisterOrDeregisterParams) (common.Address, error) + RegisterAVSWithChainID( + sdk.Context, *avstypes.AVSRegisterOrDeregisterParams, + ) (common.Address, error) IsAVSByChainID(sdk.Context, string) (bool, common.Address) DeleteAVSInfo(sdk.Context, common.Address) error } @@ -30,7 +32,7 @@ type StakingKeeper interface { // OperatorKeeper represents the expected keeper interface for the operator module. type OperatorKeeper interface { - GetActiveOperatorsForChainID(sdk.Context, string) ([]sdk.AccAddress, []types.WrappedConsKey) + GetActiveOperatorsForChainID(sdk.Context, string) ([]sdk.AccAddress, []keytypes.WrappedConsKey) GetVotePowerForChainID(sdk.Context, []sdk.AccAddress, string) ([]int64, error) GetOperatorAddressForChainIDAndConsAddr( sdk.Context, string, sdk.ConsAddress, @@ -46,5 +48,5 @@ type OperatorKeeper interface { ctx sdk.Context, operatorAccAddress sdk.AccAddress, avsAddress string, height uint64, fraction sdk.Dec, infraction stakingtypes.Infraction, jailDuration time.Duration, - ) + ) error } diff --git a/x/appchain/subscriber/keeper/connection.go b/x/appchain/subscriber/keeper/connection.go index 5a3021719..4bae8dfec 100644 --- a/x/appchain/subscriber/keeper/connection.go +++ b/x/appchain/subscriber/keeper/connection.go @@ -51,9 +51,9 @@ func (k Keeper) DeleteCoordinatorChannel(ctx sdk.Context) { // VerifyCoordinatorChain verifies the chain trying to connect on the channel handshake. func (k Keeper) VerifyCoordinatorChain(ctx sdk.Context, connectionHops []string) error { if len(connectionHops) != 1 { - return errorsmod.Wrap( - channeltypes.ErrTooManyConnectionHops, - "must have direct connection to coordinator chain", + return channeltypes.ErrTooManyConnectionHops.Wrapf( + "must have direct connection to coordinator chain, found %d hops", + len(connectionHops), ) } connectionID := connectionHops[0] diff --git a/x/appchain/subscriber/keeper/keeper.go b/x/appchain/subscriber/keeper/keeper.go index 1bb985d95..e3a32ea96 100644 --- a/x/appchain/subscriber/keeper/keeper.go +++ b/x/appchain/subscriber/keeper/keeper.go @@ -98,7 +98,7 @@ func (k Keeper) GetPendingChanges( if bz == nil { return nil, false } - var res *commontypes.ValidatorSetChangePacketData + res := &commontypes.ValidatorSetChangePacketData{} k.cdc.MustUnmarshal(bz, res) return res, true } @@ -120,8 +120,8 @@ func (k Keeper) SetPacketMaturityTime( ) { store := ctx.KVStore(k.storeKey) maturingVSCPacket := &types.MaturingVSCPacket{ - ID: vscID, - MaturityTime: maturityTime, + ValidatorSetChangeID: vscID, + MaturityTime: maturityTime, } store.Set( types.PacketMaturityTimeKey(vscID, maturityTime), diff --git a/x/appchain/subscriber/keeper/validators.go b/x/appchain/subscriber/keeper/validators.go index 1b9f91c66..04f55ec45 100644 --- a/x/appchain/subscriber/keeper/validators.go +++ b/x/appchain/subscriber/keeper/validators.go @@ -1,8 +1,6 @@ package keeper import ( - "fmt" - keytypes "github.com/ExocoreNetwork/exocore/types/keys" types "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types" abci "github.com/cometbft/cometbft/abci/types" @@ -50,7 +48,11 @@ func (k Keeper) ApplyValidatorChanges( // an error in deserializing the key would indicate that the coordinator // has provided invalid data. this is a critical error and should be // investigated. - panic(fmt.Sprintf("invalid pubkey %s", change.PubKey)) + logger.Error( + "failed to deserialize validator key", + "validator", change.PubKey, + ) + continue } consAddress := wrappedKey.ToConsAddr() val, found := k.GetSubscriberChainValidator(ctx, consAddress) @@ -76,7 +78,6 @@ func (k Keeper) ApplyValidatorChanges( } logger.Info("adding validator", "consAddress", consAddress) k.SetSubscriberChainValidator(ctx, ocVal) - ret = append(ret, change) } else { // edge case: we received an update for 0 power // but the validator is already deleted. Do not forward @@ -121,7 +122,12 @@ func (k Keeper) GetSubscriberChainValidator( // DeleteSubscriberChainValidator deletes a validator based on the pub key derived address. func (k Keeper) DeleteSubscriberChainValidator(ctx sdk.Context, addr sdk.ConsAddress) { store := ctx.KVStore(k.storeKey) - store.Delete(types.SubscriberChainValidatorKey(addr)) + key := types.SubscriberChainValidatorKey(addr) + if store.Has(key) { + store.Delete(key) + } else { + k.Logger(ctx).Info("validator not found", "address", addr) + } } // GetAllSubscriberChainValidators returns all validators in the store. diff --git a/x/appchain/subscriber/module_ibc.go b/x/appchain/subscriber/module_ibc.go index eac59d418..7845053fa 100644 --- a/x/appchain/subscriber/module_ibc.go +++ b/x/appchain/subscriber/module_ibc.go @@ -157,8 +157,7 @@ func (im IBCModule) OnChanOpenAck( if err := (&md).Unmarshal([]byte(counterpartyMetadata)); err != nil { return errorsmod.Wrapf( commontypes.ErrInvalidHandshakeMetadata, - "error unmarshalling ibc-ack metadata: \n%v; \nmetadata: %v", - err, counterpartyMetadata, + "error unmarshalling ibc-ack metadata: \n%v", err, ) } diff --git a/x/appchain/subscriber/types/genesis.pb.go b/x/appchain/subscriber/types/genesis.pb.go index 1be726c52..9933621a3 100644 --- a/x/appchain/subscriber/types/genesis.pb.go +++ b/x/appchain/subscriber/types/genesis.pb.go @@ -111,7 +111,7 @@ func (m *GenesisState) GetCoordinatorChannelID() string { // The key used is prefix + time + vscId. type MaturingVSCPacket struct { // vsc_id is the id of the VSC that is maturing. - ID uint64 `protobuf:"varint,1,opt,name=vsc_id,json=vscId,proto3" json:"vsc_id,omitempty"` + ValidatorSetChangeID uint64 `protobuf:"varint,1,opt,name=vsc_id,json=vscId,proto3" json:"vsc_id,omitempty"` // maturity_time is the time at which the VSC will mature. MaturityTime time.Time `protobuf:"bytes,2,opt,name=maturity_time,json=maturityTime,proto3,stdtime" json:"maturity_time"` } @@ -149,9 +149,9 @@ func (m *MaturingVSCPacket) XXX_DiscardUnknown() { var xxx_messageInfo_MaturingVSCPacket proto.InternalMessageInfo -func (m *MaturingVSCPacket) GetID() uint64 { +func (m *MaturingVSCPacket) GetValidatorSetChangeID() uint64 { if m != nil { - return m.ID + return m.ValidatorSetChangeID } return 0 } @@ -173,35 +173,35 @@ func init() { } var fileDescriptor_f608de439fd2c5db = []byte{ - // 442 bytes of a gzipped FileDescriptorProto + // 448 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x41, 0x6f, 0xd3, 0x30, - 0x14, 0xc7, 0x9b, 0x52, 0x2a, 0xf0, 0xc6, 0x81, 0xac, 0x40, 0x55, 0x89, 0x64, 0xda, 0x85, 0x49, - 0x4c, 0xb6, 0x0a, 0x67, 0x2e, 0x69, 0x11, 0x0a, 0x88, 0x69, 0x4a, 0x11, 0x48, 0x5c, 0x2a, 0xc7, - 0xf1, 0x52, 0x6b, 0x8d, 0x1d, 0xd9, 0x6e, 0xd8, 0x0e, 0x7c, 0x87, 0x7d, 0xac, 0x1d, 0x38, 0xec, - 0xc8, 0xa9, 0xa0, 0xf4, 0x8b, 0x20, 0x3b, 0x09, 0x2d, 0x0a, 0xda, 0xed, 0xf9, 0xf9, 0xff, 0x7e, - 0x7e, 0xfa, 0xff, 0x0d, 0x4e, 0xe8, 0xa5, 0x20, 0x42, 0x52, 0x84, 0xf3, 0x9c, 0x2c, 0x30, 0xe3, - 0x48, 0xad, 0x62, 0x45, 0x24, 0x8b, 0xa9, 0x44, 0xc5, 0x18, 0xa5, 0x94, 0x53, 0xc5, 0x14, 0xcc, - 0xa5, 0xd0, 0xc2, 0xf5, 0x6a, 0x35, 0x6c, 0xd4, 0x70, 0xab, 0x86, 0xc5, 0x78, 0xf4, 0xa2, 0x45, - 0x23, 0x22, 0xcb, 0x04, 0x37, 0xa4, 0xaa, 0xaa, 0x40, 0xa3, 0x41, 0x2a, 0x52, 0x61, 0x4b, 0x64, - 0xaa, 0xba, 0xeb, 0xa7, 0x42, 0xa4, 0x4b, 0x8a, 0xec, 0x29, 0x5e, 0x9d, 0x23, 0xcd, 0x32, 0xaa, - 0x34, 0xce, 0xf2, 0x4a, 0x70, 0xf4, 0xa3, 0x0b, 0xf6, 0xdf, 0x55, 0x1b, 0xcd, 0x34, 0xd6, 0xd4, - 0x7d, 0x0f, 0xfa, 0x39, 0x96, 0x38, 0x53, 0x43, 0xe7, 0xd0, 0x39, 0xde, 0x7b, 0x75, 0x02, 0x5b, - 0x1b, 0xd6, 0xef, 0x16, 0x63, 0x38, 0xfb, 0xbb, 0xeb, 0x99, 0x9d, 0x09, 0x7a, 0x37, 0x6b, 0xbf, - 0x13, 0xd5, 0x04, 0x77, 0x06, 0xf6, 0x88, 0x10, 0x32, 0x61, 0x1c, 0x6b, 0x21, 0x87, 0x5d, 0x0b, - 0x7c, 0x79, 0x17, 0x70, 0xb2, 0x95, 0x87, 0xfc, 0x5c, 0xd4, 0xbc, 0x5d, 0x8a, 0xfb, 0x01, 0x3c, - 0xd9, 0x39, 0xce, 0xc9, 0x92, 0x51, 0xae, 0xe7, 0x2c, 0x19, 0xde, 0x3b, 0x74, 0x8e, 0x1f, 0x06, - 0xcf, 0xca, 0xb5, 0x7f, 0xb0, 0x83, 0x99, 0xd8, 0xfb, 0x70, 0x1a, 0x1d, 0x90, 0x56, 0x33, 0x71, - 0x4f, 0xc1, 0xd3, 0x7f, 0x60, 0x0b, 0xcc, 0x39, 0x5d, 0x1a, 0x5a, 0xcf, 0xd2, 0x86, 0xe5, 0xda, - 0x1f, 0xec, 0xd2, 0x2a, 0x41, 0x38, 0x8d, 0x06, 0xa4, 0xdd, 0x4d, 0x8e, 0xbe, 0x83, 0xc7, 0x1f, - 0xb1, 0x5e, 0x49, 0xc6, 0xd3, 0xcf, 0xb3, 0xc9, 0x19, 0x26, 0x17, 0x54, 0xbb, 0xcf, 0x41, 0xbf, - 0x50, 0xc4, 0x40, 0x8d, 0xa5, 0xbd, 0xa0, 0x5f, 0xae, 0xfd, 0x6e, 0x38, 0x8d, 0xee, 0x17, 0x8a, - 0x84, 0x89, 0x1b, 0x82, 0x47, 0x99, 0x9d, 0xd1, 0x57, 0x73, 0x13, 0x4f, 0xed, 0xd3, 0x08, 0x56, - 0xd9, 0xc1, 0x26, 0x3b, 0xf8, 0xa9, 0xc9, 0x2e, 0x78, 0x60, 0x6c, 0xb9, 0xfe, 0xe5, 0x3b, 0xd1, - 0x7e, 0x33, 0x6a, 0x2e, 0x83, 0x2f, 0x37, 0xa5, 0xe7, 0xdc, 0x96, 0x9e, 0xf3, 0xbb, 0xf4, 0x9c, - 0xeb, 0x8d, 0xd7, 0xb9, 0xdd, 0x78, 0x9d, 0x9f, 0x1b, 0xaf, 0xf3, 0xf5, 0x4d, 0xca, 0xf4, 0x62, - 0x15, 0x1b, 0xab, 0xd1, 0xdb, 0xca, 0xff, 0x53, 0xaa, 0xbf, 0x09, 0x79, 0x81, 0x9a, 0x1f, 0x76, - 0xf9, 0xdf, 0x1f, 0xab, 0xaf, 0x72, 0xaa, 0xe2, 0xbe, 0x5d, 0xe2, 0xf5, 0x9f, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x83, 0x95, 0xc1, 0xee, 0xdd, 0x02, 0x00, 0x00, + 0x14, 0xc7, 0x9b, 0x51, 0x2a, 0xf0, 0xc6, 0x81, 0xac, 0x40, 0xd5, 0x43, 0x32, 0xed, 0xc2, 0x24, + 0x26, 0x5b, 0x85, 0x33, 0x97, 0xb6, 0x08, 0x05, 0xc4, 0x34, 0x25, 0x68, 0x48, 0x5c, 0x2a, 0xc7, + 0xf1, 0x52, 0x6b, 0x8d, 0x1d, 0xd9, 0x6e, 0xd8, 0x3e, 0x05, 0xfb, 0x58, 0x3b, 0x70, 0xd8, 0x91, + 0x53, 0x41, 0xe9, 0x17, 0x41, 0xb6, 0x13, 0x56, 0x54, 0xb4, 0xdb, 0xf3, 0xf3, 0xff, 0xfd, 0xfc, + 0xf4, 0xff, 0x1b, 0x1c, 0xd3, 0x4b, 0x41, 0x84, 0xa4, 0x08, 0x97, 0x25, 0x99, 0x63, 0xc6, 0x91, + 0x5a, 0xa6, 0x8a, 0x48, 0x96, 0x52, 0x89, 0xaa, 0x11, 0xca, 0x29, 0xa7, 0x8a, 0x29, 0x58, 0x4a, + 0xa1, 0x85, 0x1f, 0x34, 0x6a, 0xd8, 0xaa, 0xe1, 0x9d, 0x1a, 0x56, 0xa3, 0xe1, 0xcb, 0x2d, 0x1a, + 0x11, 0x45, 0x21, 0xb8, 0x21, 0xb9, 0xca, 0x81, 0x86, 0xfd, 0x5c, 0xe4, 0xc2, 0x96, 0xc8, 0x54, + 0x4d, 0x37, 0xcc, 0x85, 0xc8, 0x17, 0x14, 0xd9, 0x53, 0xba, 0x3c, 0x47, 0x9a, 0x15, 0x54, 0x69, + 0x5c, 0x94, 0x4e, 0x70, 0xf8, 0x63, 0x07, 0xec, 0xbd, 0x77, 0x1b, 0x25, 0x1a, 0x6b, 0xea, 0x7f, + 0x00, 0xbd, 0x12, 0x4b, 0x5c, 0xa8, 0x81, 0x77, 0xe0, 0x1d, 0xed, 0xbe, 0x3e, 0x86, 0x5b, 0x1b, + 0x36, 0xef, 0x56, 0x23, 0x98, 0xfc, 0xdd, 0xf5, 0xd4, 0xce, 0x8c, 0xbb, 0x37, 0xab, 0xb0, 0x13, + 0x37, 0x04, 0x3f, 0x01, 0xbb, 0x44, 0x08, 0x99, 0x31, 0x8e, 0xb5, 0x90, 0x83, 0x1d, 0x0b, 0x7c, + 0x75, 0x1f, 0x70, 0x72, 0x27, 0x8f, 0xf8, 0xb9, 0x68, 0x78, 0x9b, 0x14, 0xff, 0x23, 0x78, 0xb6, + 0x71, 0x9c, 0x91, 0x05, 0xa3, 0x5c, 0xcf, 0x58, 0x36, 0x78, 0x70, 0xe0, 0x1d, 0x3d, 0x1e, 0xbf, + 0xa8, 0x57, 0xe1, 0xfe, 0x06, 0x66, 0x62, 0xef, 0xa3, 0x69, 0xbc, 0x4f, 0xb6, 0x9a, 0x99, 0x7f, + 0x02, 0x9e, 0xff, 0x03, 0x9b, 0x63, 0xce, 0xe9, 0xc2, 0xd0, 0xba, 0x96, 0x36, 0xa8, 0x57, 0x61, + 0x7f, 0x93, 0xe6, 0x04, 0xd1, 0x34, 0xee, 0x93, 0xed, 0x6e, 0x76, 0xf8, 0xdd, 0x03, 0x4f, 0x3f, + 0x61, 0xbd, 0x94, 0x8c, 0xe7, 0x67, 0xc9, 0xe4, 0x14, 0x93, 0x0b, 0xaa, 0x7d, 0x04, 0x7a, 0x95, + 0x22, 0x86, 0x6a, 0x3c, 0xed, 0x3a, 0xea, 0x19, 0x5e, 0xb0, 0xcc, 0x4c, 0x27, 0x54, 0x1b, 0x40, + 0x4e, 0xa3, 0x69, 0xfc, 0xb0, 0x52, 0x24, 0xca, 0xfc, 0x08, 0x3c, 0x29, 0x2c, 0x45, 0x5f, 0xcd, + 0x4c, 0x62, 0x8d, 0x75, 0x43, 0xe8, 0xe2, 0x84, 0x6d, 0x9c, 0xf0, 0x73, 0x1b, 0xe7, 0xf8, 0x91, + 0x71, 0xea, 0xfa, 0x57, 0xe8, 0xc5, 0x7b, 0xed, 0xa8, 0xb9, 0x1c, 0x7f, 0xb9, 0xa9, 0x03, 0xef, + 0xb6, 0x0e, 0xbc, 0xdf, 0x75, 0xe0, 0x5d, 0xaf, 0x83, 0xce, 0xed, 0x3a, 0xe8, 0xfc, 0x5c, 0x07, + 0x9d, 0xaf, 0x6f, 0x73, 0xa6, 0xe7, 0xcb, 0xd4, 0xb8, 0x8f, 0xde, 0xb9, 0x48, 0x4e, 0xa8, 0xfe, + 0x26, 0xe4, 0x05, 0x6a, 0x3f, 0xdd, 0xe5, 0x7f, 0x3f, 0xb1, 0xbe, 0x2a, 0xa9, 0x4a, 0x7b, 0x76, + 0x89, 0x37, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x44, 0xfd, 0x3d, 0x44, 0xf0, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -289,8 +289,8 @@ func (m *MaturingVSCPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(n3)) i-- dAtA[i] = 0x12 - if m.ID != 0 { - i = encodeVarintGenesis(dAtA, i, uint64(m.ID)) + if m.ValidatorSetChangeID != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.ValidatorSetChangeID)) i-- dAtA[i] = 0x8 } @@ -335,8 +335,8 @@ func (m *MaturingVSCPacket) Size() (n int) { } var l int _ = l - if m.ID != 0 { - n += 1 + sovGenesis(uint64(m.ID)) + if m.ValidatorSetChangeID != 0 { + n += 1 + sovGenesis(uint64(m.ValidatorSetChangeID)) } l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.MaturityTime) n += 1 + l + sovGenesis(uint64(l)) @@ -560,9 +560,9 @@ func (m *MaturingVSCPacket) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetChangeID", wireType) } - m.ID = 0 + m.ValidatorSetChangeID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -572,7 +572,7 @@ func (m *MaturingVSCPacket) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ID |= uint64(b&0x7F) << shift + m.ValidatorSetChangeID |= uint64(b&0x7F) << shift if b < 0x80 { break } From b52b87a71d30a2a9c75bdf31dfe98dd692b3aae3 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 13 Oct 2024 15:40:44 +0000 Subject: [PATCH 47/52] chore(appchain): golang lint --- x/appchain/common/types/types.go | 18 +++++++++++------- x/appchain/coordinator/module_ibc.go | 7 ++++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/x/appchain/common/types/types.go b/x/appchain/common/types/types.go index f88c54c5c..ae5d487aa 100644 --- a/x/appchain/common/types/types.go +++ b/x/appchain/common/types/types.go @@ -9,15 +9,19 @@ const maxLogSize = 1024 // NewResultAcknowledgementWithLog creates a result acknowledgement with a log message. func NewResultAcknowledgementWithLog(ctx sdk.Context, res []byte) channeltypes.Acknowledgement { - logRes := res if len(res) > maxLogSize { - logRes = append(res[:maxLogSize], []byte("... (truncated)")...) + ctx.Logger().Info( + "IBC ResultAcknowledgement constructed", + "res_size", len(res), + "res_preview", string(res[:maxLogSize]), + ) + } else { + ctx.Logger().Info( + "IBC ResultAcknowledgement constructed", + "res_size", len(res), + "res", string(res), + ) } - ctx.Logger().Info( - "IBC ResultAcknowledgement constructed", - "res_size", len(res), - "res_preview", string(logRes), - ) return channeltypes.NewResultAcknowledgement(res) } diff --git a/x/appchain/coordinator/module_ibc.go b/x/appchain/coordinator/module_ibc.go index 009b3bba0..a13cd6378 100644 --- a/x/appchain/coordinator/module_ibc.go +++ b/x/appchain/coordinator/module_ibc.go @@ -221,11 +221,12 @@ func (im IBCModule) OnRecvPacket( err = sdkerrors.ErrInvalidType.Wrapf("unknown packet type: %s", data.Type) } } - if err != nil { + switch { + case err != nil: ack = commontypes.NewErrorAcknowledgementWithLog(ctx, err) - } else if res != nil { + case res != nil: ack = commontypes.NewResultAcknowledgementWithLog(ctx, res) - } else { + default: ack = commontypes.NewResultAcknowledgementWithLog(ctx, nil) } From dd499d1df222e55d1c17ccd8efbe8ba361ecb5d4 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sun, 13 Oct 2024 15:59:41 +0000 Subject: [PATCH 48/52] respond to more AI comments --- x/appchain/coordinator/module_ibc.go | 2 +- x/appchain/subscriber/keeper/validators.go | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/x/appchain/coordinator/module_ibc.go b/x/appchain/coordinator/module_ibc.go index a13cd6378..caa8932a7 100644 --- a/x/appchain/coordinator/module_ibc.go +++ b/x/appchain/coordinator/module_ibc.go @@ -234,7 +234,7 @@ func (im IBCModule) OnRecvPacket( sdk.NewEvent( commontypes.EventTypePacket, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - sdk.NewAttribute(commontypes.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack != nil)), + sdk.NewAttribute(commontypes.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack.Success())), ), ) diff --git a/x/appchain/subscriber/keeper/validators.go b/x/appchain/subscriber/keeper/validators.go index 04f55ec45..9fadcd4b1 100644 --- a/x/appchain/subscriber/keeper/validators.go +++ b/x/appchain/subscriber/keeper/validators.go @@ -50,7 +50,7 @@ func (k Keeper) ApplyValidatorChanges( // investigated. logger.Error( "failed to deserialize validator key", - "validator", change.PubKey, + "i", i, "validator", change.PubKey, ) continue } @@ -74,6 +74,10 @@ func (k Keeper) ApplyValidatorChanges( if err != nil { // cannot happen, but just in case add this check. // simply skip the validator if it does. + logger.Error( + "failed to instantiate validator", + "i", i, "validator", change.PubKey, + ) continue } logger.Info("adding validator", "consAddress", consAddress) From 8e931aa99269146729ddb8f19dc6c92eaa601ec4 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:17:09 +0000 Subject: [PATCH 49/52] app: introduce coordinator module --- app/app.go | 60 +++++++++++----- utils/utils.go | 7 ++ .../keeper/impl_delegation_hooks.go | 71 +++++++++++-------- .../coordinator/keeper/impl_operator_hooks.go | 65 +++++++++-------- x/appchain/coordinator/keeper/keeper.go | 24 ++++++- x/appchain/coordinator/keeper/slash.go | 2 +- .../coordinator/types/expected_keepers.go | 6 +- x/dogfood/keeper/keeper.go | 16 +++-- x/dogfood/types/utils.go | 6 -- x/operator/keeper/operator.go | 2 +- x/operator/keeper/slash.go | 21 ++++++ 11 files changed, 186 insertions(+), 94 deletions(-) diff --git a/app/app.go b/app/app.go index 1eeffa625..bb5082f5c 100644 --- a/app/app.go +++ b/app/app.go @@ -204,6 +204,10 @@ import ( // Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes _ "github.com/ethereum/go-ethereum/eth/tracers/js" _ "github.com/ethereum/go-ethereum/eth/tracers/native" + + "github.com/ExocoreNetwork/exocore/x/appchain/coordinator" + coordinatorkeeper "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/keeper" + coordinatortypes "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" ) // Name defines the application binary name @@ -274,6 +278,7 @@ var ( avs.AppModuleBasic{}, oracle.AppModuleBasic{}, distr.AppModuleBasic{}, + coordinator.AppModuleBasic{}, ) // module account permissions @@ -351,15 +356,16 @@ type ExocoreApp struct { EpochsKeeper epochskeeper.Keeper // exocore assets module keepers - AssetsKeeper assetsKeeper.Keeper - DelegationKeeper delegationKeeper.Keeper - RewardKeeper rewardKeeper.Keeper - OperatorKeeper operatorKeeper.Keeper - ExoSlashKeeper slashKeeper.Keeper - AVSManagerKeeper avsManagerKeeper.Keeper - OracleKeeper oracleKeeper.Keeper - ExomintKeeper exomintkeeper.Keeper - DistrKeeper distrkeeper.Keeper + AssetsKeeper assetsKeeper.Keeper + DelegationKeeper delegationKeeper.Keeper + RewardKeeper rewardKeeper.Keeper + OperatorKeeper operatorKeeper.Keeper + ExoSlashKeeper slashKeeper.Keeper + AVSManagerKeeper avsManagerKeeper.Keeper + OracleKeeper oracleKeeper.Keeper + ExomintKeeper exomintkeeper.Keeper + DistrKeeper distrkeeper.Keeper + CoordinatorKeeper coordinatorkeeper.Keeper // the module manager mm *module.Manager @@ -445,6 +451,7 @@ func NewExocoreApp( oracleTypes.StoreKey, exominttypes.StoreKey, distrtypes.StoreKey, + coordinatortypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey, feemarkettypes.TransientKey) @@ -619,6 +626,7 @@ func NewExocoreApp( scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) + scopedIBCProviderKeeper := app.CapabilityKeeper.ScopeToModule(coordinatortypes.ModuleName) // Applications that wish to enforce statically created ScopedKeepers should call `Seal` // after creating their scoped modules in `NewApp` with `ScopeToModule` app.CapabilityKeeper.Seal() @@ -785,22 +793,42 @@ func NewExocoreApp( app.IBCKeeper.SetRouter(ibcRouter) + // we are the x/appchain coordinator chain, so we add the keeper, but + // it's added after IBC to allow communication between chains. + app.CoordinatorKeeper = coordinatorkeeper.NewKeeper( + appCodec, keys[coordinatortypes.StoreKey], + app.AVSManagerKeeper, app.EpochsKeeper, app.OperatorKeeper, + app.StakingKeeper, app.DelegationKeeper, + app.IBCKeeper.ClientKeeper, &app.IBCKeeper.PortKeeper, + scopedIBCProviderKeeper, app.IBCKeeper.ChannelKeeper, + app.IBCKeeper.ConnectionKeeper, app.AccountKeeper, + ) + // set the hooks at the end, after all modules are instantiated. (&app.OperatorKeeper).SetHooks( - app.StakingKeeper.OperatorHooks(), + operatorTypes.NewMultiOperatorHooks( + // the order is not super relevant because these functions are independent + app.StakingKeeper.OperatorHooks(), + app.CoordinatorKeeper.OperatorHooks(), + ), ) (&app.DelegationKeeper).SetHooks( - app.StakingKeeper.DelegationHooks(), + delegationTypes.NewMultiDelegationHooks( + // the order is not super relevant because these functions are independent + app.StakingKeeper.DelegationHooks(), + app.CoordinatorKeeper.DelegationHooks(), + ), ) (&app.EpochsKeeper).SetHooks( epochstypes.NewMultiEpochHooks( - app.DistrKeeper.EpochsHooks(), // come first for using the voting power of last epoch - app.OperatorKeeper.EpochsHooks(), // must come before staking keeper so it can set the USD value - app.StakingKeeper.EpochsHooks(), // at this point, the order is irrelevant. - app.ExomintKeeper.EpochsHooks(), // however, this may change once we have distribution - app.AVSManagerKeeper.EpochsHooks(), // no-op for now + app.DistrKeeper.EpochsHooks(), // come first for using the voting power of last epoch + app.OperatorKeeper.EpochsHooks(), // must come before staking keeper so it can set the USD value + app.ExomintKeeper.EpochsHooks(), // must happen after distribution but not relevant otherwise + app.StakingKeeper.EpochsHooks(), // after operator == good + app.AVSManagerKeeper.EpochsHooks(), // after operator == good + app.CoordinatorKeeper.EpochsHooks(), // after operator == good ), ) diff --git a/utils/utils.go b/utils/utils.go index 563012170..955b50d63 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -283,3 +283,10 @@ func ChainIDWithLenKey(chainID string) []byte { []byte(chainID), ) } + +// PanicIfNil panics if the input is nil with the given message. +func PanicIfNil(x interface{}, msg string) { + if x == nil { + panic("zero or nil value for " + msg) + } +} diff --git a/x/appchain/coordinator/keeper/impl_delegation_hooks.go b/x/appchain/coordinator/keeper/impl_delegation_hooks.go index 3c17bc94c..d52896904 100644 --- a/x/appchain/coordinator/keeper/impl_delegation_hooks.go +++ b/x/appchain/coordinator/keeper/impl_delegation_hooks.go @@ -3,6 +3,7 @@ package keeper import ( "fmt" + "github.com/ExocoreNetwork/exocore/utils" delegationtypes "github.com/ExocoreNetwork/exocore/x/delegation/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -41,46 +42,58 @@ func (wrapper DelegationHooksWrapper) AfterUndelegationStarted( // (2) the undelegation should mature when the operator's opt out matures on the subscriber chain. // within the undelegation situation, the previous keys don't matter, because // they will be replaced anyway. hence, we only need to check the current keys. - chainIDs := wrapper.keeper.operatorKeeper.GetChainIDsForOperator(ctx, operator) + chainIDs, err := wrapper.keeper.operatorKeeper.GetChainIDsForOperator(ctx, operator.String()) + if err != nil { + logger.Error( + "error getting chainIDs for operator", + "operator", operator, + "recordKey", fmt.Sprintf("%x", recordKey), + ) + // do not return an error because that would indicate an undelegation failure. + // TODO: verify the above claim and check the impact of actually returning the error + return nil + } // TODO: above only returns the chainIDs for which the operator is opted-in, but // not those for which the operator is in the process of opting out. this will be // resolved in the unbonding duration calculation pull request and hopefully, // meaningfully unified. for _, chainID := range chainIDs { - found, wrappedKey, _ := wrapper.keeper.operatorKeeper.GetOperatorConsKeyForChainID( - ctx, operator, chainID, - ) - if !found { - logger.Debug( - "operator not opted in; ignoring", - "operator", operator, - "chainID", chainID, + if chainID != utils.ChainIDWithoutRevision(ctx.ChainID()) { + found, wrappedKey, _ := wrapper.keeper.operatorKeeper.GetOperatorConsKeyForChainID( + ctx, operator, chainID, ) - continue - } - var nextVscID uint64 - if wrapper.keeper.operatorKeeper.IsOperatorRemovingKeyFromChainID( - ctx, operator, chainID, - ) { - nextVscID = wrapper.keeper.GetMaturityVscIDForChainIDConsAddr(ctx, chainID, wrappedKey.ToConsAddr()) - if nextVscID == 0 { - logger.Error( - "undelegation maturity epoch not set", + if !found { + logger.Debug( + "operator not opted in; ignoring", "operator", operator, "chainID", chainID, - "consAddr", wrappedKey.ToConsAddr(), - "recordKey", fmt.Sprintf("%x", recordKey), ) - // move on to the next chainID continue } - } else { - nextVscID = wrapper.keeper.GetVscIDForChain(ctx, chainID) + 1 - } - wrapper.keeper.AppendUndelegationToRelease(ctx, chainID, nextVscID, recordKey) - // increment the count for each such chainID - if err := wrapper.keeper.delegationKeeper.IncrementUndelegationHoldCount(ctx, recordKey); err != nil { - return err + var nextVscID uint64 + if wrapper.keeper.operatorKeeper.IsOperatorRemovingKeyFromChainID( + ctx, operator, chainID, + ) { + nextVscID = wrapper.keeper.GetMaturityVscIDForChainIDConsAddr(ctx, chainID, wrappedKey.ToConsAddr()) + if nextVscID == 0 { + logger.Error( + "undelegation maturity epoch not set", + "operator", operator, + "chainID", chainID, + "consAddr", wrappedKey.ToConsAddr(), + "recordKey", fmt.Sprintf("%x", recordKey), + ) + // move on to the next chainID + continue + } + } else { + nextVscID = wrapper.keeper.GetVscIDForChain(ctx, chainID) + 1 + } + wrapper.keeper.AppendUndelegationToRelease(ctx, chainID, nextVscID, recordKey) + // increment the count for each such chainID + if err := wrapper.keeper.delegationKeeper.IncrementUndelegationHoldCount(ctx, recordKey); err != nil { + return err + } } } return nil diff --git a/x/appchain/coordinator/keeper/impl_operator_hooks.go b/x/appchain/coordinator/keeper/impl_operator_hooks.go index aa527e1f1..3241c8907 100644 --- a/x/appchain/coordinator/keeper/impl_operator_hooks.go +++ b/x/appchain/coordinator/keeper/impl_operator_hooks.go @@ -2,6 +2,7 @@ package keeper import ( exocoretypes "github.com/ExocoreNetwork/exocore/types/keys" + "github.com/ExocoreNetwork/exocore/utils" operatortypes "github.com/ExocoreNetwork/exocore/x/operator/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -32,21 +33,23 @@ func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( oldKey exocoretypes.WrappedConsKey, _ exocoretypes.WrappedConsKey, chainID string, ) { - consAddr := oldKey.ToConsAddr() - _, found := h.keeper.GetSubscriberValidatorForChain(ctx, chainID, consAddr) - if found { - // schedule this consensus address for pruning at the maturity of the packet containing this vscID that will - // go out at the end of this epoch. - nextVscID := h.keeper.GetVscIDForChain(ctx, chainID) + 1 - h.keeper.AppendConsAddrToPrune(ctx, chainID, nextVscID, consAddr) - // reverse lookup - h.keeper.SetMaturityVscIDForChainIDConsAddr(ctx, chainID, consAddr, nextVscID) - } else { - // delete the reverse lookup of old cons addr + chain id -> operator addr, since it was never an active - // validator. - h.keeper.operatorKeeper.DeleteOperatorAddressForChainIDAndConsAddr( - ctx, chainID, consAddr, - ) + if chainID != utils.ChainIDWithoutRevision(ctx.ChainID()) { + consAddr := oldKey.ToConsAddr() + _, found := h.keeper.GetSubscriberValidatorForChain(ctx, chainID, consAddr) + if found { + // schedule this consensus address for pruning at the maturity of the packet containing this vscID that will + // go out at the end of this epoch. + nextVscID := h.keeper.GetVscIDForChain(ctx, chainID) + 1 + h.keeper.AppendConsAddrToPrune(ctx, chainID, nextVscID, consAddr) + // reverse lookup + h.keeper.SetMaturityVscIDForChainIDConsAddr(ctx, chainID, consAddr, nextVscID) + } else { + // delete the reverse lookup of old cons addr + chain id -> operator addr, since it was never an active + // validator. + h.keeper.operatorKeeper.DeleteOperatorAddressForChainIDAndConsAddr( + ctx, chainID, consAddr, + ) + } } } @@ -54,20 +57,22 @@ func (h OperatorHooksWrapper) AfterOperatorKeyReplaced( func (h OperatorHooksWrapper) AfterOperatorKeyRemovalInitiated( ctx sdk.Context, _ sdk.AccAddress, chainID string, key exocoretypes.WrappedConsKey, ) { - consAddr := key.ToConsAddr() - _, found := h.keeper.GetSubscriberValidatorForChain(ctx, chainID, consAddr) - if found { - // schedule this consensus address for pruning at the maturity of the packet containing this vscID that will - // go out at the end of this epoch. - nextVscID := h.keeper.GetVscIDForChain(ctx, chainID) + 1 - h.keeper.AppendConsAddrToPrune(ctx, chainID, nextVscID, consAddr) - // reverse lookup - h.keeper.SetMaturityVscIDForChainIDConsAddr(ctx, chainID, consAddr, nextVscID) - } else { - // delete the reverse lookup of old cons addr + chain id -> operator addr, since it was never an active - // validator. - h.keeper.operatorKeeper.DeleteOperatorAddressForChainIDAndConsAddr( - ctx, chainID, consAddr, - ) + if chainID != utils.ChainIDWithoutRevision(ctx.ChainID()) { + consAddr := key.ToConsAddr() + _, found := h.keeper.GetSubscriberValidatorForChain(ctx, chainID, consAddr) + if found { + // schedule this consensus address for pruning at the maturity of the packet containing this vscID that will + // go out at the end of this epoch. + nextVscID := h.keeper.GetVscIDForChain(ctx, chainID) + 1 + h.keeper.AppendConsAddrToPrune(ctx, chainID, nextVscID, consAddr) + // reverse lookup + h.keeper.SetMaturityVscIDForChainIDConsAddr(ctx, chainID, consAddr, nextVscID) + } else { + // delete the reverse lookup of old cons addr + chain id -> operator addr, since it was never an active + // validator. + h.keeper.operatorKeeper.DeleteOperatorAddressForChainIDAndConsAddr( + ctx, chainID, consAddr, + ) + } } } diff --git a/x/appchain/coordinator/keeper/keeper.go b/x/appchain/coordinator/keeper/keeper.go index d783c2267..bd3d95903 100644 --- a/x/appchain/coordinator/keeper/keeper.go +++ b/x/appchain/coordinator/keeper/keeper.go @@ -3,6 +3,7 @@ package keeper import ( "fmt" + "github.com/ExocoreNetwork/exocore/utils" commontypes "github.com/ExocoreNetwork/exocore/x/appchain/common/types" "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types" "github.com/cometbft/cometbft/libs/log" @@ -45,7 +46,7 @@ func NewKeeper( connectionKeeper commontypes.ConnectionKeeper, accountKeeper commontypes.AccountKeeper, ) Keeper { - return Keeper{ + k := Keeper{ cdc: cdc, storeKey: storeKey, avsKeeper: avsKeeper, @@ -60,6 +61,8 @@ func NewKeeper( connectionKeeper: connectionKeeper, accountKeeper: accountKeeper, } + k.mustValidateFields() + return k } // Logger returns a logger object for use within the module. @@ -93,3 +96,22 @@ func (k Keeper) ClaimCapability( ) error { return k.scopedKeeper.ClaimCapability(ctx, cap, name) } + +// mustValidateFields ensures that all the required fields are set. It does not count the number +func (k Keeper) mustValidateFields() { + // TODO: there is no way to count the number of fields here, besides using reflect, which + // fails the Linter. The developer should ensure to add the fields here when adding new fields. + utils.PanicIfNil(k.storeKey, "storeKey") + utils.PanicIfNil(k.cdc, "cdc") + utils.PanicIfNil(k.avsKeeper, "avsKeeper") + utils.PanicIfNil(k.epochsKeeper, "epochsKeeper") + utils.PanicIfNil(k.operatorKeeper, "operatorKeeper") + utils.PanicIfNil(k.stakingKeeper, "stakingKeeper") + utils.PanicIfNil(k.delegationKeeper, "delegationKeeper") + utils.PanicIfNil(k.clientKeeper, "clientKeeper") + utils.PanicIfNil(k.portKeeper, "portKeeper") + utils.PanicIfNil(k.scopedKeeper, "scopedKeeper") + utils.PanicIfNil(k.channelKeeper, "channelKeeper") + utils.PanicIfNil(k.connectionKeeper, "connectionKeeper") + utils.PanicIfNil(k.accountKeeper, "accountKeeper") +} diff --git a/x/appchain/coordinator/keeper/slash.go b/x/appchain/coordinator/keeper/slash.go index e660befdd..c94d65d2d 100644 --- a/x/appchain/coordinator/keeper/slash.go +++ b/x/appchain/coordinator/keeper/slash.go @@ -60,7 +60,7 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data commonty // validator set update; record that here. k.AppendSlashAck(ctx, chainID, consAddress) if err := k.operatorKeeper.ApplySlashForHeight( - ctx, operatorAccAddress, avsAddress.String(), height, + ctx, operatorAccAddress, avsAddress, height, slashProportionDecimal, data.Infraction, jailDuration, ); err != nil { k.Logger(ctx).Error( diff --git a/x/appchain/coordinator/types/expected_keepers.go b/x/appchain/coordinator/types/expected_keepers.go index c5553177c..9c2c60097 100644 --- a/x/appchain/coordinator/types/expected_keepers.go +++ b/x/appchain/coordinator/types/expected_keepers.go @@ -16,8 +16,8 @@ type AVSKeeper interface { RegisterAVSWithChainID( sdk.Context, *avstypes.AVSRegisterOrDeregisterParams, ) (common.Address, error) - IsAVSByChainID(sdk.Context, string) (bool, common.Address) - DeleteAVSInfo(sdk.Context, common.Address) error + IsAVSByChainID(sdk.Context, string) (bool, string) + DeleteAVSInfo(sdk.Context, string) error GetEpochEndChainIDs(sdk.Context, string, int64) []string } @@ -52,7 +52,7 @@ type OperatorKeeper interface { height uint64, fraction sdk.Dec, infraction stakingtypes.Infraction, jailDuration time.Duration, ) error - GetChainIDsForOperator(sdk.Context, sdk.AccAddress) []string + GetChainIDsForOperator(sdk.Context, string) ([]string, error) } // DelegationKeeper represents the expected keeper interface for the delegation module. diff --git a/x/dogfood/keeper/keeper.go b/x/dogfood/keeper/keeper.go index 861a69b82..176689689 100644 --- a/x/dogfood/keeper/keeper.go +++ b/x/dogfood/keeper/keeper.go @@ -17,6 +17,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ExocoreNetwork/exocore/x/dogfood/types" + + "github.com/ExocoreNetwork/exocore/utils" ) type ( @@ -106,13 +108,13 @@ func (k Keeper) ClearEpochEnd(ctx sdk.Context) { } func (k Keeper) mustValidateFields() { - types.PanicIfNil(k.storeKey, "storeKey") - types.PanicIfNil(k.cdc, "cdc") - types.PanicIfNil(k.epochsKeeper, "epochsKeeper") - types.PanicIfNil(k.operatorKeeper, "operatorKeeper") - types.PanicIfNil(k.delegationKeeper, "delegationKeeper") - types.PanicIfNil(k.restakingKeeper, "restakingKeeper") - types.PanicIfNil(k.avsKeeper, "avsKeeper") + utils.PanicIfNil(k.storeKey, "storeKey") + utils.PanicIfNil(k.cdc, "cdc") + utils.PanicIfNil(k.epochsKeeper, "epochsKeeper") + utils.PanicIfNil(k.operatorKeeper, "operatorKeeper") + utils.PanicIfNil(k.delegationKeeper, "delegationKeeper") + utils.PanicIfNil(k.restakingKeeper, "restakingKeeper") + utils.PanicIfNil(k.avsKeeper, "avsKeeper") } // Add the function to get detail information through the operatorKeeper within the dogfood diff --git a/x/dogfood/types/utils.go b/x/dogfood/types/utils.go index e7ca01047..6c613e4c6 100644 --- a/x/dogfood/types/utils.go +++ b/x/dogfood/types/utils.go @@ -14,9 +14,3 @@ func RemoveFromBytesList(list [][]byte, addr []byte) [][]byte { } panic("address not found in list") } - -func PanicIfNil(x interface{}, msg string) { - if x == nil { - panic("zero or nil value for " + msg) - } -} diff --git a/x/operator/keeper/operator.go b/x/operator/keeper/operator.go index e04ed80e4..2dddf9732 100644 --- a/x/operator/keeper/operator.go +++ b/x/operator/keeper/operator.go @@ -196,7 +196,7 @@ func (k *Keeper) GetOptedInAVSForOperator(ctx sdk.Context, operatorAddr string) return avsList, nil } -func (k *Keeper) GetChainIDsForOperator(ctx sdk.Context, operatorAddr string) ([]string, error) { +func (k Keeper) GetChainIDsForOperator(ctx sdk.Context, operatorAddr string) ([]string, error) { addrs, err := k.GetOptedInAVSForOperator(ctx, operatorAddr) if err != nil { return nil, err diff --git a/x/operator/keeper/slash.go b/x/operator/keeper/slash.go index ecf69e32f..189c4e054 100644 --- a/x/operator/keeper/slash.go +++ b/x/operator/keeper/slash.go @@ -2,6 +2,7 @@ package keeper import ( "strings" + "time" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/ethereum/go-ethereum/common/hexutil" @@ -262,3 +263,23 @@ func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress, chainID string) func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress, chainID string) { k.SetJailedState(ctx, consAddr, chainID, false) } + +// ApplySlashForHeight is a function used by x/appchain/coordinator to slash an operator +// based on the historical power and the current assets state. The slashing is made for the +// provided avsAddress. +func (k Keeper) ApplySlashForHeight( + ctx sdk.Context, operatorAccAddress sdk.AccAddress, avsAddress string, + height uint64, fraction sdk.Dec, infraction stakingtypes.Infraction, + jailDuration time.Duration, +) error { + k.Logger(ctx).Info( + "ApplySlashForHeight", + "operatorAccAddress", operatorAccAddress, + "avsAddress", avsAddress, + "height", height, + "fraction", fraction, + "infraction", infraction, + "jailDuration", jailDuration, + ) + return nil +} From c59c3e2f54f396934a8f348da2d3eb08f85769e9 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Tue, 22 Oct 2024 07:32:33 +0000 Subject: [PATCH 50/52] fix(app): add module correctly --- app/app.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/app/app.go b/app/app.go index c71fc85e0..a207a2173 100644 --- a/app/app.go +++ b/app/app.go @@ -787,16 +787,10 @@ func NewExocoreApp( transferStack = transfer.NewIBCModule(app.TransferKeeper) transferStack = erc20.NewIBCMiddleware(app.Erc20Keeper, transferStack) - // Create static IBC router, add transfer route, then set and seal it - ibcRouter := porttypes.NewRouter() - ibcRouter. - AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). - AddRoute(ibctransfertypes.ModuleName, transferStack) - - app.IBCKeeper.SetRouter(ibcRouter) - // we are the x/appchain coordinator chain, so we add the keeper, but // it's added after IBC to allow communication between chains. + // however, it is added before the IBC router is set (and sealed), so that + // it can handle messages from other chains. app.CoordinatorKeeper = coordinatorkeeper.NewKeeper( appCodec, keys[coordinatortypes.StoreKey], app.AVSManagerKeeper, app.EpochsKeeper, app.OperatorKeeper, @@ -806,6 +800,21 @@ func NewExocoreApp( app.IBCKeeper.ConnectionKeeper, app.AccountKeeper, ) + coordinatorModule := coordinator.NewAppModule( + appCodec, + app.CoordinatorKeeper, + ) + coordinatorIbcModule := coordinator.NewIBCModule(app.CoordinatorKeeper) + + // Create static IBC router, add transfer route, then set and seal it + ibcRouter := porttypes.NewRouter() + ibcRouter. + AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). + AddRoute(ibctransfertypes.ModuleName, transferStack). + AddRoute(coordinatortypes.ModuleName, coordinatorIbcModule) + + app.IBCKeeper.SetRouter(ibcRouter) + // set the hooks at the end, after all modules are instantiated. (&app.OperatorKeeper).SetHooks( operatorTypes.NewMultiOperatorHooks( @@ -929,6 +938,7 @@ func NewExocoreApp( avs.NewAppModule(appCodec, app.AVSManagerKeeper), oracle.NewAppModule(appCodec, app.OracleKeeper, app.AccountKeeper, app.BankKeeper), distr.NewAppModule(appCodec, app.DistrKeeper), + coordinatorModule, ) // During begin block slashing happens after reward.BeginBlocker so that @@ -967,6 +977,7 @@ func NewExocoreApp( avsManagerTypes.ModuleName, oracleTypes.ModuleName, distrtypes.ModuleName, + coordinatortypes.ModuleName, ) app.mm.SetOrderEndBlockers( @@ -1001,6 +1012,7 @@ func NewExocoreApp( exoslashTypes.ModuleName, avsManagerTypes.ModuleName, distrtypes.ModuleName, + coordinatortypes.ModuleName, // op module feemarkettypes.ModuleName, // last in order to retrieve the block gas used ) @@ -1043,6 +1055,7 @@ func NewExocoreApp( rewardTypes.ModuleName, // not fully implemented yet exoslashTypes.ModuleName, // not fully implemented yet distrtypes.ModuleName, + coordinatortypes.ModuleName, // not fully implemented yet // must be the last module after others have been set up, so that it can check // the invariants (if configured to do so). crisistypes.ModuleName, From cfca848b795e27382a45687deb408a09f682c243 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:33:16 +0000 Subject: [PATCH 51/52] refactor: rename function param for clarity --- utils/utils.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/utils.go b/utils/utils.go index d20814e59..c76861573 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -246,9 +246,9 @@ func AccumulateChanges( } // AppendMany appends a variable number of byte slices together -func AppendMany(byteses ...[]byte) (out []byte) { - for _, bytes := range byteses { - out = append(out, bytes...) +func AppendMany(slices ...[]byte) (out []byte) { + for _, slice := range slices { + out = append(out, slice...) } return out } From 0ca361dd2b16d1eaeb275f013bd7c3775a36aa20 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:33:37 +0000 Subject: [PATCH 52/52] refactor: rename object for clarity --- x/appchain/subscriber/types/validator.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x/appchain/subscriber/types/validator.go b/x/appchain/subscriber/types/validator.go index 7ab49887b..37462d3b8 100644 --- a/x/appchain/subscriber/types/validator.go +++ b/x/appchain/subscriber/types/validator.go @@ -26,14 +26,14 @@ func NewSubscriberChainValidator( // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces. // It is required to ensure that ConsPubKey below works. -func (ocv SubscriberChainValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { +func (scv SubscriberChainValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { var pk cryptotypes.PubKey - return unpacker.UnpackAny(ocv.Pubkey, &pk) + return unpacker.UnpackAny(scv.Pubkey, &pk) } // ConsPubKey returns the validator PubKey as a cryptotypes.PubKey. -func (ocv SubscriberChainValidator) ConsPubKey() (cryptotypes.PubKey, error) { - pk, ok := ocv.Pubkey.GetCachedValue().(cryptotypes.PubKey) +func (scv SubscriberChainValidator) ConsPubKey() (cryptotypes.PubKey, error) { + pk, ok := scv.Pubkey.GetCachedValue().(cryptotypes.PubKey) if !ok { return nil, errorsmod.Wrapf( sdkerrors.ErrInvalidType,