Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add fixed fee for creating a new credit class (#351) #375

Merged
merged 4 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,6 @@ build/
/proto-tools-stamp
/tools-stamp
dist/

# pre-commit
.pre-commit-config.yaml
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ endif
.PHONY: run-tests test test-all $(TEST_TARGETS)

test-cover:
@export VERSION=$(VERSION);
@export VERSION=$(VERSION);
@bash scripts/test_cover.sh
.PHONY: test-cover

Expand Down Expand Up @@ -378,6 +378,7 @@ proto-update-deps:

@mkdir -p $(COSMOS_PROTO_TYPES)/base/query/v1beta1/
@curl -sSL $(COSMOS_PROTO_URL)/base/query/v1beta1/pagination.proto > $(COSMOS_PROTO_TYPES)/base/query/v1beta1/pagination.proto
@curl -sSL $(COSMOS_PROTO_URL)/base/v1beta1/coin.proto > $(COSMOS_PROTO_TYPES)/base/v1beta1/coin.proto


###############################################################################
Expand Down
2 changes: 2 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import (
dbm "github.com/tendermint/tm-db"

"github.com/regen-network/regen-ledger/types/module/server"
"github.com/regen-network/regen-ledger/x/ecocredit"
)

const (
Expand Down Expand Up @@ -137,6 +138,7 @@ var (
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
govtypes.ModuleName: {authtypes.Burner},
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
ecocredit.ModuleName: {authtypes.Burner},
}
)

Expand Down
9 changes: 8 additions & 1 deletion app/experimental_appconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
moduletypes "github.com/regen-network/regen-ledger/types/module"
"github.com/regen-network/regen-ledger/types/module/server"
data "github.com/regen-network/regen-ledger/x/data/module"
ecocredittypes "github.com/regen-network/regen-ledger/x/ecocredit"
ecocredit "github.com/regen-network/regen-ledger/x/ecocredit/module"
group "github.com/regen-network/regen-ledger/x/group/module"
)
Expand Down Expand Up @@ -51,10 +52,15 @@ func setCustomModules(app *RegenApp, interfaceRegistry types.InterfaceRegistry)
newModuleManager := server.NewManager(app.BaseApp, codec.NewProtoCodec(interfaceRegistry))

// BEGIN HACK: this is a total, ugly hack until x/auth & x/bank supports ADR 033 or we have a suitable alternative
ecocreditModule := ecocredit.NewModule(
app.GetSubspace(ecocredittypes.DefaultParamspace),
app.BankKeeper,
)

groupModule := group.Module{AccountKeeper: app.AccountKeeper, BankKeeper: app.BankKeeper}
// use a separate newModules from the global NewModules here because we need to pass state into the group module
newModules := []moduletypes.Module{
ecocredit.Module{},
ecocreditModule,
data.Module{},
groupModule,
}
Expand Down Expand Up @@ -135,4 +141,5 @@ func (app *RegenApp) setCustomSimulationManager() []module.AppModuleSimulation {
}

func initCustomParamsKeeper(paramsKeeper *paramskeeper.Keeper) {
paramsKeeper.Subspace(ecocredittypes.DefaultParamspace)
}
33 changes: 33 additions & 0 deletions docs/modules/ecocredit/protobuf.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
- [regen/ecocredit/v1alpha1/types.proto](#regen/ecocredit/v1alpha1/types.proto)
- [BatchInfo](#regen.ecocredit.v1alpha1.BatchInfo)
- [ClassInfo](#regen.ecocredit.v1alpha1.ClassInfo)
- [GenesisState](#regen.ecocredit.v1alpha1.GenesisState)
- [Params](#regen.ecocredit.v1alpha1.Params)

- [regen/ecocredit/v1alpha1/query.proto](#regen/ecocredit/v1alpha1/query.proto)
- [QueryBalanceRequest](#regen.ecocredit.v1alpha1.QueryBalanceRequest)
Expand Down Expand Up @@ -181,6 +183,37 @@ ClassInfo represents the high-level on-chain information for a credit class.




<a name="regen.ecocredit.v1alpha1.GenesisState"></a>

### GenesisState
GenesisState defines the state of the ecocredit module that is needed at genesis


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| params | [Params](#regen.ecocredit.v1alpha1.Params) | | Params contains the updateable global parameters for use with the x/params module |






<a name="regen.ecocredit.v1alpha1.Params"></a>

### Params
Params defines the updatable global parameters of the ecocredit module for
use with the x/params module.


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| credit_class_fee | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | credit_class_fee is the fixed fee charged on creation of a new credit class |





<!-- end messages -->

<!-- end enums -->
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/tendermint/tendermint v0.34.10
github.com/tendermint/tm-db v0.6.4
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d // indirect
google.golang.org/genproto v0.0.0-20210611144927-798beca9d670 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cosmos/cosmos-sdk v0.43.0-beta1 h1:cfRZY+opamo+zF+MuEbvriZwoSzfCuEh1fqUM8fFHbg=
github.com/cosmos/cosmos-sdk v0.43.0-beta1/go.mod h1:rpCPaC3MnityU4Io4CDZqZB4GMtPqNeYXxPk8iRqmYM=
github.com/cosmos/cosmos-sdk v0.43.0-beta1.0.20210520130629-fbb50cfa0a43 h1:50vB4gU07eqPc3LqzBOYXxXt7uiwkzsBMF/q9mms7UY=
github.com/cosmos/cosmos-sdk v0.43.0-beta1.0.20210520130629-fbb50cfa0a43/go.mod h1:rpCPaC3MnityU4Io4CDZqZB4GMtPqNeYXxPk8iRqmYM=
Expand Down Expand Up @@ -300,7 +299,6 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
Expand Down Expand Up @@ -989,8 +987,8 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d h1:KzwjikDymrEmYYbdyfievTwjEeGlu+OM6oiKBkF3Jfg=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210611144927-798beca9d670 h1:M9c2dapWGIISuWaz5vr/RUk5Qn2Hs8DZ9CJb5aH266Q=
google.golang.org/genproto v0.0.0-20210611144927-798beca9d670/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
Expand Down
15 changes: 15 additions & 0 deletions proto/regen/ecocredit/v1alpha1/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";

package regen.ecocredit.v1alpha1;

import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";

option go_package = "github.com/regen-network/regen-ledger/x/ecocredit";
Expand Down Expand Up @@ -40,4 +41,18 @@ message BatchInfo {

// metadata is any arbitrary metadata to attached to the credit batch.
bytes metadata = 5;
}

// Params defines the updatable global parameters of the ecocredit module for
// use with the x/params module.
message Params {
// credit_class_fee is the fixed fee charged on creation of a new credit class
repeated cosmos.base.v1beta1.Coin credit_class_fee = 1
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}

// GenesisState defines the state of the ecocredit module that is needed at genesis
message GenesisState {
// Params contains the updateable global parameters for use with the x/params module
Params params = 1 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"params\""];
}
3 changes: 3 additions & 0 deletions third_party/proto/cosmos/base/query/v1beta1/pagination.proto
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ message PageRequest {
// count_total is only respected when offset is used. It is ignored when key
// is set.
bool count_total = 4;

// reverse is set to true if results are to be returned in the descending order.
bool reverse = 5;
aaronc marked this conversation as resolved.
Show resolved Hide resolved
}

// PageResponse is to be embedded in gRPC response messages where the
Expand Down
40 changes: 40 additions & 0 deletions third_party/proto/cosmos/base/v1beta1/coin.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
syntax = "proto3";
ruhatch marked this conversation as resolved.
Show resolved Hide resolved
package cosmos.base.v1beta1;

import "gogoproto/gogo.proto";

option go_package = "github.com/cosmos/cosmos-sdk/types";
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = false;

// Coin defines a token with a denomination and an amount.
//
// NOTE: The amount field is an Int which implements the custom method
// signatures required by gogoproto.
message Coin {
option (gogoproto.equal) = true;

string denom = 1;
string amount = 2 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false];
}

// DecCoin defines a token with a denomination and a decimal amount.
//
// NOTE: The amount field is an Dec which implements the custom method
// signatures required by gogoproto.
message DecCoin {
option (gogoproto.equal) = true;

string denom = 1;
string amount = 2 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false];
}

// IntProto defines a Protobuf wrapper around an Int object.
message IntProto {
string int = 1 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false];
}

// DecProto defines a Protobuf wrapper around a Dec object.
message DecProto {
string dec = 1 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false];
}
10 changes: 10 additions & 0 deletions x/ecocredit/expected_keepers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ecocredit

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

type BankKeeper interface {
BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error
SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
}
1 change: 1 addition & 0 deletions x/ecocredit/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
github.com/spf13/cobra v1.1.3
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
github.com/tendermint/tendermint v0.34.10 // indirect
google.golang.org/grpc v1.37.0
gopkg.in/yaml.v2 v2.4.0
)
Expand Down
8 changes: 8 additions & 0 deletions x/ecocredit/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ecocredit

const (
// ModuleName is the module name constant used in many places
ModuleName = "ecocredit"

DefaultParamspace = ModuleName
)
25 changes: 21 additions & 4 deletions x/ecocredit/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types/module"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/gorilla/mux"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra"
Expand All @@ -18,25 +19,41 @@ import (
"github.com/regen-network/regen-ledger/x/ecocredit/server"
)

type Module struct{}
type Module struct {
paramSpace paramtypes.Subspace
bankKeeper ecocredit.BankKeeper
}

func NewModule(paramSpace paramtypes.Subspace, bankKeeper ecocredit.BankKeeper) Module {
if !paramSpace.HasKeyTable() {
paramSpace = paramSpace.WithKeyTable(ecocredit.ParamKeyTable())
}

return Module{
paramSpace: paramSpace,
bankKeeper: bankKeeper,
}
}

var _ module.AppModuleBasic = Module{}
var _ servermodule.Module = Module{}
var _ climodule.Module = Module{}

func (a Module) Name() string {
return "ecocredit"
return ecocredit.ModuleName
}

func (a Module) RegisterInterfaces(registry types.InterfaceRegistry) {
ecocredit.RegisterTypes(registry)
}

func (a Module) RegisterServices(configurator servermodule.Configurator) {
server.RegisterServices(configurator)
server.RegisterServices(configurator, a.paramSpace, a.bankKeeper)
}

func (a Module) DefaultGenesis(codec.JSONCodec) json.RawMessage { return nil }
func (a Module) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
return cdc.MustMarshalJSON(ecocredit.DefaultGenesisState())
}

func (a Module) ValidateGenesis(codec.JSONCodec, sdkclient.TxEncodingConfig, json.RawMessage) error {
return nil
Expand Down
48 changes: 48 additions & 0 deletions x/ecocredit/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ecocredit

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)

var (
// TODO: Decide a sensible default value
DefaultCreditClassFeeTokens = sdk.NewInt(10000)
KeyCreditClassFee = []byte("CreditClassFee")
)

func ParamKeyTable() paramtypes.KeyTable {
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
}

// Implements params.ParamSet
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(KeyCreditClassFee, &p.CreditClassFee, validateCreditClassFee),
}
}

func validateCreditClassFee(i interface{}) error {
v, ok := i.(sdk.Coins)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}

if err := v.Validate(); err != nil {
return err
}

return nil
}

func NewParams(creditClassFee sdk.Coins) Params {
return Params{
CreditClassFee: creditClassFee,
}
}

func DefaultParams() Params {
return NewParams(sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, DefaultCreditClassFeeTokens)))
}
30 changes: 30 additions & 0 deletions x/ecocredit/server/fee.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package server

import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/regen-network/regen-ledger/x/ecocredit"
)

func (s serverImpl) getCreditClassFee(ctx sdk.Context) sdk.Coins {
var params ecocredit.Params
s.paramSpace.GetParamSet(ctx, &params)
return params.CreditClassFee
}

func (s serverImpl) chargeCreditClassFee(ctx sdk.Context, designerAddr sdk.AccAddress) error {
creditClassFee := s.getCreditClassFee(ctx)

// Move the fee to the ecocredit module's account
err := s.bankKeeper.SendCoinsFromAccountToModule(ctx, designerAddr, ecocredit.ModuleName, creditClassFee)
if err != nil {
return err
}

// Burn the coins
// TODO: Update this implementation based on the discussion at
// https://github.com/regen-network/regen-ledger/issues/351
err = s.bankKeeper.BurnCoins(ctx, ecocredit.ModuleName, creditClassFee)

return nil
}
Loading