From 76469b1184339cbfc21e73556481fee5f446221f Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 16:20:05 +0100 Subject: [PATCH 01/16] Integrate ecocredits module --- x/data/module/module.go | 10 +++--- x/ecocredit/module/module.go | 16 +++++---- x/ecocredit/server/data_prefixes.go | 34 +++++++++++++++++++ x/ecocredit/server/msg_server.go | 18 ++-------- x/ecocredit/server/query_server.go | 13 ++------ x/ecocredit/server/server.go | 52 +++++++++-------------------- 6 files changed, 67 insertions(+), 76 deletions(-) create mode 100644 x/ecocredit/server/data_prefixes.go diff --git a/x/data/module/module.go b/x/data/module/module.go index ffee3724a3..225accca8e 100644 --- a/x/data/module/module.go +++ b/x/data/module/module.go @@ -3,17 +3,15 @@ package module import ( "encoding/json" - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - sdkclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" "github.com/regen-network/regen-ledger/x/data" "github.com/regen-network/regen-ledger/x/data/client" diff --git a/x/ecocredit/module/module.go b/x/ecocredit/module/module.go index a7c67630f4..1e7586742f 100644 --- a/x/ecocredit/module/module.go +++ b/x/ecocredit/module/module.go @@ -3,17 +3,15 @@ package module import ( "encoding/json" - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - sdkclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" "github.com/regen-network/regen-ledger/x/ecocredit" "github.com/regen-network/regen-ledger/x/ecocredit/server" @@ -23,6 +21,8 @@ type AppModule struct { Key sdk.StoreKey } +var _ module.AppModule = AppModule{} + func (a AppModule) Name() string { return ecocredit.ModuleName } func (a AppModule) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} @@ -59,7 +59,9 @@ func (a AppModule) ExportGenesis(sdk.Context, codec.JSONMarshaler) json.RawMessa func (a AppModule) RegisterInvariants(sdk.InvariantRegistry) {} -func (a AppModule) Route() sdk.Route { return sdk.Route{} } +func (a AppModule) Route() sdk.Route { + return sdk.Route{} +} func (a AppModule) QuerierRoute() string { return "" } diff --git a/x/ecocredit/server/data_prefixes.go b/x/ecocredit/server/data_prefixes.go new file mode 100644 index 0000000000..f269f3e875 --- /dev/null +++ b/x/ecocredit/server/data_prefixes.go @@ -0,0 +1,34 @@ +package server + +import "fmt" + +// batchDenomT is used to prevent errors when forming keys as accounts and denoms are +// both represented as strings +type batchDenomT string + +func TradableBalanceKey(acc string, denom batchDenomT) []byte { + key := []byte{TradableBalancePrefix} + str := fmt.Sprintf("%s|%s", acc, denom) + return append(key, str...) +} + +func TradableSupplyKey(batchDenom batchDenomT) []byte { + key := []byte{TradableSupplyPrefix} + return append(key, batchDenom...) +} + +func RetiredBalanceKey(acc string, batchDenom batchDenomT) []byte { + key := []byte{RetiredBalancePrefix} + str := fmt.Sprintf("%s|%s", acc, batchDenom) + return append(key, str...) +} + +func RetiredSupplyKey(batchDenom batchDenomT) []byte { + key := []byte{RetiredSupplyPrefix} + return append(key, batchDenom...) +} + +func MaxDecimalPlacesKey(batchDenom batchDenomT) []byte { + key := []byte{MaxDecimalPlacesPrefix} + return append(key, batchDenom...) +} diff --git a/x/ecocredit/server/msg_server.go b/x/ecocredit/server/msg_server.go index 1929284089..b365922d58 100644 --- a/x/ecocredit/server/msg_server.go +++ b/x/ecocredit/server/msg_server.go @@ -6,12 +6,10 @@ import ( "fmt" "github.com/btcsuite/btcutil/base58" - "github.com/regen-network/regen-ledger/orm" - "github.com/cockroachdb/apd/v2" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/regen-network/regen-ledger/orm" "github.com/regen-network/regen-ledger/x/ecocredit" "github.com/regen-network/regen-ledger/x/ecocredit/math" @@ -19,9 +17,7 @@ import ( func (s serverImpl) CreateClass(goCtx context.Context, req *ecocredit.MsgCreateClassRequest) (*ecocredit.MsgCreateClassResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - classID := s.idSeq.NextVal(ctx) - classIDStr := uint64ToBase58Check(classID) err := s.classInfoTable.Create(ctx, &ecocredit.ClassInfo{ @@ -30,7 +26,6 @@ func (s serverImpl) CreateClass(goCtx context.Context, req *ecocredit.MsgCreateC Issuers: req.Issuers, Metadata: req.Metadata, }) - if err != nil { return nil, err } @@ -48,7 +43,6 @@ func (s serverImpl) CreateClass(goCtx context.Context, req *ecocredit.MsgCreateC func (s serverImpl) CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateBatchRequest) (*ecocredit.MsgCreateBatchResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - classID := req.ClassId classInfo, err := s.getClassInfo(ctx, classID) if err != nil { @@ -68,9 +62,7 @@ func (s serverImpl) CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateB } batchID := s.idSeq.NextVal(ctx) - batchDenom := batchDenomT(fmt.Sprintf("%s/%s", classID, uint64ToBase58Check(batchID))) - tradableSupply := apd.New(0, 0) retiredSupply := apd.New(0, 0) var maxDecimalPlaces uint32 = 0 @@ -181,12 +173,10 @@ func (s serverImpl) CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateB func (s serverImpl) Send(goCtx context.Context, req *ecocredit.MsgSendRequest) (*ecocredit.MsgSendResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - + store := ctx.KVStore(s.storeKey) sender := req.Sender recipient := req.Recipient - store := ctx.KVStore(s.storeKey) - for _, credit := range req.Credits { denom := batchDenomT(credit.BatchDenom) @@ -257,10 +247,8 @@ func (s serverImpl) Send(goCtx context.Context, req *ecocredit.MsgSendRequest) ( func (s serverImpl) Retire(goCtx context.Context, req *ecocredit.MsgRetireRequest) (*ecocredit.MsgRetireResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - - holder := req.Holder - store := ctx.KVStore(s.storeKey) + holder := req.Holder for _, credit := range req.Credits { denom := batchDenomT(credit.BatchDenom) diff --git a/x/ecocredit/server/query_server.go b/x/ecocredit/server/query_server.go index c863882e77..ac77ecdea4 100644 --- a/x/ecocredit/server/query_server.go +++ b/x/ecocredit/server/query_server.go @@ -22,11 +22,7 @@ func (s serverImpl) ClassInfo(ctx context.Context, request *ecocredit.QueryClass func (s serverImpl) getClassInfo(ctx sdk.Context, classID string) (*ecocredit.ClassInfo, error) { var classInfo ecocredit.ClassInfo err := s.classInfoTable.GetOne(ctx, orm.RowID(classID), &classInfo) - if err != nil { - return nil, err - } - - return &classInfo, nil + return &classInfo, err } func (s serverImpl) BatchInfo(goCtx context.Context, request *ecocredit.QueryBatchInfoRequest) (*ecocredit.QueryBatchInfoResponse, error) { @@ -34,11 +30,7 @@ func (s serverImpl) BatchInfo(goCtx context.Context, request *ecocredit.QueryBat var batchInfo ecocredit.BatchInfo err := s.batchInfoTable.GetOne(ctx, orm.RowID(request.BatchDenom), &batchInfo) - if err != nil { - return nil, err - } - - return &ecocredit.QueryBatchInfoResponse{Info: &batchInfo}, nil + return &ecocredit.QueryBatchInfoResponse{Info: &batchInfo}, err } func (s serverImpl) Balance(goCtx context.Context, request *ecocredit.QueryBalanceRequest) (*ecocredit.QueryBalanceResponse, error) { @@ -46,7 +38,6 @@ func (s serverImpl) Balance(goCtx context.Context, request *ecocredit.QueryBalan acc := request.Account denom := batchDenomT(request.BatchDenom) - store := ctx.KVStore(s.storeKey) tradable, err := getDecimal(store, TradableBalanceKey(acc, denom)) diff --git a/x/ecocredit/server/server.go b/x/ecocredit/server/server.go index 8adb9ea49c..4fa88b0d99 100644 --- a/x/ecocredit/server/server.go +++ b/x/ecocredit/server/server.go @@ -1,7 +1,7 @@ package server import ( - "fmt" + "context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -25,14 +25,23 @@ type serverImpl struct { storeKey sdk.StoreKey // we use a single sequence to avoid having the same string/ID identifying a class and batch denom - idSeq orm.Sequence - + idSeq orm.Sequence classInfoTable orm.NaturalKeyTable - batchInfoTable orm.NaturalKeyTable } -func newServer(storeKey sdk.StoreKey) serverImpl { +// Server is the the ecocredits implementation of ADR 031 Msg Service +type Server interface { + CreateClass(goCtx context.Context, req *ecocredit.MsgCreateClassRequest) (*ecocredit.MsgCreateClassResponse, error) + CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateBatchRequest) (*ecocredit.MsgCreateBatchResponse, error) + Send(goCtx context.Context, req *ecocredit.MsgSendRequest) (*ecocredit.MsgSendResponse, error) + + Retire(goCtx context.Context, req *ecocredit.MsgRetireRequest) (*ecocredit.MsgRetireResponse, error) + SetPrecision(goCtx context.Context, request *ecocredit.MsgSetPrecisionRequest) (*ecocredit.MsgSetPrecisionResponse, error) +} + +// NewServer implements the +func NewServer(storeKey sdk.StoreKey) serverImpl { s := serverImpl{storeKey: storeKey} s.idSeq = orm.NewSequence(storeKey, IDSeqPrefix) @@ -47,38 +56,7 @@ func newServer(storeKey sdk.StoreKey) serverImpl { } func RegisterServices(storeKey sdk.StoreKey, cfg module.Configurator) { - impl := newServer(storeKey) + impl := NewServer(storeKey) ecocredit.RegisterMsgServer(cfg.MsgServer(), impl) ecocredit.RegisterQueryServer(cfg.QueryServer(), impl) } - -// batchDenomT is used to prevent errors when forming keys as accounts and denoms are -// both represented as strings -type batchDenomT string - -func TradableBalanceKey(acc string, denom batchDenomT) []byte { - key := []byte{TradableBalancePrefix} - str := fmt.Sprintf("%s|%s", acc, denom) - return append(key, str...) -} - -func TradableSupplyKey(batchDenom batchDenomT) []byte { - key := []byte{TradableSupplyPrefix} - return append(key, batchDenom...) -} - -func RetiredBalanceKey(acc string, batchDenom batchDenomT) []byte { - key := []byte{RetiredBalancePrefix} - str := fmt.Sprintf("%s|%s", acc, batchDenom) - return append(key, str...) -} - -func RetiredSupplyKey(batchDenom batchDenomT) []byte { - key := []byte{RetiredSupplyPrefix} - return append(key, batchDenom...) -} - -func MaxDecimalPlacesKey(batchDenom batchDenomT) []byte { - key := []byte{MaxDecimalPlacesPrefix} - return append(key, batchDenom...) -} From 79e555b5342d4199244e600b25c4824541ce229b Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 16:56:37 +0100 Subject: [PATCH 02/16] use interfaces for Msg/Query services --- x/ecocredit/server/server.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/x/ecocredit/server/server.go b/x/ecocredit/server/server.go index 4fa88b0d99..07a7d0f13a 100644 --- a/x/ecocredit/server/server.go +++ b/x/ecocredit/server/server.go @@ -32,16 +32,24 @@ type serverImpl struct { // Server is the the ecocredits implementation of ADR 031 Msg Service type Server interface { + // Msg Services CreateClass(goCtx context.Context, req *ecocredit.MsgCreateClassRequest) (*ecocredit.MsgCreateClassResponse, error) CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateBatchRequest) (*ecocredit.MsgCreateBatchResponse, error) Send(goCtx context.Context, req *ecocredit.MsgSendRequest) (*ecocredit.MsgSendResponse, error) Retire(goCtx context.Context, req *ecocredit.MsgRetireRequest) (*ecocredit.MsgRetireResponse, error) SetPrecision(goCtx context.Context, request *ecocredit.MsgSetPrecisionRequest) (*ecocredit.MsgSetPrecisionResponse, error) + + // Query methods + ClassInfo(ctx context.Context, request *ecocredit.QueryClassInfoRequest) (*ecocredit.QueryClassInfoResponse, error) + BatchInfo(goCtx context.Context, request *ecocredit.QueryBatchInfoRequest) (*ecocredit.QueryBatchInfoResponse, error) + Balance(goCtx context.Context, request *ecocredit.QueryBalanceRequest) (*ecocredit.QueryBalanceResponse, error) + Supply(goCtx context.Context, request *ecocredit.QuerySupplyRequest) (*ecocredit.QuerySupplyResponse, error) + Precision(goCtx context.Context, request *ecocredit.QueryPrecisionRequest) (*ecocredit.QueryPrecisionResponse, error) } -// NewServer implements the -func NewServer(storeKey sdk.StoreKey) serverImpl { +// NewServer implements the interface for ADR-031 +func NewServer(storeKey sdk.StoreKey) Server { s := serverImpl{storeKey: storeKey} s.idSeq = orm.NewSequence(storeKey, IDSeqPrefix) From 56fd908260aee096f3e3cc9ee1923d72953f61d4 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 19:37:57 +0100 Subject: [PATCH 03/16] simplify decimal parsing --- x/ecocredit/math/math.go | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/x/ecocredit/math/math.go b/x/ecocredit/math/math.go index 710739ecdb..42c28206dd 100644 --- a/x/ecocredit/math/math.go +++ b/x/ecocredit/math/math.go @@ -12,11 +12,7 @@ import ( // ParseNonNegativeDecimal parses a non-negative decimal or returns an error. func ParseNonNegativeDecimal(x string) (*apd.Decimal, error) { res, _, err := apd.NewFromString(x) - if err != nil { - return nil, errors.Wrap(errors.ErrInvalidRequest, fmt.Sprintf("expected a non-negative decimal, got %s", x)) - } - - if res.Sign() < 0 { + if err != nil || res.Sign() < 0 { return nil, errors.Wrap(errors.ErrInvalidRequest, fmt.Sprintf("expected a non-negative decimal, got %s", x)) } @@ -26,11 +22,7 @@ func ParseNonNegativeDecimal(x string) (*apd.Decimal, error) { // ParsePositiveDecimal parses a positive decimal or returns an error. func ParsePositiveDecimal(x string) (*apd.Decimal, error) { res, _, err := apd.NewFromString(x) - if err != nil { - return nil, errors.Wrap(errors.ErrInvalidRequest, fmt.Sprintf("expected a positive decimal, got %s", x)) - } - - if res.Sign() <= 0 { + if err != nil || res.Sign() <= 0 { return nil, errors.Wrap(errors.ErrInvalidRequest, fmt.Sprintf("expected a positive decimal, got %s", x)) } From 8639f35917e9638659283d3ce349a510d6f22ca8 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 19:53:11 +0100 Subject: [PATCH 04/16] use protobuf server interfaces --- x/ecocredit/server/server.go | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/x/ecocredit/server/server.go b/x/ecocredit/server/server.go index 07a7d0f13a..a96a4dc322 100644 --- a/x/ecocredit/server/server.go +++ b/x/ecocredit/server/server.go @@ -1,8 +1,6 @@ package server import ( - "context" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -32,20 +30,8 @@ type serverImpl struct { // Server is the the ecocredits implementation of ADR 031 Msg Service type Server interface { - // Msg Services - CreateClass(goCtx context.Context, req *ecocredit.MsgCreateClassRequest) (*ecocredit.MsgCreateClassResponse, error) - CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateBatchRequest) (*ecocredit.MsgCreateBatchResponse, error) - Send(goCtx context.Context, req *ecocredit.MsgSendRequest) (*ecocredit.MsgSendResponse, error) - - Retire(goCtx context.Context, req *ecocredit.MsgRetireRequest) (*ecocredit.MsgRetireResponse, error) - SetPrecision(goCtx context.Context, request *ecocredit.MsgSetPrecisionRequest) (*ecocredit.MsgSetPrecisionResponse, error) - - // Query methods - ClassInfo(ctx context.Context, request *ecocredit.QueryClassInfoRequest) (*ecocredit.QueryClassInfoResponse, error) - BatchInfo(goCtx context.Context, request *ecocredit.QueryBatchInfoRequest) (*ecocredit.QueryBatchInfoResponse, error) - Balance(goCtx context.Context, request *ecocredit.QueryBalanceRequest) (*ecocredit.QueryBalanceResponse, error) - Supply(goCtx context.Context, request *ecocredit.QuerySupplyRequest) (*ecocredit.QuerySupplyResponse, error) - Precision(goCtx context.Context, request *ecocredit.QueryPrecisionRequest) (*ecocredit.QueryPrecisionResponse, error) + ecocredit.MsgServer + ecocredit.QueryServer } // NewServer implements the interface for ADR-031 From ff2a9036c68ee5fd9b96d0b2a9dcfe46c8e392f9 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 20:51:18 +0100 Subject: [PATCH 05/16] Refactor the MsgServer usage with modules I found that we are recreating a server and hardcoding it in local functions (eg in SDK modules in all handler methods). This leads to difficulties or weird designs if we want to test or customize it. Instead, I propose to relay more on tests and configurability. In this commit, I compose a Server inside the AppModule. The AppModule constructor could take a server as a parameter, however I decided to not do it and not expose the default functionality. Module test suites however, will like to customize it. They can do that by creating an AppModule themselves - the struct is public. --- x/ecocredit/module/module.go | 15 +++++++++++---- x/ecocredit/server/server.go | 7 ------- x/ecocredit/server/server_test.go | 18 ++++++++++++------ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/x/ecocredit/module/module.go b/x/ecocredit/module/module.go index 1e7586742f..8a5c754d68 100644 --- a/x/ecocredit/module/module.go +++ b/x/ecocredit/module/module.go @@ -19,11 +19,17 @@ import ( type AppModule struct { Key sdk.StoreKey + Srv server.Server } var _ module.AppModule = AppModule{} -func (a AppModule) Name() string { return ecocredit.ModuleName } +func NewAppModule() AppModule { + key := sdk.NewKVStoreKey(ecocredit.ModuleName) + return AppModule{key, server.NewServer(key)} +} + +func (a AppModule) Name() string { return a.Key.Name() } func (a AppModule) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} @@ -63,14 +69,15 @@ func (a AppModule) Route() sdk.Route { return sdk.Route{} } -func (a AppModule) QuerierRoute() string { return "" } +func (a AppModule) QuerierRoute() string { return a.Name() } func (a AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } -func (a AppModule) RegisterServices(configurator module.Configurator) { - server.RegisterServices(a.Key, configurator) +func (a AppModule) RegisterServices(cfg module.Configurator) { + ecocredit.RegisterMsgServer(cfg.MsgServer(), a.Srv) + ecocredit.RegisterQueryServer(cfg.QueryServer(), a.Srv) } func (a AppModule) BeginBlock(sdk.Context, abci.RequestBeginBlock) {} diff --git a/x/ecocredit/server/server.go b/x/ecocredit/server/server.go index a96a4dc322..a3212b7f0e 100644 --- a/x/ecocredit/server/server.go +++ b/x/ecocredit/server/server.go @@ -2,7 +2,6 @@ package server import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" "github.com/regen-network/regen-ledger/orm" "github.com/regen-network/regen-ledger/x/ecocredit" @@ -48,9 +47,3 @@ func NewServer(storeKey sdk.StoreKey) Server { return s } - -func RegisterServices(storeKey sdk.StoreKey, cfg module.Configurator) { - impl := NewServer(storeKey) - ecocredit.RegisterMsgServer(cfg.MsgServer(), impl) - ecocredit.RegisterQueryServer(cfg.QueryServer(), impl) -} diff --git a/x/ecocredit/server/server_test.go b/x/ecocredit/server/server_test.go index 0ee700a279..4d68918820 100644 --- a/x/ecocredit/server/server_test.go +++ b/x/ecocredit/server/server_test.go @@ -3,20 +3,26 @@ package server import ( "testing" - "github.com/stretchr/testify/suite" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" "github.com/regen-network/regen-ledger/testutil/server/configurator" + "github.com/regen-network/regen-ledger/x/ecocredit" "github.com/regen-network/regen-ledger/x/ecocredit/server/testsuite" ) +func registerServers(key sdk.StoreKey, cfg configurator.Fixture) { + srv := NewServer(key) + ecocredit.RegisterMsgServer(cfg.MsgServer(), srv) + ecocredit.RegisterQueryServer(cfg.QueryServer(), srv) +} + func TestServer(t *testing.T) { - key := sdk.NewKVStoreKey("ecocredit") + key := sdk.NewKVStoreKey(ecocredit.ModuleName) addrs := configurator.MakeTestAddresses(6) - configuratorFixture := configurator.NewFixture(t, []sdk.StoreKey{key}, addrs) - RegisterServices(key, configuratorFixture) - s := testsuite.NewIntegrationTestSuite(configuratorFixture) + cfg := configurator.NewFixture(t, []sdk.StoreKey{key}, addrs) + registerServers(key, cfg) + s := testsuite.NewIntegrationTestSuite(cfg) suite.Run(t, s) } From f8b22702cd756c43f63ad1392bea35da191e7294 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 21:51:12 +0100 Subject: [PATCH 06/16] clean module.go --- x/ecocredit/module/module.go | 42 +++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/x/ecocredit/module/module.go b/x/ecocredit/module/module.go index 8a5c754d68..331aeb9427 100644 --- a/x/ecocredit/module/module.go +++ b/x/ecocredit/module/module.go @@ -31,10 +31,6 @@ func NewAppModule() AppModule { func (a AppModule) Name() string { return a.Key.Name() } -func (a AppModule) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} - -func (a AppModule) RegisterInterfaces(codectypes.InterfaceRegistry) {} - func (a AppModule) DefaultGenesis(codec.JSONMarshaler) json.RawMessage { return nil } @@ -42,10 +38,13 @@ func (a AppModule) DefaultGenesis(codec.JSONMarshaler) json.RawMessage { func (a AppModule) ValidateGenesis(codec.JSONMarshaler, sdkclient.TxEncodingConfig, json.RawMessage) error { return nil } +func (a AppModule) InitGenesis(sdk.Context, codec.JSONMarshaler, json.RawMessage) []abci.ValidatorUpdate { + return nil +} -func (a AppModule) RegisterRESTRoutes(sdkclient.Context, *mux.Router) {} - -func (a AppModule) RegisterGRPCGatewayRoutes(sdkclient.Context, *runtime.ServeMux) {} +func (a AppModule) ExportGenesis(sdk.Context, codec.JSONMarshaler) json.RawMessage { + return nil +} func (a AppModule) GetTxCmd() *cobra.Command { return nil @@ -55,15 +54,25 @@ func (a AppModule) GetQueryCmd() *cobra.Command { return nil } -func (a AppModule) InitGenesis(sdk.Context, codec.JSONMarshaler, json.RawMessage) []abci.ValidatorUpdate { - return nil +func (a AppModule) RegisterGRPCGatewayRoutes(sdkclient.Context, *runtime.ServeMux) {} + +func (a AppModule) RegisterInvariants(sdk.InvariantRegistry) {} + +func (a AppModule) RegisterServices(cfg module.Configurator) { + ecocredit.RegisterMsgServer(cfg.MsgServer(), a.Srv) + ecocredit.RegisterQueryServer(cfg.QueryServer(), a.Srv) } -func (a AppModule) ExportGenesis(sdk.Context, codec.JSONMarshaler) json.RawMessage { +func (a AppModule) BeginBlock(sdk.Context, abci.RequestBeginBlock) {} + +func (a AppModule) EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate { return nil } -func (a AppModule) RegisterInvariants(sdk.InvariantRegistry) {} +/**** DEPRECATED ****/ + +// Should we deprecate it? RegisterServices already registers everything for the module. +func (a AppModule) RegisterInterfaces(codectypes.InterfaceRegistry) {} func (a AppModule) Route() sdk.Route { return sdk.Route{} @@ -75,13 +84,6 @@ func (a AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } -func (a AppModule) RegisterServices(cfg module.Configurator) { - ecocredit.RegisterMsgServer(cfg.MsgServer(), a.Srv) - ecocredit.RegisterQueryServer(cfg.QueryServer(), a.Srv) -} - -func (a AppModule) BeginBlock(sdk.Context, abci.RequestBeginBlock) {} +func (a AppModule) RegisterRESTRoutes(sdkclient.Context, *mux.Router) {} -func (a AppModule) EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate { - return nil -} +func (a AppModule) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} From b8a3d73d42b0e10ff190c2a39685f6bfb56e18ba Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 22:13:43 +0100 Subject: [PATCH 07/16] update app --- app/app.go | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/app/app.go b/app/app.go index c2377b9e39..5d621dbf38 100644 --- a/app/app.go +++ b/app/app.go @@ -6,17 +6,18 @@ import ( "net/http" "os" - "github.com/cosmos/cosmos-sdk/x/auth/tx" - "github.com/gorilla/mux" "github.com/rakyll/statik/fs" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" + baseapp "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" @@ -24,11 +25,14 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" + "github.com/cosmos/cosmos-sdk/x/auth/tx" "github.com/cosmos/cosmos-sdk/x/auth/vesting" + "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" "github.com/cosmos/cosmos-sdk/x/capability" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" @@ -63,9 +67,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" - "github.com/tendermint/tendermint/libs/log" // types + sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" @@ -81,16 +85,8 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - // "os" - - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/bank" - - baseapp "github.com/cosmos/cosmos-sdk/baseapp" - sdk "github.com/cosmos/cosmos-sdk/types" - data "github.com/regen-network/regen-ledger/x/data/module" + ecocredit "github.com/regen-network/regen-ledger/x/ecocredit/module" ) const ( @@ -349,6 +345,7 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest params.NewAppModule(app.ParamsKeeper), transferModule, data.NewAppModule(keys[data.StoreKey]), + ecocredit.NewAppModule(), ) // During begin block slashing happens after distr.BeginBlocker so that From 6c56276eaf921549936b3f693491726bf2067862 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 23:45:27 +0100 Subject: [PATCH 08/16] Add Query CLI --- x/ecocredit/client/query.go | 139 +++++++++++++++++++++++++++++++++++ x/ecocredit/module/module.go | 5 +- 2 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 x/ecocredit/client/query.go diff --git a/x/ecocredit/client/query.go b/x/ecocredit/client/query.go new file mode 100644 index 0000000000..91cfe8381f --- /dev/null +++ b/x/ecocredit/client/query.go @@ -0,0 +1,139 @@ +package client + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/gogo/protobuf/proto" + "github.com/spf13/cobra" + + "github.com/regen-network/regen-ledger/x/ecocredit" +) + +// QueryCmd returns the parent command for all x/data CLI query commands +func QueryCmd() *cobra.Command { + cmd := &cobra.Command{ + Args: cobra.ExactArgs(1), + Use: ecocredit.ModuleName, + Short: "Querying commands for the ecocredit module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + cmd.AddCommand( + queryClassInfo(), + queryBatchInfo(), + queryBalance(), + querySupply(), + queryPrecision(), + ) + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func print(ctx client.Context, res proto.Message, err error) error { + if err != nil { + return err + } + return ctx.PrintOutput(res) +} + +func createClient(cmd *cobra.Command) (ecocredit.QueryClient, client.Context, error) { + ctx := client.GetClientContextFromCmd(cmd) + ctx, err := client.ReadQueryCommandFlags(ctx, cmd.Flags()) + return ecocredit.NewQueryClient(ctx), ctx, err +} + +func queryClassInfo() *cobra.Command { + return &cobra.Command{ + Use: "class_info [class_id]", + Short: "Select a class info", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + c, ctx, err := createClient(cmd) + if err != nil { + return err + } + res, err := c.ClassInfo(cmd.Context(), &ecocredit.QueryClassInfoRequest{ + ClassId: args[0], + }) + return print(ctx, res, err) + }, + } +} + +func queryBatchInfo() *cobra.Command { + return &cobra.Command{ + Use: "batch_info [batch_denom]", + Short: "Select the credit issuance batch info", + Long: "Select the credit issuance batch info based on the bach_denom (ID)", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + c, ctx, err := createClient(cmd) + if err != nil { + return err + } + res, err := c.BatchInfo(cmd.Context(), &ecocredit.QueryBatchInfoRequest{ + BatchDenom: args[0], + }) + return print(ctx, res, err) + }, + } +} + +func queryBalance() *cobra.Command { + return &cobra.Command{ + Use: "balance [batch_denom] [account]", + Short: "Select the tradable and retired balance of the credit batch", + Long: "Select the credit tradable and retired balance of the credit batch denom (ID) and account address", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + c, ctx, err := createClient(cmd) + if err != nil { + return err + } + res, err := c.Balance(cmd.Context(), &ecocredit.QueryBalanceRequest{ + BatchDenom: args[0], Account: args[1], + }) + return print(ctx, res, err) + }, + } +} + +func querySupply() *cobra.Command { + return &cobra.Command{ + Use: "supply [batch_denom]", + Short: "Select the tradable and retired supply of the credit batch", + Long: "Select the tradable and retired supply of the credit batch batch denom (ID)", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + c, ctx, err := createClient(cmd) + if err != nil { + return err + } + res, err := c.Supply(cmd.Context(), &ecocredit.QuerySupplyRequest{ + BatchDenom: args[0], + }) + return print(ctx, res, err) + }, + } +} + +func queryPrecision() *cobra.Command { + return &cobra.Command{ + Use: "precision [batch_denom]", + Short: "Select the maximum length of the fractional part of credits in the given batch", + Long: "Select the maximum length of the fractional part of credits in the given batch. The precision tells what is the minimum unit of a credit.\nExample: a decimal number 12.345 has fractional part length equal 3. A precision=5 means that the minimum unit we can trade is 0.00001", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + c, ctx, err := createClient(cmd) + if err != nil { + return err + } + res, err := c.Precision(cmd.Context(), &ecocredit.QueryPrecisionRequest{ + BatchDenom: args[0], + }) + return print(ctx, res, err) + }, + } +} diff --git a/x/ecocredit/module/module.go b/x/ecocredit/module/module.go index 331aeb9427..8c2280c26f 100644 --- a/x/ecocredit/module/module.go +++ b/x/ecocredit/module/module.go @@ -14,6 +14,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/regen-network/regen-ledger/x/ecocredit" + client "github.com/regen-network/regen-ledger/x/ecocredit/client" "github.com/regen-network/regen-ledger/x/ecocredit/server" ) @@ -50,9 +51,7 @@ func (a AppModule) GetTxCmd() *cobra.Command { return nil } -func (a AppModule) GetQueryCmd() *cobra.Command { - return nil -} +func (a AppModule) GetQueryCmd() *cobra.Command { return client.QueryCmd() } func (a AppModule) RegisterGRPCGatewayRoutes(sdkclient.Context, *runtime.ServeMux) {} From dc048365dfe446f99959d95d612aeb758f61e8bf Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 5 Nov 2020 23:52:48 +0100 Subject: [PATCH 09/16] move client utility functions --- x/ecocredit/client/query.go | 24 +++++------------------- x/ecocredit/client/util.go | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 19 deletions(-) create mode 100644 x/ecocredit/client/util.go diff --git a/x/ecocredit/client/query.go b/x/ecocredit/client/query.go index 91cfe8381f..679b0df0dc 100644 --- a/x/ecocredit/client/query.go +++ b/x/ecocredit/client/query.go @@ -3,7 +3,6 @@ package client import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/gogo/protobuf/proto" "github.com/spf13/cobra" "github.com/regen-network/regen-ledger/x/ecocredit" @@ -31,26 +30,13 @@ func QueryCmd() *cobra.Command { return cmd } -func print(ctx client.Context, res proto.Message, err error) error { - if err != nil { - return err - } - return ctx.PrintOutput(res) -} - -func createClient(cmd *cobra.Command) (ecocredit.QueryClient, client.Context, error) { - ctx := client.GetClientContextFromCmd(cmd) - ctx, err := client.ReadQueryCommandFlags(ctx, cmd.Flags()) - return ecocredit.NewQueryClient(ctx), ctx, err -} - func queryClassInfo() *cobra.Command { return &cobra.Command{ Use: "class_info [class_id]", Short: "Select a class info", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - c, ctx, err := createClient(cmd) + c, ctx, err := mkQueryClient(cmd) if err != nil { return err } @@ -69,7 +55,7 @@ func queryBatchInfo() *cobra.Command { Long: "Select the credit issuance batch info based on the bach_denom (ID)", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - c, ctx, err := createClient(cmd) + c, ctx, err := mkQueryClient(cmd) if err != nil { return err } @@ -88,7 +74,7 @@ func queryBalance() *cobra.Command { Long: "Select the credit tradable and retired balance of the credit batch denom (ID) and account address", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - c, ctx, err := createClient(cmd) + c, ctx, err := mkQueryClient(cmd) if err != nil { return err } @@ -107,7 +93,7 @@ func querySupply() *cobra.Command { Long: "Select the tradable and retired supply of the credit batch batch denom (ID)", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - c, ctx, err := createClient(cmd) + c, ctx, err := mkQueryClient(cmd) if err != nil { return err } @@ -126,7 +112,7 @@ func queryPrecision() *cobra.Command { Long: "Select the maximum length of the fractional part of credits in the given batch. The precision tells what is the minimum unit of a credit.\nExample: a decimal number 12.345 has fractional part length equal 3. A precision=5 means that the minimum unit we can trade is 0.00001", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - c, ctx, err := createClient(cmd) + c, ctx, err := mkQueryClient(cmd) if err != nil { return err } diff --git a/x/ecocredit/client/util.go b/x/ecocredit/client/util.go new file mode 100644 index 0000000000..ac2d2bd567 --- /dev/null +++ b/x/ecocredit/client/util.go @@ -0,0 +1,22 @@ +package client + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/gogo/protobuf/proto" + "github.com/spf13/cobra" + + "github.com/regen-network/regen-ledger/x/ecocredit" +) + +func print(ctx client.Context, res proto.Message, err error) error { + if err != nil { + return err + } + return ctx.PrintOutput(res) +} + +func mkQueryClient(cmd *cobra.Command) (ecocredit.QueryClient, client.Context, error) { + ctx := client.GetClientContextFromCmd(cmd) + ctx, err := client.ReadQueryCommandFlags(ctx, cmd.Flags()) + return ecocredit.NewQueryClient(ctx), ctx, err +} From 9fbfcb08a8882ec5c14aac14d5c01e8dc617786b Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 6 Nov 2020 00:35:17 +0100 Subject: [PATCH 10/16] Adding MsgClient CLI: wip --- x/ecocredit/client/query.go | 11 ++++--- x/ecocredit/client/tx.go | 65 +++++++++++++++++++++++++++++++++++++ x/ecocredit/client/util.go | 14 ++++++++ 3 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 x/ecocredit/client/tx.go diff --git a/x/ecocredit/client/query.go b/x/ecocredit/client/query.go index 679b0df0dc..945e55a04a 100644 --- a/x/ecocredit/client/query.go +++ b/x/ecocredit/client/query.go @@ -11,12 +11,13 @@ import ( // QueryCmd returns the parent command for all x/data CLI query commands func QueryCmd() *cobra.Command { cmd := &cobra.Command{ - Args: cobra.ExactArgs(1), - Use: ecocredit.ModuleName, - Short: "Querying commands for the ecocredit module", - DisableFlagParsing: true, SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, + DisableFlagParsing: true, + + Args: cobra.ExactArgs(1), + Use: ecocredit.ModuleName, + Short: "Querying commands for the ecocredit module", + RunE: client.ValidateCmd, } cmd.AddCommand( queryClassInfo(), diff --git a/x/ecocredit/client/tx.go b/x/ecocredit/client/tx.go new file mode 100644 index 0000000000..7271fbf368 --- /dev/null +++ b/x/ecocredit/client/tx.go @@ -0,0 +1,65 @@ +package client + +import ( + "encoding/base64" + "errors" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/spf13/cobra" + + "github.com/regen-network/regen-ledger/x/ecocredit" +) + +// TxCmd returns a root CLI command handler for all x/data transaction commands. +func TxCmd() *cobra.Command { + cmd := &cobra.Command{ + SuggestionsMinimumDistance: 2, + DisableFlagParsing: true, + + Use: ecocredit.ModuleName, + Short: "Ecocredit module transactions", + RunE: client.ValidateCmd, + } + cmd.AddCommand() + + return cmd +} + +func txCreateClass() *cobra.Command { + cmd := &cobra.Command{ + Use: "create_class [designer] [issuer[,issuer]*] [base64_metadata]", + Short: `Creates a new credit class. + designer: address of the account which designed the credit class + issuer: comma separated (no spaces) list of issuer account addresses. Example: "addr1,addr2" + metadata: base64 encoded metadata - arbitrary data attached to the credit class info`, + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + issuers := strings.Split(args[1], ",") + for i := range issuers { + issuers[i] = strings.TrimSpace(issuers[i]) + } + if args[2] == "" { + return errors.New("base64_metadata is required") + } + b, err := base64.StdEncoding.DecodeString(args[2]) + if err != nil { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "base64_metadata is malformed, proper base64 string is required") + } + + c, ctx, err := mkMsgClient(cmd) + if err != nil { + return err + } + res, err := c.CreateClass(cmd.Context(), &ecocredit.MsgCreateClassRequest{ + Designer: args[0], Issuers: issuers, Metadata: b, + }) + return print(ctx, res, err) + // TODO: return mkTx(ctx, cmd, err) + }, + } + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/ecocredit/client/util.go b/x/ecocredit/client/util.go index ac2d2bd567..b9a9db7f66 100644 --- a/x/ecocredit/client/util.go +++ b/x/ecocredit/client/util.go @@ -2,6 +2,7 @@ package client import ( "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" "github.com/gogo/protobuf/proto" "github.com/spf13/cobra" @@ -15,8 +16,21 @@ func print(ctx client.Context, res proto.Message, err error) error { return ctx.PrintOutput(res) } +func mkTx(ctx client.Context, cmd *cobra.Command, err error) error { + if err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags()) +} + func mkQueryClient(cmd *cobra.Command) (ecocredit.QueryClient, client.Context, error) { ctx := client.GetClientContextFromCmd(cmd) ctx, err := client.ReadQueryCommandFlags(ctx, cmd.Flags()) return ecocredit.NewQueryClient(ctx), ctx, err } + +func mkMsgClient(cmd *cobra.Command) (ecocredit.MsgClient, client.Context, error) { + ctx := client.GetClientContextFromCmd(cmd) + ctx, err := client.ReadTxCommandFlags(ctx, cmd.Flags()) + return ecocredit.NewMsgClient(ctx), ctx, err +} From 9c255e7b4fc4521e8b2b318153b555df6027a36a Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 6 Nov 2020 11:37:28 +0100 Subject: [PATCH 11/16] remove Server interface --- x/ecocredit/codec.go | 10 ++++++++ x/ecocredit/module/module.go | 39 ++++++++++++++----------------- x/ecocredit/server/server.go | 16 ++++++------- x/ecocredit/server/server_test.go | 8 +------ 4 files changed, 36 insertions(+), 37 deletions(-) create mode 100644 x/ecocredit/codec.go diff --git a/x/ecocredit/codec.go b/x/ecocredit/codec.go new file mode 100644 index 0000000000..4d96df1202 --- /dev/null +++ b/x/ecocredit/codec.go @@ -0,0 +1,10 @@ +package ecocredit + +import ( + "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterTypes(registry types.InterfaceRegistry) { + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} diff --git a/x/ecocredit/module/module.go b/x/ecocredit/module/module.go index 8c2280c26f..c9d9d6f005 100644 --- a/x/ecocredit/module/module.go +++ b/x/ecocredit/module/module.go @@ -14,23 +14,19 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/regen-network/regen-ledger/x/ecocredit" - client "github.com/regen-network/regen-ledger/x/ecocredit/client" + "github.com/regen-network/regen-ledger/x/ecocredit/client" "github.com/regen-network/regen-ledger/x/ecocredit/server" ) -type AppModule struct { - Key sdk.StoreKey - Srv server.Server -} +type AppModule struct{} var _ module.AppModule = AppModule{} -func NewAppModule() AppModule { - key := sdk.NewKVStoreKey(ecocredit.ModuleName) - return AppModule{key, server.NewServer(key)} +func NewAppModule() module.AppModule { + return AppModule{} } -func (a AppModule) Name() string { return a.Key.Name() } +func (a AppModule) Name() string { return ecocredit.ModuleName } func (a AppModule) DefaultGenesis(codec.JSONMarshaler) json.RawMessage { return nil @@ -48,18 +44,24 @@ func (a AppModule) ExportGenesis(sdk.Context, codec.JSONMarshaler) json.RawMessa } func (a AppModule) GetTxCmd() *cobra.Command { - return nil + return client.TxCmd() } -func (a AppModule) GetQueryCmd() *cobra.Command { return client.QueryCmd() } +func (a AppModule) GetQueryCmd() *cobra.Command { + return client.QueryCmd() +} func (a AppModule) RegisterGRPCGatewayRoutes(sdkclient.Context, *runtime.ServeMux) {} func (a AppModule) RegisterInvariants(sdk.InvariantRegistry) {} func (a AppModule) RegisterServices(cfg module.Configurator) { - ecocredit.RegisterMsgServer(cfg.MsgServer(), a.Srv) - ecocredit.RegisterQueryServer(cfg.QueryServer(), a.Srv) + key := sdk.NewKVStoreKey(ecocredit.ModuleName) + server.RegisterServices(key, cfg) +} + +func (a AppModule) RegisterInterfaces(r codectypes.InterfaceRegistry) { + ecocredit.RegisterTypes(r) } func (a AppModule) BeginBlock(sdk.Context, abci.RequestBeginBlock) {} @@ -70,18 +72,11 @@ func (a AppModule) EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorU /**** DEPRECATED ****/ -// Should we deprecate it? RegisterServices already registers everything for the module. -func (a AppModule) RegisterInterfaces(codectypes.InterfaceRegistry) {} - -func (a AppModule) Route() sdk.Route { - return sdk.Route{} -} +func (a AppModule) Route() sdk.Route { return sdk.Route{} } func (a AppModule) QuerierRoute() string { return a.Name() } -func (a AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { - return nil -} +func (a AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } func (a AppModule) RegisterRESTRoutes(sdkclient.Context, *mux.Router) {} diff --git a/x/ecocredit/server/server.go b/x/ecocredit/server/server.go index a3212b7f0e..058c2c4284 100644 --- a/x/ecocredit/server/server.go +++ b/x/ecocredit/server/server.go @@ -2,6 +2,7 @@ package server import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" "github.com/regen-network/regen-ledger/orm" "github.com/regen-network/regen-ledger/x/ecocredit" @@ -27,14 +28,7 @@ type serverImpl struct { batchInfoTable orm.NaturalKeyTable } -// Server is the the ecocredits implementation of ADR 031 Msg Service -type Server interface { - ecocredit.MsgServer - ecocredit.QueryServer -} - -// NewServer implements the interface for ADR-031 -func NewServer(storeKey sdk.StoreKey) Server { +func newServer(storeKey sdk.StoreKey) serverImpl { s := serverImpl{storeKey: storeKey} s.idSeq = orm.NewSequence(storeKey, IDSeqPrefix) @@ -47,3 +41,9 @@ func NewServer(storeKey sdk.StoreKey) Server { return s } + +func RegisterServices(storeKey sdk.StoreKey, configurator module.Configurator) { + impl := newServer(storeKey) + ecocredit.RegisterMsgServer(configurator.MsgServer(), impl) + ecocredit.RegisterQueryServer(configurator.QueryServer(), impl) +} diff --git a/x/ecocredit/server/server_test.go b/x/ecocredit/server/server_test.go index 4d68918820..3f06da7d0b 100644 --- a/x/ecocredit/server/server_test.go +++ b/x/ecocredit/server/server_test.go @@ -11,17 +11,11 @@ import ( "github.com/regen-network/regen-ledger/x/ecocredit/server/testsuite" ) -func registerServers(key sdk.StoreKey, cfg configurator.Fixture) { - srv := NewServer(key) - ecocredit.RegisterMsgServer(cfg.MsgServer(), srv) - ecocredit.RegisterQueryServer(cfg.QueryServer(), srv) -} - func TestServer(t *testing.T) { key := sdk.NewKVStoreKey(ecocredit.ModuleName) addrs := configurator.MakeTestAddresses(6) cfg := configurator.NewFixture(t, []sdk.StoreKey{key}, addrs) - registerServers(key, cfg) + RegisterServices(key, cfg) s := testsuite.NewIntegrationTestSuite(cfg) suite.Run(t, s) From 228aec066ed52e58c83c333d3fc50f28710b7991 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 6 Nov 2020 11:46:12 +0100 Subject: [PATCH 12/16] add AppModuleBasic to enable interface types registration --- app/app.go | 1 + x/ecocredit/module/module.go | 48 +++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/app/app.go b/app/app.go index 5d621dbf38..f6abd7f79b 100644 --- a/app/app.go +++ b/app/app.go @@ -121,6 +121,7 @@ var ( transfer.AppModuleBasic{}, vesting.AppModuleBasic{}, data.AppModuleBasic{}, + ecocredit.AppModuleBasic{}, ) // module account permissions diff --git a/x/ecocredit/module/module.go b/x/ecocredit/module/module.go index c9d9d6f005..fea8395c4b 100644 --- a/x/ecocredit/module/module.go +++ b/x/ecocredit/module/module.go @@ -18,40 +18,50 @@ import ( "github.com/regen-network/regen-ledger/x/ecocredit/server" ) -type AppModule struct{} +type AppModuleBasic struct{} + +type AppModule struct { + AppModuleBasic +} var _ module.AppModule = AppModule{} +var _ module.AppModuleBasic = AppModuleBasic{} func NewAppModule() module.AppModule { return AppModule{} } -func (a AppModule) Name() string { return ecocredit.ModuleName } +func (a AppModuleBasic) Name() string { return ecocredit.ModuleName } -func (a AppModule) DefaultGenesis(codec.JSONMarshaler) json.RawMessage { +func (a AppModuleBasic) DefaultGenesis(codec.JSONMarshaler) json.RawMessage { return nil } -func (a AppModule) ValidateGenesis(codec.JSONMarshaler, sdkclient.TxEncodingConfig, json.RawMessage) error { - return nil -} -func (a AppModule) InitGenesis(sdk.Context, codec.JSONMarshaler, json.RawMessage) []abci.ValidatorUpdate { +func (a AppModuleBasic) ValidateGenesis(codec.JSONMarshaler, sdkclient.TxEncodingConfig, json.RawMessage) error { return nil } -func (a AppModule) ExportGenesis(sdk.Context, codec.JSONMarshaler) json.RawMessage { - return nil +func (a AppModuleBasic) GetQueryCmd() *cobra.Command { + return client.QueryCmd() } -func (a AppModule) GetTxCmd() *cobra.Command { +func (a AppModuleBasic) GetTxCmd() *cobra.Command { return client.TxCmd() } -func (a AppModule) GetQueryCmd() *cobra.Command { - return client.QueryCmd() +func (a AppModuleBasic) RegisterGRPCGatewayRoutes(sdkclient.Context, *runtime.ServeMux) {} + +func (a AppModuleBasic) RegisterInterfaces(r codectypes.InterfaceRegistry) { + ecocredit.RegisterTypes(r) } -func (a AppModule) RegisterGRPCGatewayRoutes(sdkclient.Context, *runtime.ServeMux) {} +func (a AppModule) InitGenesis(sdk.Context, codec.JSONMarshaler, json.RawMessage) []abci.ValidatorUpdate { + return nil +} + +func (a AppModule) ExportGenesis(sdk.Context, codec.JSONMarshaler) json.RawMessage { + return nil +} func (a AppModule) RegisterInvariants(sdk.InvariantRegistry) {} @@ -60,10 +70,6 @@ func (a AppModule) RegisterServices(cfg module.Configurator) { server.RegisterServices(key, cfg) } -func (a AppModule) RegisterInterfaces(r codectypes.InterfaceRegistry) { - ecocredit.RegisterTypes(r) -} - func (a AppModule) BeginBlock(sdk.Context, abci.RequestBeginBlock) {} func (a AppModule) EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate { @@ -72,12 +78,10 @@ func (a AppModule) EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorU /**** DEPRECATED ****/ -func (a AppModule) Route() sdk.Route { return sdk.Route{} } +func (a AppModuleBasic) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} +func (a AppModuleBasic) RegisterRESTRoutes(sdkclient.Context, *mux.Router) {} +func (a AppModule) Route() sdk.Route { return sdk.Route{} } func (a AppModule) QuerierRoute() string { return a.Name() } func (a AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } - -func (a AppModule) RegisterRESTRoutes(sdkclient.Context, *mux.Router) {} - -func (a AppModule) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} From d5aa4f7486e003d53141be762e293ed6bf38cf65 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Tue, 10 Nov 2020 11:14:52 -0500 Subject: [PATCH 13/16] fix tests --- x/ecocredit/msgs.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/x/ecocredit/msgs.go b/x/ecocredit/msgs.go index a36fd89dfd..6096a8c5ea 100644 --- a/x/ecocredit/msgs.go +++ b/x/ecocredit/msgs.go @@ -7,7 +7,8 @@ import ( ) var ( - _, _, _, _ sdk.MsgRequest = &MsgCreateClassRequest{}, &MsgCreateBatchRequest{}, &MsgSendRequest{}, &MsgRetireRequest{} + _, _, _, _, _ sdk.MsgRequest = &MsgCreateClassRequest{}, &MsgCreateBatchRequest{}, &MsgSendRequest{}, + &MsgRetireRequest{}, &MsgSetPrecisionRequest{} ) func (m *MsgCreateClassRequest) ValidateBasic() error { @@ -93,3 +94,19 @@ func (m *MsgRetireRequest) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{addr} } + +func (m *MsgSetPrecisionRequest) ValidateBasic() error { + if len(m.BatchDenom) == 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "missing batch_denom") + } + return nil +} + +func (m *MsgSetPrecisionRequest) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.Issuer) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{addr} +} From 51851c5ea7111381fb93630fe2ea2729337eb77f Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Tue, 10 Nov 2020 11:17:04 -0500 Subject: [PATCH 14/16] grammar check --- x/ecocredit/client/query.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/x/ecocredit/client/query.go b/x/ecocredit/client/query.go index 945e55a04a..71c3ddf238 100644 --- a/x/ecocredit/client/query.go +++ b/x/ecocredit/client/query.go @@ -16,7 +16,7 @@ func QueryCmd() *cobra.Command { Args: cobra.ExactArgs(1), Use: ecocredit.ModuleName, - Short: "Querying commands for the ecocredit module", + Short: "Query commands for the ecocredit module", RunE: client.ValidateCmd, } cmd.AddCommand( @@ -34,7 +34,7 @@ func QueryCmd() *cobra.Command { func queryClassInfo() *cobra.Command { return &cobra.Command{ Use: "class_info [class_id]", - Short: "Select a class info", + Short: "Retrieve credit class info", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { c, ctx, err := mkQueryClient(cmd) @@ -52,8 +52,8 @@ func queryClassInfo() *cobra.Command { func queryBatchInfo() *cobra.Command { return &cobra.Command{ Use: "batch_info [batch_denom]", - Short: "Select the credit issuance batch info", - Long: "Select the credit issuance batch info based on the bach_denom (ID)", + Short: "Retrieve the credit issuance batch info", + Long: "Retrieve the credit issuance batch info based on the bach_denom (ID)", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { c, ctx, err := mkQueryClient(cmd) @@ -71,8 +71,8 @@ func queryBatchInfo() *cobra.Command { func queryBalance() *cobra.Command { return &cobra.Command{ Use: "balance [batch_denom] [account]", - Short: "Select the tradable and retired balance of the credit batch", - Long: "Select the credit tradable and retired balance of the credit batch denom (ID) and account address", + Short: "Retrieve the tradable and retired balances of the credit batch", + Long: "Retrieve the tradable and retired balances of the credit batch for a given account address", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { c, ctx, err := mkQueryClient(cmd) @@ -90,8 +90,8 @@ func queryBalance() *cobra.Command { func querySupply() *cobra.Command { return &cobra.Command{ Use: "supply [batch_denom]", - Short: "Select the tradable and retired supply of the credit batch", - Long: "Select the tradable and retired supply of the credit batch batch denom (ID)", + Short: "Retrieve the tradable and retired supply of the credit batch", + Long: "Retrieve the tradable and retired supply of the credit batch", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { c, ctx, err := mkQueryClient(cmd) @@ -109,8 +109,8 @@ func querySupply() *cobra.Command { func queryPrecision() *cobra.Command { return &cobra.Command{ Use: "precision [batch_denom]", - Short: "Select the maximum length of the fractional part of credits in the given batch", - Long: "Select the maximum length of the fractional part of credits in the given batch. The precision tells what is the minimum unit of a credit.\nExample: a decimal number 12.345 has fractional part length equal 3. A precision=5 means that the minimum unit we can trade is 0.00001", + Short: "Retrieve the maximum length of the fractional part of credits in the given batch", + Long: "Retrieve the maximum length of the fractional part of credits in the given batch. The precision tells what is the minimum unit of a credit.\nExample: a decimal number 12.345 has fractional part length equal 3. A precision=5 means that the minimum unit we can trade is 0.00001", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { c, ctx, err := mkQueryClient(cmd) From 0fcbfaaf83a23b007922a1d455591ac8e085bc95 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Tue, 10 Nov 2020 12:05:27 -0500 Subject: [PATCH 15/16] fix imports --- app/app.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/app.go b/app/app.go index 4d5ad5200e..8d42587a87 100644 --- a/app/app.go +++ b/app/app.go @@ -84,13 +84,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/bank" - - baseapp "github.com/cosmos/cosmos-sdk/baseapp" - sdk "github.com/cosmos/cosmos-sdk/types" - data "github.com/regen-network/regen-ledger/x/data/module" ecocredit "github.com/regen-network/regen-ledger/x/ecocredit/module" ) From 5bb66b2af67492eda31f2da871c7300bde1e6697 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Tue, 10 Nov 2020 12:14:29 -0500 Subject: [PATCH 16/16] fix lint --- x/ecocredit/client/tx.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x/ecocredit/client/tx.go b/x/ecocredit/client/tx.go index 7271fbf368..e1ce6fc16a 100644 --- a/x/ecocredit/client/tx.go +++ b/x/ecocredit/client/tx.go @@ -23,7 +23,10 @@ func TxCmd() *cobra.Command { Short: "Ecocredit module transactions", RunE: client.ValidateCmd, } - cmd.AddCommand() + + cmd.AddCommand( + txCreateClass(), + ) return cmd } @@ -53,11 +56,10 @@ func txCreateClass() *cobra.Command { if err != nil { return err } - res, err := c.CreateClass(cmd.Context(), &ecocredit.MsgCreateClassRequest{ + _, err = c.CreateClass(cmd.Context(), &ecocredit.MsgCreateClassRequest{ Designer: args[0], Issuers: issuers, Metadata: b, }) - return print(ctx, res, err) - // TODO: return mkTx(ctx, cmd, err) + return mkTx(ctx, cmd, err) }, } flags.AddTxFlagsToCmd(cmd)