From ad0f5ce3a8e3b242f628116458ea6efe07bff878 Mon Sep 17 00:00:00 2001 From: krhubert Date: Thu, 6 Feb 2020 19:47:32 +0100 Subject: [PATCH] Use template to move ownership cosmos module to x/ dir --- app/app.go | 15 +- core/main.go | 2 +- cosmos/client.go | 20 ++- sdk/ownership/keeper.go | 97 ------------ sdk/ownership/module.go | 37 ----- sdk/ownership/sdk.go | 28 ---- sdk/process/keeper.go | 10 +- sdk/sdk.go | 4 - sdk/service/keeper.go | 16 +- server/grpc/api/ownership.go | 18 ++- server/grpc/server.go | 12 +- server/grpc/server_test.go | 2 +- x/ownership/abci.go | 13 ++ x/ownership/alias.go | 35 +++++ x/ownership/client/cli/query.go | 50 +++++++ x/ownership/client/cli/tx.go | 26 ++++ x/ownership/client/rest/query.go | 39 +++++ x/ownership/client/rest/rest.go | 13 ++ x/ownership/client/rest/tx.go | 9 ++ x/ownership/genesis.go | 18 +++ x/ownership/handler.go | 17 +++ x/ownership/internal/keeper/keeper.go | 104 +++++++++++++ x/ownership/internal/keeper/querier.go | 33 +++++ x/ownership/internal/types/codec.go | 18 +++ .../internal/types/expected_keepers.go | 14 ++ x/ownership/internal/types/genesis.go | 19 +++ x/ownership/internal/types/key.go | 14 ++ x/ownership/internal/types/params.go | 38 +++++ x/ownership/internal/types/querier.go | 6 + x/ownership/module.go | 139 ++++++++++++++++++ 30 files changed, 668 insertions(+), 198 deletions(-) delete mode 100644 sdk/ownership/keeper.go delete mode 100644 sdk/ownership/module.go delete mode 100644 sdk/ownership/sdk.go create mode 100644 x/ownership/abci.go create mode 100644 x/ownership/alias.go create mode 100644 x/ownership/client/cli/query.go create mode 100644 x/ownership/client/cli/tx.go create mode 100644 x/ownership/client/rest/query.go create mode 100644 x/ownership/client/rest/rest.go create mode 100644 x/ownership/client/rest/tx.go create mode 100644 x/ownership/genesis.go create mode 100644 x/ownership/handler.go create mode 100644 x/ownership/internal/keeper/keeper.go create mode 100644 x/ownership/internal/keeper/querier.go create mode 100644 x/ownership/internal/types/codec.go create mode 100644 x/ownership/internal/types/expected_keepers.go create mode 100644 x/ownership/internal/types/genesis.go create mode 100644 x/ownership/internal/types/key.go create mode 100644 x/ownership/internal/types/params.go create mode 100644 x/ownership/internal/types/querier.go create mode 100644 x/ownership/module.go diff --git a/app/app.go b/app/app.go index b441bf99c..295d562b1 100644 --- a/app/app.go +++ b/app/app.go @@ -28,9 +28,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/supply" mesgcodec "github.com/mesg-foundation/engine/codec" "github.com/mesg-foundation/engine/cosmos" + "github.com/mesg-foundation/engine/x/ownership" executionsdk "github.com/mesg-foundation/engine/sdk/execution" instancesdk "github.com/mesg-foundation/engine/sdk/instance" - ownershipsdk "github.com/mesg-foundation/engine/sdk/ownership" processsdk "github.com/mesg-foundation/engine/sdk/process" runnersdk "github.com/mesg-foundation/engine/sdk/runner" servicesdk "github.com/mesg-foundation/engine/sdk/service" @@ -59,7 +59,7 @@ var ( supply.AppModuleBasic{}, // Engine's AppModuleBasic - cosmos.NewAppModuleBasic(ownershipsdk.ModuleName), + cosmos.NewAppModuleBasic(ownership.ModuleName), cosmos.NewAppModuleBasic(servicesdk.ModuleName), cosmos.NewAppModuleBasic(instancesdk.ModuleName), cosmos.NewAppModuleBasic(runnersdk.ModuleName), @@ -84,6 +84,7 @@ func MakeCodec() *codec.Codec { ModuleBasics.RegisterCodec(mesgcodec.Codec) vesting.RegisterCodec(mesgcodec.Codec) + ownership.RegisterCodec(mesgcodec.Codec) // sdk.RegisterCodec(cdc) // codec.RegisterCrypto(cdc) @@ -115,7 +116,7 @@ type NewApp struct { paramsKeeper params.Keeper // Engine's keepers - ownershipKeeper *ownershipsdk.Keeper + ownershipKeeper ownership.Keeper serviceKeeper *servicesdk.Keeper instanceKeeper *instancesdk.Keeper runnerKeeper *runnersdk.Keeper @@ -155,7 +156,7 @@ func NewInitApp( params.StoreKey, // Engine's module keys - ownershipsdk.ModuleName, + ownership.ModuleName, servicesdk.ModuleName, instancesdk.ModuleName, runnersdk.ModuleName, @@ -242,7 +243,7 @@ func NewInitApp( ) // Engine's module keepers - app.ownershipKeeper = ownershipsdk.NewKeeper(keys[ownershipsdk.ModuleName]) + app.ownershipKeeper = ownership.NewKeeper(app.cdc, keys[ownership.ModuleName]) app.serviceKeeper = servicesdk.NewKeeper(keys[servicesdk.ModuleName], app.ownershipKeeper) app.instanceKeeper = instancesdk.NewKeeper(keys[instancesdk.ModuleName]) app.runnerKeeper = runnersdk.NewKeeper(keys[runnersdk.ModuleName], app.instanceKeeper) @@ -260,7 +261,7 @@ func NewInitApp( slashing.NewAppModule(app.slashingKeeper, app.accountKeeper, app.stakingKeeper), // Engine's modules - ownershipsdk.NewModule(app.ownershipKeeper), + ownership.NewAppModule(app.ownershipKeeper), servicesdk.NewModule(app.serviceKeeper), instancesdk.NewModule(app.instanceKeeper), runnersdk.NewModule(app.runnerKeeper), @@ -287,7 +288,7 @@ func NewInitApp( slashing.ModuleName, // Engine's modules - ownershipsdk.ModuleName, + ownership.ModuleName, servicesdk.ModuleName, instancesdk.ModuleName, runnersdk.ModuleName, diff --git a/core/main.go b/core/main.go index f5daa91b3..5da37b9d7 100644 --- a/core/main.go +++ b/core/main.go @@ -191,7 +191,7 @@ func main() { } // init gRPC server. - server := grpc.New(sdk, cfg) + server := grpc.New(sdk, cfg, client) logrus.WithField("module", "main").Infof("starting MESG Engine version %s", version.Version) diff --git a/cosmos/client.go b/cosmos/client.go index ab8a9bff9..38c67ca19 100644 --- a/cosmos/client.go +++ b/cosmos/client.go @@ -15,9 +15,9 @@ import ( authExported "github.com/cosmos/cosmos-sdk/x/auth/exported" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/mesg-foundation/engine/codec" - "github.com/mesg-foundation/engine/hash" "github.com/mesg-foundation/engine/ext/xreflect" "github.com/mesg-foundation/engine/ext/xstrings" + "github.com/mesg-foundation/engine/hash" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/node" rpcclient "github.com/tendermint/tendermint/rpc/client" @@ -55,6 +55,24 @@ func NewClient(node *node.Node, kb keys.Keybase, chainID, accName, accPassword, }, nil } +// QueryJSON is abci.query wrapper with errors check and decode data. +func (c *Client) QueryJSON(path string, qdata, ptr interface{}) error { + var data []byte + if !xreflect.IsNil(qdata) { + b, err := codec.MarshalJSON(qdata) + if err != nil { + return err + } + data = b + } + + result, _, err := c.QueryWithData(path, data) + if err != nil { + return err + } + return codec.UnmarshalJSON(result, ptr) +} + // Query is abci.query wrapper with errors check and decode data. func (c *Client) Query(path string, qdata, ptr interface{}) error { var data []byte diff --git a/sdk/ownership/keeper.go b/sdk/ownership/keeper.go deleted file mode 100644 index 31cda1ad3..000000000 --- a/sdk/ownership/keeper.go +++ /dev/null @@ -1,97 +0,0 @@ -package ownershipsdk - -import ( - "fmt" - - cosmostypes "github.com/cosmos/cosmos-sdk/types" - "github.com/mesg-foundation/engine/codec" - "github.com/mesg-foundation/engine/hash" - "github.com/mesg-foundation/engine/ownership" -) - -// Keeper holds the logic to read and write data. -type Keeper struct { - storeKey *cosmostypes.KVStoreKey -} - -// NewKeeper initialize a new keeper. -func NewKeeper(storeKey *cosmostypes.KVStoreKey) *Keeper { - return &Keeper{ - storeKey: storeKey, - } -} - -// Create creates a new ownership. -func (k *Keeper) Create(req cosmostypes.Request, owner cosmostypes.AccAddress, resourceHash hash.Hash, resource ownership.Ownership_Resource) (*ownership.Ownership, error) { - store := req.KVStore(k.storeKey) - hashes := findOwnerships(store, "", resourceHash) - if len(hashes) > 0 { - return nil, fmt.Errorf("resource %s:%q already has an owner", resource, resourceHash) - } - ownership := &ownership.Ownership{ - Owner: owner.String(), - Resource: resource, - ResourceHash: resourceHash, - } - ownership.Hash = hash.Dump(ownership) - - value, err := codec.MarshalBinaryBare(ownership) - if err != nil { - return nil, err - } - store.Set(ownership.Hash, value) - return ownership, nil -} - -// Delete deletes a ownership. -func (k *Keeper) Delete(req cosmostypes.Request, owner cosmostypes.AccAddress, resourceHash hash.Hash) error { - store := req.KVStore(k.storeKey) - hashes := findOwnerships(store, owner.String(), resourceHash) - if len(hashes) == 0 { - return fmt.Errorf("resource %q do not have any ownership", resourceHash) - } - - for _, hash := range hashes { - store.Delete(hash) - } - return nil -} - -// List returns all ownerships. -func (k *Keeper) List(req cosmostypes.Request) ([]*ownership.Ownership, error) { - var ( - ownerships []*ownership.Ownership - iter = req.KVStore(k.storeKey).Iterator(nil, nil) - ) - defer iter.Close() - - for iter.Valid() { - var o *ownership.Ownership - if err := codec.UnmarshalBinaryBare(iter.Value(), &o); err != nil { - return nil, err - } - ownerships = append(ownerships, o) - iter.Next() - } - return ownerships, nil -} - -// hasOwner checks if given resource has owner. Returns all ownership hash and true if has one -// nil and false otherwise. -func findOwnerships(store cosmostypes.KVStore, owner string, resourceHash hash.Hash) []hash.Hash { - var ownerships []hash.Hash - iter := store.Iterator(nil, nil) - - for iter.Valid() { - var o *ownership.Ownership - if err := codec.UnmarshalBinaryBare(iter.Value(), &o); err == nil { - if (owner == "" || o.Owner == owner) && o.ResourceHash.Equal(resourceHash) { - ownerships = append(ownerships, o.Hash) - } - } - iter.Next() - } - - iter.Close() - return ownerships -} diff --git a/sdk/ownership/module.go b/sdk/ownership/module.go deleted file mode 100644 index 5ed26b8e8..000000000 --- a/sdk/ownership/module.go +++ /dev/null @@ -1,37 +0,0 @@ -package ownershipsdk - -import ( - "fmt" - - cosmostypes "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/mesg-foundation/engine/cosmos" - "github.com/mesg-foundation/engine/hash" - abci "github.com/tendermint/tendermint/abci/types" -) - -// ModuleName is the name of this module. -const ModuleName = "ownership" - -// NewModule returns the module of this sdk. -func NewModule(k *Keeper) module.AppModule { - return cosmos.NewAppModule(cosmos.NewAppModuleBasic(ModuleName), handler(k), querier(k)) -} - -func handler(k *Keeper) cosmos.Handler { - return func(request cosmostypes.Request, msg cosmostypes.Msg) (hash.Hash, error) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "Unrecognized ownership Msg type: %v", msg.Type()) - } -} - -func querier(k *Keeper) cosmos.Querier { - return func(request cosmostypes.Request, path []string, req abci.RequestQuery) (res interface{}, err error) { - switch path[0] { - case "list": - return k.List(request) - default: - return nil, fmt.Errorf("unknown ownership query endpoint %s", path[0]) - } - } -} diff --git a/sdk/ownership/sdk.go b/sdk/ownership/sdk.go deleted file mode 100644 index 9c7717d73..000000000 --- a/sdk/ownership/sdk.go +++ /dev/null @@ -1,28 +0,0 @@ -package ownershipsdk - -import ( - "github.com/mesg-foundation/engine/cosmos" - "github.com/mesg-foundation/engine/ownership" -) - -// SDK is the ownership sdk. -type SDK struct { - client *cosmos.Client -} - -// New returns the ownership sdk. -func New(client *cosmos.Client) *SDK { - sdk := &SDK{ - client: client, - } - return sdk -} - -// List returns all ownerships. -func (s *SDK) List() ([]*ownership.Ownership, error) { - var ownerships []*ownership.Ownership - if err := s.client.Query("custom/"+ModuleName+"/list", nil, &ownerships); err != nil { - return nil, err - } - return ownerships, nil -} diff --git a/sdk/process/keeper.go b/sdk/process/keeper.go index 9e8fab7d4..c4a51aa19 100644 --- a/sdk/process/keeper.go +++ b/sdk/process/keeper.go @@ -6,21 +6,21 @@ import ( cosmostypes "github.com/cosmos/cosmos-sdk/types" "github.com/mesg-foundation/engine/codec" "github.com/mesg-foundation/engine/hash" - "github.com/mesg-foundation/engine/ownership" + ownershippb "github.com/mesg-foundation/engine/ownership" "github.com/mesg-foundation/engine/process" instancesdk "github.com/mesg-foundation/engine/sdk/instance" - ownershipsdk "github.com/mesg-foundation/engine/sdk/ownership" + "github.com/mesg-foundation/engine/x/ownership" ) // Keeper is the service keeper. type Keeper struct { storeKey *cosmostypes.KVStoreKey - ownershipKeeper *ownershipsdk.Keeper + ownershipKeeper ownership.Keeper instanceKeeper *instancesdk.Keeper } // NewKeeper returns the keeper of the service sdk. -func NewKeeper(storeKey *cosmostypes.KVStoreKey, ownershipKeeper *ownershipsdk.Keeper, instanceKeeper *instancesdk.Keeper) *Keeper { +func NewKeeper(storeKey *cosmostypes.KVStoreKey, ownershipKeeper ownership.Keeper, instanceKeeper *instancesdk.Keeper) *Keeper { return &Keeper{ storeKey: storeKey, ownershipKeeper: ownershipKeeper, @@ -63,7 +63,7 @@ func (k *Keeper) Create(req cosmostypes.Request, msg *msgCreateProcess) (*proces return nil, err } - if _, err := k.ownershipKeeper.Create(req, msg.Owner, p.Hash, ownership.Ownership_Process); err != nil { + if _, err := k.ownershipKeeper.Set(req, msg.Owner, p.Hash, ownershippb.Ownership_Process); err != nil { return nil, err } diff --git a/sdk/sdk.go b/sdk/sdk.go index 3d6867230..c1f511d83 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -7,7 +7,6 @@ import ( eventsdk "github.com/mesg-foundation/engine/sdk/event" executionsdk "github.com/mesg-foundation/engine/sdk/execution" instancesdk "github.com/mesg-foundation/engine/sdk/instance" - ownershipsdk "github.com/mesg-foundation/engine/sdk/ownership" processesdk "github.com/mesg-foundation/engine/sdk/process" runnersdk "github.com/mesg-foundation/engine/sdk/runner" servicesdk "github.com/mesg-foundation/engine/sdk/service" @@ -20,7 +19,6 @@ type SDK struct { Execution *executionsdk.SDK Event *eventsdk.Event Process *processesdk.SDK - Ownership *ownershipsdk.SDK Runner *runnersdk.SDK } @@ -28,7 +26,6 @@ type SDK struct { func New(client *cosmos.Client, kb *cosmos.Keybase, container container.Container, engineName, port, ipfsEndpoint string) *SDK { ps := pubsub.New(0) serviceSDK := servicesdk.New(client) - ownershipSDK := ownershipsdk.New(client) instanceSDK := instancesdk.New(client) runnerSDK := runnersdk.New(client, serviceSDK, instanceSDK, container, engineName, port, ipfsEndpoint) processSDK := processesdk.New(client) @@ -40,7 +37,6 @@ func New(client *cosmos.Client, kb *cosmos.Keybase, container container.Containe Execution: executionSDK, Event: eventSDK, Process: processSDK, - Ownership: ownershipSDK, Runner: runnerSDK, } } diff --git a/sdk/service/keeper.go b/sdk/service/keeper.go index 7896dc888..798908495 100644 --- a/sdk/service/keeper.go +++ b/sdk/service/keeper.go @@ -6,24 +6,24 @@ import ( cosmostypes "github.com/cosmos/cosmos-sdk/types" "github.com/mesg-foundation/engine/codec" "github.com/mesg-foundation/engine/hash" - "github.com/mesg-foundation/engine/ownership" + "github.com/mesg-foundation/engine/x/ownership" + ownershippb "github.com/mesg-foundation/engine/ownership" "github.com/mesg-foundation/engine/protobuf/api" - ownershipsdk "github.com/mesg-foundation/engine/sdk/ownership" "github.com/mesg-foundation/engine/service" "github.com/mesg-foundation/engine/service/validator" ) // Keeper holds the logic to read and write data. type Keeper struct { - storeKey *cosmostypes.KVStoreKey - ownerships *ownershipsdk.Keeper + storeKey *cosmostypes.KVStoreKey + ownershipKeeper ownership.Keeper } // NewKeeper initialize a new keeper. -func NewKeeper(storeKey *cosmostypes.KVStoreKey, ownerships *ownershipsdk.Keeper) *Keeper { +func NewKeeper(storeKey *cosmostypes.KVStoreKey, ownershipKeeper ownership.Keeper) *Keeper { return &Keeper{ - storeKey: storeKey, - ownerships: ownerships, + storeKey: storeKey, + ownershipKeeper: ownershipKeeper, } } @@ -48,7 +48,7 @@ func (k *Keeper) Create(request cosmostypes.Request, msg *msgCreateService) (*se return nil, err } - if _, err := k.ownerships.Create(request, msg.Owner, srv.Hash, ownership.Ownership_Service); err != nil { + if _, err := k.ownershipKeeper.Set(request, msg.Owner, srv.Hash, ownershippb.Ownership_Service); err != nil { return nil, err } diff --git a/server/grpc/api/ownership.go b/server/grpc/api/ownership.go index 0e5024d84..529916307 100644 --- a/server/grpc/api/ownership.go +++ b/server/grpc/api/ownership.go @@ -3,26 +3,32 @@ package api import ( "context" + "github.com/mesg-foundation/engine/cosmos" + ownershippb "github.com/mesg-foundation/engine/ownership" protobuf_api "github.com/mesg-foundation/engine/protobuf/api" "github.com/mesg-foundation/engine/sdk" + "github.com/mesg-foundation/engine/x/ownership" ) // OwnershipServer is the type to aggregate all Ownership APIs. type OwnershipServer struct { - sdk *sdk.SDK + sdk *sdk.SDK + client *cosmos.Client } // NewOwnershipServer creates a new OwnershipServer. -func NewOwnershipServer(sdk *sdk.SDK) *OwnershipServer { - return &OwnershipServer{sdk: sdk} +func NewOwnershipServer(sdk *sdk.SDK, client *cosmos.Client) *OwnershipServer { + return &OwnershipServer{ + sdk: sdk, + client: client, + } } // List returns all ownerships. func (s *OwnershipServer) List(ctx context.Context, req *protobuf_api.ListOwnershipRequest) (*protobuf_api.ListOwnershipResponse, error) { - ownerships, err := s.sdk.Ownership.List() - if err != nil { + var ownerships []*ownershippb.Ownership + if err := s.client.QueryJSON("custom/"+ownership.ModuleName+"/"+ownership.QueryListOwnerships, nil, &ownerships); err != nil { return nil, err } - return &protobuf_api.ListOwnershipResponse{Ownerships: ownerships}, nil } diff --git a/server/grpc/server.go b/server/grpc/server.go index eb255e92e..465541898 100644 --- a/server/grpc/server.go +++ b/server/grpc/server.go @@ -9,6 +9,7 @@ import ( grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/mesg-foundation/engine/config" + "github.com/mesg-foundation/engine/cosmos" protobuf_api "github.com/mesg-foundation/engine/protobuf/api" "github.com/mesg-foundation/engine/sdk" "github.com/mesg-foundation/engine/server/grpc/api" @@ -24,11 +25,16 @@ type Server struct { instance *grpc.Server sdk *sdk.SDK cfg *config.Config + client *cosmos.Client } // New returns a new gRPC server. -func New(sdk *sdk.SDK, cfg *config.Config) *Server { - return &Server{sdk: sdk, cfg: cfg} +func New(sdk *sdk.SDK, cfg *config.Config, client *cosmos.Client) *Server { + return &Server{ + sdk: sdk, + cfg: cfg, + client: client, + } } // Serve listens for connections. @@ -80,7 +86,7 @@ func (s *Server) register() { protobuf_api.RegisterInstanceServer(s.instance, api.NewInstanceServer(s.sdk)) protobuf_api.RegisterServiceServer(s.instance, api.NewServiceServer(s.sdk)) protobuf_api.RegisterProcessServer(s.instance, api.NewProcessServer(s.sdk)) - protobuf_api.RegisterOwnershipServer(s.instance, api.NewOwnershipServer(s.sdk)) + protobuf_api.RegisterOwnershipServer(s.instance, api.NewOwnershipServer(s.sdk, s.client)) protobuf_api.RegisterRunnerServer(s.instance, api.NewRunnerServer(s.sdk)) reflection.Register(s.instance) diff --git a/server/grpc/server_test.go b/server/grpc/server_test.go index cee473192..207295145 100644 --- a/server/grpc/server_test.go +++ b/server/grpc/server_test.go @@ -8,7 +8,7 @@ import ( ) func TestServerServe(t *testing.T) { - s := New(nil, nil) + s := New(nil, nil, nil) go func() { time.Sleep(500 * time.Millisecond) s.Close() diff --git a/x/ownership/abci.go b/x/ownership/abci.go new file mode 100644 index 000000000..c7ec36a3d --- /dev/null +++ b/x/ownership/abci.go @@ -0,0 +1,13 @@ +package ownership + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +// BeginBlocker check for infraction evidence or downtime of validators +// on every begin block +func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k Keeper) {} + +// EndBlocker called every block, process inflation, update validator set. +func EndBlocker(ctx sdk.Context, k Keeper) {} diff --git a/x/ownership/alias.go b/x/ownership/alias.go new file mode 100644 index 000000000..c4f00e3a2 --- /dev/null +++ b/x/ownership/alias.go @@ -0,0 +1,35 @@ +package ownership + +import ( + "github.com/mesg-foundation/engine/x/ownership/internal/keeper" + "github.com/mesg-foundation/engine/x/ownership/internal/types" +) + +// const aliases +const ( + ModuleName = types.ModuleName + RouterKey = types.RouterKey + StoreKey = types.StoreKey + DefaultParamspace = types.DefaultParamspace + QuerierRoute = types.QuerierRoute +) + +// functions and variable aliases +var ( + NewKeeper = keeper.NewKeeper + NewQuerier = keeper.NewQuerier + RegisterCodec = types.RegisterCodec + NewGenesisState = types.NewGenesisState + DefaultGenesisState = types.DefaultGenesisState + ValidateGenesis = types.ValidateGenesis + + ModuleCdc = types.ModuleCdc + QueryListOwnerships = types.QueryListOwnerships +) + +// module types +type ( + Keeper = keeper.Keeper + GenesisState = types.GenesisState + Params = types.Params +) diff --git a/x/ownership/client/cli/query.go b/x/ownership/client/cli/query.go new file mode 100644 index 000000000..8b15c79b8 --- /dev/null +++ b/x/ownership/client/cli/query.go @@ -0,0 +1,50 @@ +package cli + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/mesg-foundation/engine/ownership" + "github.com/mesg-foundation/engine/x/ownership/internal/types" + "github.com/spf13/cobra" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { + // Group ownership queries under a subcommand + ownershipQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + ownershipQueryCmd.AddCommand( + flags.GetCommands()..., + ) + + return ownershipQueryCmd +} + +func GetCmdListOwnerships(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "list", + Short: "list", + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/"+types.QueryListOwnerships, queryRoute), nil) + if err != nil { + fmt.Printf("could not get scavenges\n%s\n", err.Error()) + return nil + } + + var out []*ownership.Ownership + cdc.MustUnmarshalJSON(res, &out) + return cliCtx.PrintOutput(out) + }, + } +} diff --git a/x/ownership/client/cli/tx.go b/x/ownership/client/cli/tx.go new file mode 100644 index 000000000..67ad67c77 --- /dev/null +++ b/x/ownership/client/cli/tx.go @@ -0,0 +1,26 @@ +package cli + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/mesg-foundation/engine/x/ownership/internal/types" + "github.com/spf13/cobra" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + ownershipTxCmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + ownershipTxCmd.AddCommand(flags.PostCommands()...) + + return ownershipTxCmd +} diff --git a/x/ownership/client/rest/query.go b/x/ownership/client/rest/query.go new file mode 100644 index 000000000..62598ed89 --- /dev/null +++ b/x/ownership/client/rest/query.go @@ -0,0 +1,39 @@ +package rest + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/mesg-foundation/engine/x/ownership/internal/types" +) + +func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { + r.HandleFunc( + "/ownership/parameters", + queryParamsHandlerFn(cliCtx), + ).Methods("GET") +} + +func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + route := fmt.Sprintf("custom/%s/parameters", types.QuerierRoute) + + res, height, err := cliCtx.QueryWithData(route, nil) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) + } +} diff --git a/x/ownership/client/rest/rest.go b/x/ownership/client/rest/rest.go new file mode 100644 index 000000000..ca9a5c63d --- /dev/null +++ b/x/ownership/client/rest/rest.go @@ -0,0 +1,13 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" +) + +// RegisterRoutes registers ownership-related REST handlers to a router +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) { + registerQueryRoutes(cliCtx, r) + registerTxRoutes(cliCtx, r) +} diff --git a/x/ownership/client/rest/tx.go b/x/ownership/client/rest/tx.go new file mode 100644 index 000000000..ae173af7c --- /dev/null +++ b/x/ownership/client/rest/tx.go @@ -0,0 +1,9 @@ +package rest + +import ( + "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" +) + +func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {} diff --git a/x/ownership/genesis.go b/x/ownership/genesis.go new file mode 100644 index 000000000..2fac591fe --- /dev/null +++ b/x/ownership/genesis.go @@ -0,0 +1,18 @@ +package ownership + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/mesg-foundation/engine/x/ownership/internal/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +// InitGenesis initialize default parameters and the keeper's address to pubkey map. +func InitGenesis(ctx sdk.Context, k Keeper, data types.GenesisState) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ExportGenesis writes the current store values // to a genesis file, +// which can be imported again with InitGenesis. +func ExportGenesis(ctx sdk.Context, k Keeper) types.GenesisState { + return types.NewGenesisState() +} diff --git a/x/ownership/handler.go b/x/ownership/handler.go new file mode 100644 index 000000000..322eb7fc0 --- /dev/null +++ b/x/ownership/handler.go @@ -0,0 +1,17 @@ +package ownership + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/mesg-foundation/engine/x/ownership/internal/types" +) + +// NewHandler creates an sdk.Handler for all the instance type messages +func NewHandler(k Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg) + return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) + } +} diff --git a/x/ownership/internal/keeper/keeper.go b/x/ownership/internal/keeper/keeper.go new file mode 100644 index 000000000..ccb85249f --- /dev/null +++ b/x/ownership/internal/keeper/keeper.go @@ -0,0 +1,104 @@ +package keeper + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/mesg-foundation/engine/hash" + "github.com/mesg-foundation/engine/x/ownership/internal/types" + "github.com/mesg-foundation/engine/ownership" + "github.com/tendermint/tendermint/libs/log" +) + +// Keeper of the ownership store +type Keeper struct { + storeKey sdk.StoreKey + cdc *codec.Codec +} + +// NewKeeper creates a ownership keeper +func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper { + keeper := Keeper{ + storeKey: key, + cdc: cdc, + } + return keeper +} + +// 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)) +} + +// List returns all ownerships. +func (k *Keeper) List(ctx sdk.Context) ([]*ownership.Ownership, error) { + var ( + ownerships []*ownership.Ownership + iter = ctx.KVStore(k.storeKey).Iterator(nil, nil) + ) + defer iter.Close() + + for iter.Valid() { + var o *ownership.Ownership + if err := k.cdc.UnmarshalBinaryLengthPrefixed(iter.Value(), &o); err != nil { + return nil, err + } + ownerships = append(ownerships, o) + iter.Next() + } + return ownerships, nil +} + +// Set creates a new ownership. +func (k Keeper) Set(ctx sdk.Context, owner sdk.AccAddress, resourceHash hash.Hash, resource ownership.Ownership_Resource) (*ownership.Ownership, error) { + store := ctx.KVStore(k.storeKey) + hashes := k.findOwnerships(store, "", resourceHash) + if len(hashes) > 0 { + return nil, fmt.Errorf("resource %s:%q already has an owner", resource, resourceHash) + } + + ownership := &ownership.Ownership{ + Owner: owner.String(), + Resource: resource, + ResourceHash: resourceHash, + } + ownership.Hash = hash.Dump(ownership) + + store.Set(ownership.Hash, k.cdc.MustMarshalBinaryLengthPrefixed(ownership)) + return ownership, nil +} + +// Delete deletes an ownership. +func (k Keeper) Delete(ctx sdk.Context, owner sdk.AccAddress, resourceHash hash.Hash) error { + store := ctx.KVStore(k.storeKey) + hashes := k.findOwnerships(store, owner.String(), resourceHash) + if len(hashes) == 0 { + return fmt.Errorf("resource %q do not have any ownership", resourceHash) + } + + for _, hash := range hashes { + store.Delete(hash) + } + return nil +} + +// hasOwner checks if given resource has owner. Returns all ownership hash and true if has one +// nil and false otherwise. +func (k Keeper) findOwnerships(store sdk.KVStore, owner string, resourceHash hash.Hash) []hash.Hash { + var ownerships []hash.Hash + iter := store.Iterator(nil, nil) + + for iter.Valid() { + var o *ownership.Ownership + if err := k.cdc.UnmarshalBinaryBare(iter.Value(), &o); err == nil { + if (owner == "" || o.Owner == owner) && o.ResourceHash.Equal(resourceHash) { + ownerships = append(ownerships, o.Hash) + } + } + iter.Next() + } + + iter.Close() + return ownerships +} diff --git a/x/ownership/internal/keeper/querier.go b/x/ownership/internal/keeper/querier.go new file mode 100644 index 000000000..9dd8b3117 --- /dev/null +++ b/x/ownership/internal/keeper/querier.go @@ -0,0 +1,33 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/mesg-foundation/engine/x/ownership/internal/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +// NewQuerier creates a new querier for ownership clients. +func NewQuerier(k Keeper) sdk.Querier { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { + switch path[0] { + case types.QueryListOwnerships: + return listOwnerships(ctx, k) + default: + return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown ownership query endpoint") + } + } +} + +func listOwnerships(ctx sdk.Context, k Keeper) ([]byte, error) { + ownerships, err := k.List(ctx) + if err != nil { + return nil, err + } + + res, err := types.ModuleCdc.MarshalJSON(ownerships) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + return res, nil +} diff --git a/x/ownership/internal/types/codec.go b/x/ownership/internal/types/codec.go new file mode 100644 index 000000000..b243782e1 --- /dev/null +++ b/x/ownership/internal/types/codec.go @@ -0,0 +1,18 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" +) + +// RegisterCodec registers concrete types on codec. +func RegisterCodec(cdc *codec.Codec) {} + +// ModuleCdc defines the module codec. +var ModuleCdc *codec.Codec + +func init() { + ModuleCdc = codec.New() + RegisterCodec(ModuleCdc) + codec.RegisterCrypto(ModuleCdc) + ModuleCdc.Seal() +} diff --git a/x/ownership/internal/types/expected_keepers.go b/x/ownership/internal/types/expected_keepers.go new file mode 100644 index 000000000..23128499d --- /dev/null +++ b/x/ownership/internal/types/expected_keepers.go @@ -0,0 +1,14 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/params" +) + +// ParamSubspace defines the expected Subspace interfacace +type ParamSubspace interface { + WithKeyTable(table params.KeyTable) params.Subspace + Get(ctx sdk.Context, key []byte, ptr interface{}) + GetParamSet(ctx sdk.Context, ps params.ParamSet) + SetParamSet(ctx sdk.Context, ps params.ParamSet) +} diff --git a/x/ownership/internal/types/genesis.go b/x/ownership/internal/types/genesis.go new file mode 100644 index 000000000..82fa33c65 --- /dev/null +++ b/x/ownership/internal/types/genesis.go @@ -0,0 +1,19 @@ +package types + +// GenesisState - all ownership state that must be provided at genesis +type GenesisState struct{} + +// NewGenesisState creates a new GenesisState object +func NewGenesisState() GenesisState { + return GenesisState{} +} + +// DefaultGenesisState - default GenesisState used by Cosmos Hub +func DefaultGenesisState() GenesisState { + return GenesisState{} +} + +// ValidateGenesis validates the ownership genesis parameters +func ValidateGenesis(data GenesisState) error { + return nil +} diff --git a/x/ownership/internal/types/key.go b/x/ownership/internal/types/key.go new file mode 100644 index 000000000..b764ae656 --- /dev/null +++ b/x/ownership/internal/types/key.go @@ -0,0 +1,14 @@ +package types + +const ( + // ModuleName is the name of the module + ModuleName = "ownership" + + // StoreKey to be used when creating the KVStore + StoreKey = ModuleName + + // RouterKey to be used for routing msgs + RouterKey = ModuleName + + QuerierRoute = ModuleName +) \ No newline at end of file diff --git a/x/ownership/internal/types/params.go b/x/ownership/internal/types/params.go new file mode 100644 index 000000000..4940992b5 --- /dev/null +++ b/x/ownership/internal/types/params.go @@ -0,0 +1,38 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/x/params" +) + +// Default parameter namespace +const ( + DefaultParamspace = ModuleName +) + +// ParamKeyTable for instance module +func ParamKeyTable() params.KeyTable { + return params.NewKeyTable().RegisterParamSet(&Params{}) +} + +// Params - used for initializing default parameter for instance at genesis +type Params struct{} + +// NewParams creates a new Params object +func NewParams() Params { + return Params{} +} + +// String implements the stringer interface for Params +func (p Params) String() string { + return "" +} + +// ParamSetPairs - Implements params.ParamSet +func (p *Params) ParamSetPairs() params.ParamSetPairs { + return params.ParamSetPairs{} +} + +// DefaultParams defines the parameters for this module +func DefaultParams() Params { + return NewParams() +} diff --git a/x/ownership/internal/types/querier.go b/x/ownership/internal/types/querier.go new file mode 100644 index 000000000..96ab75048 --- /dev/null +++ b/x/ownership/internal/types/querier.go @@ -0,0 +1,6 @@ +package types + +// Query endpoints supported by the ownership querier +const ( + QueryListOwnerships = "list" +) diff --git a/x/ownership/module.go b/x/ownership/module.go new file mode 100644 index 000000000..2d1be1575 --- /dev/null +++ b/x/ownership/module.go @@ -0,0 +1,139 @@ +package ownership + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/gorilla/mux" + "github.com/mesg-foundation/engine/x/ownership/client/cli" + "github.com/mesg-foundation/engine/x/ownership/client/rest" + "github.com/mesg-foundation/engine/x/ownership/internal/types" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the ownership module. +type AppModuleBasic struct{} + +var _ module.AppModuleBasic = AppModuleBasic{} + +// Name returns the ownership module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterCodec registers the ownership module's types for the given codec. +func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { + RegisterCodec(cdc) +} + +// DefaultGenesis returns default genesis state as raw bytes for the ownership +// module. +func (AppModuleBasic) DefaultGenesis() json.RawMessage { + return ModuleCdc.MustMarshalJSON(DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the ownership module. +func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { + var data GenesisState + err := ModuleCdc.UnmarshalJSON(bz, &data) + if err != nil { + return err + } + return ValidateGenesis(data) +} + +// RegisterRESTRoutes registers the REST routes for the ownership module. +func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) { + rest.RegisterRoutes(ctx, rtr) +} + +// GetTxCmd returns the root tx command for the ownership module. +func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetTxCmd(cdc) +} + +// GetQueryCmd returns no root query command for the ownership module. +func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command { + return cli.GetQueryCmd(StoreKey, cdc) +} + +//____________________________________________________________________________ + +// AppModule implements an application module for the ownership module. +type AppModule struct { + AppModuleBasic + + keeper Keeper +} + +// NewAppModule creates a new AppModule object +func NewAppModule(k Keeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + keeper: k, + } +} + +// Name returns the ownership module's name. +func (AppModule) Name() string { + return ModuleName +} + +// RegisterInvariants registers the ownership module invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// Route returns the message routing key for the ownership module. +func (AppModule) Route() string { + return RouterKey +} + +// NewHandler returns an sdk.Handler for the ownership module. +func (am AppModule) NewHandler() sdk.Handler { + return NewHandler(am.keeper) +} + +// QuerierRoute returns the ownership module's querier route name. +func (AppModule) QuerierRoute() string { + return QuerierRoute +} + +// NewQuerierHandler returns the ownership module sdk.Querier. +func (am AppModule) NewQuerierHandler() sdk.Querier { + return NewQuerier(am.keeper) +} + +// InitGenesis performs genesis initialization for the ownership module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState GenesisState + ModuleCdc.MustUnmarshalJSON(data, &genesisState) + InitGenesis(ctx, am.keeper, genesisState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the ownership +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { + gs := ExportGenesis(ctx, am.keeper) + return ModuleCdc.MustMarshalJSON(gs) +} + +// BeginBlock returns the begin blocker for the ownership module. +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { + BeginBlocker(ctx, req, am.keeper) +} + +// EndBlock returns the end blocker for the ownership module. It returns no validator +// updates. +func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +}