Skip to content

Commit

Permalink
refactor(ecocredit/basket): wire core submodule into baskets (#935)
Browse files Browse the repository at this point in the history
* wip: baskets integration

* feat: integrate core module into baskets

* chore: fmt

* fix: add credit type check

* chore: go fmt

* chore: fix comment

* chore: remove regex call

* chore: imports, fmt

* chore: comment out sims temporarily

* chore: address review

* chore: comment correct sim call and add todo comment

* Update proto/regen/ecocredit/v1/types.proto

Co-authored-by: Ryan Christoffersen <12519942+ryanchristo@users.noreply.github.com>

* chore: use full batch denoms

* gomock.Any() -> gmAny

* chore: Save -> Update

* chore: proto-gen

* fix: put acceptance tests

* chore: move batch balance util functions to core utils

Co-authored-by: technicallyty <48813565+tytech3@users.noreply.github.com>
Co-authored-by: Ryan Christoffersen <12519942+ryanchristo@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 31, 2022
1 parent 29c8666 commit f39b517
Show file tree
Hide file tree
Showing 18 changed files with 1,456 additions and 1,360 deletions.
293 changes: 224 additions & 69 deletions api/regen/ecocredit/v1/types.pulsar.go

Large diffs are not rendered by default.

38 changes: 20 additions & 18 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ import (

"github.com/CosmWasm/wasmd/x/wasm"

"github.com/cosmos/ibc-go/v2/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/v2/modules/apps/transfer/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/v2/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/v2/modules/core"
ibcclient "github.com/cosmos/ibc-go/v2/modules/core/02-client"
ibcclienttypes "github.com/cosmos/ibc-go/v2/modules/core/02-client/types"
porttypes "github.com/cosmos/ibc-go/v2/modules/core/05-port/types"
ibchost "github.com/cosmos/ibc-go/v2/modules/core/24-host"
ibckeeper "github.com/cosmos/ibc-go/v2/modules/core/keeper"
ibcmock "github.com/cosmos/ibc-go/v2/testing/mock"
"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"
"github.com/spf13/cast"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
Expand Down Expand Up @@ -73,23 +91,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/upgrade"
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/cosmos/ibc-go/v2/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/v2/modules/apps/transfer/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/v2/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/v2/modules/core"
ibcclient "github.com/cosmos/ibc-go/v2/modules/core/02-client"
ibcclienttypes "github.com/cosmos/ibc-go/v2/modules/core/02-client/types"
porttypes "github.com/cosmos/ibc-go/v2/modules/core/05-port/types"
ibchost "github.com/cosmos/ibc-go/v2/modules/core/24-host"
ibckeeper "github.com/cosmos/ibc-go/v2/modules/core/keeper"
ibcmock "github.com/cosmos/ibc-go/v2/testing/mock"
"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"
"github.com/spf13/cast"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
dbm "github.com/tendermint/tm-db"

moduletypes "github.com/regen-network/regen-ledger/types/module"
"github.com/regen-network/regen-ledger/types/module/server"
Expand Down Expand Up @@ -537,7 +538,8 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest
// authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), // enable after updating sdk version v0.46
ibc.NewAppModule(app.IBCKeeper),
transferModule,
ecocreditmodule.NewModule(app.GetSubspace(ecocredit.DefaultParamspace), app.AccountKeeper, app.BankKeeper, app.DistrKeeper),
// TODO: uncomment when sims are refactored https://github.com/regen-network/regen-ledger/issues/920
// ecocreditmodule.NewModule(app.GetSubspace(ecocredit.DefaultParamspace), app.AccountKeeper, app.BankKeeper, app.DistrKeeper),
}, app.setCustomSimulationManager()...)...,
)

Expand Down
17 changes: 9 additions & 8 deletions app/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import (
"testing"

"github.com/CosmWasm/wasmd/x/wasm"
ibctransfertypes "github.com/cosmos/ibc-go/v2/modules/apps/transfer/types"
ibchost "github.com/cosmos/ibc-go/v2/modules/core/24-host"
"github.com/regen-network/regen-ledger/x/ecocredit"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
Expand All @@ -25,14 +34,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/simulation"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
ibctransfertypes "github.com/cosmos/ibc-go/v2/modules/apps/transfer/types"
ibchost "github.com/cosmos/ibc-go/v2/modules/core/24-host"
"github.com/regen-network/regen-ledger/x/ecocredit"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"
)

// Get flags every time the simulator is run
Expand Down
12 changes: 9 additions & 3 deletions proto/regen/ecocredit/v1/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ message Params {
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];

// basket_fee is the fixed fee charged on creation of a new basket
repeated cosmos.base.v1beta1.Coin basket_fee = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];

// allowed_class_creators is an allowlist defining the addresses with
// the required permissions to create credit classes
repeated string allowed_class_creators = 2;
repeated string allowed_class_creators = 3;

// allowlist_enabled is a param that enables/disables the allowlist for credit
// creation
bool allowlist_enabled = 3;
bool allowlist_enabled = 4;

// credit_types is a list of definitions for credit types
repeated CreditType credit_types = 4;
repeated CreditType credit_types = 5;
}
209 changes: 209 additions & 0 deletions x/ecocredit/core/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package core

import (
"regexp"

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

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

var (
// This is a value of 20 REGEN
DefaultCreditClassFeeTokens = sdk.NewInt(2e7)
DefaultBasketCreationFee = sdk.NewInt(2e7)
KeyCreditClassFee = []byte("CreditClassFee")
KeyAllowedClassCreators = []byte("AllowedClassCreators")
KeyAllowlistEnabled = []byte("AllowlistEnabled")
KeyCreditTypes = []byte("CreditTypes")
KeyBasketCreationFee = []byte("BasketCreationFee")
)

// TODO: remove after we open governance changes for precision

const (
PRECISION uint32 = 6
)

// ParamKeyTable returns the parameter key table.
func ParamKeyTable() paramtypes.KeyTable {
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
}

func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(KeyCreditClassFee, &p.CreditClassFee, validateCreditClassFee),
paramtypes.NewParamSetPair(KeyAllowedClassCreators, &p.AllowedClassCreators, validateAllowedClassCreators),
paramtypes.NewParamSetPair(KeyAllowlistEnabled, &p.AllowlistEnabled, validateAllowlistEnabled),
paramtypes.NewParamSetPair(KeyCreditTypes, &p.CreditTypes, validateCreditTypes),
paramtypes.NewParamSetPair(KeyBasketCreationFee, &p.BasketFee, validateBasketCreationFee),
}
}

// Validate will run each param field's validate method
func (p Params) Validate() error {
if err := validateCreditTypes(p.CreditTypes); err != nil {
return err
}

if err := validateAllowedClassCreators(p.AllowedClassCreators); err != nil {
return err
}

if err := validateAllowlistEnabled(p.AllowlistEnabled); err != nil {
return err
}

if err := validateCreditClassFee(p.CreditClassFee); err != nil {
return err
}

if err := validateBasketCreationFee(p.BasketFee); err != nil {
return err
}

return nil
}

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

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

return nil
}

func validateAllowedClassCreators(i interface{}) error {
v, ok := i.([]string)
if !ok {
return sdkerrors.ErrInvalidType.Wrapf("invalid parameter type: %T", i)
}
for _, sAddr := range v {
_, err := sdk.AccAddressFromBech32(sAddr)
if err != nil {
return sdkerrors.ErrInvalidAddress.Wrapf("invalid creator address: %s", err.Error())
}
}
return nil
}

func validateAllowlistEnabled(i interface{}) error {
_, ok := i.(bool)
if !ok {
return sdkerrors.ErrInvalidType.Wrapf("invalid parameter type: %T", i)
}

return nil
}

func validateCreditTypes(i interface{}) error {
creditTypes, ok := i.([]*CreditType)
if !ok {
return sdkerrors.ErrInvalidType.Wrapf("invalid parameter type: %T", i)
}

// ensure no duplicate credit types or abbreviations and that all
// precisions conform to hardcoded PRECISION above
seenTypes := make(map[string]bool)
seenAbbrs := make(map[string]bool)
for _, creditType := range creditTypes {
// Validate name
T := ecocredit.NormalizeCreditTypeName(creditType.Name)
if T != creditType.Name {
return sdkerrors.ErrInvalidRequest.Wrapf("credit type name should be normalized: got %s, should be %s", creditType.Name, T)
}
if creditType.Name == "" {
return sdkerrors.ErrInvalidRequest.Wrap("empty credit type name")
}
if seenTypes[T] {
return sdkerrors.ErrInvalidRequest.Wrapf("duplicate credit type name in request: %s", T)
}

// Validate abbreviation
abbr := creditType.Abbreviation
err := ValidateCreditTypeAbbreviation(abbr)
if err != nil {
return err
}
if seenAbbrs[abbr] {
return sdkerrors.ErrInvalidRequest.Wrapf("duplicate credit type abbreviation: %s", abbr)
}

// Validate precision
// TODO: remove after we open governance changes for precision
if creditType.Precision != PRECISION {
return sdkerrors.ErrInvalidRequest.Wrapf("invalid precision %d: precision is currently locked to %d", creditType.Precision, PRECISION)
}

// Validate units
if creditType.Unit == "" {
return sdkerrors.ErrInvalidRequest.Wrap("empty credit type unit")
}

// Mark type and abbr as seen
seenTypes[T] = true
seenAbbrs[abbr] = true
}

return nil
}

// Check that CreditType abbreviation is valid, i.e. it consists of 1-3
// uppercase letters
func ValidateCreditTypeAbbreviation(abbr string) error {
reAbbr := regexp.MustCompile(`^[A-Z]{1,3}$`)
matches := reAbbr.FindStringSubmatch(abbr)
if matches == nil {
return sdkerrors.ErrInvalidRequest.Wrapf("credit type abbreviation must be 1-3 uppercase latin letters: got %s", abbr)
}
return nil
}

func validateBasketCreationFee(i interface{}) error {
v, ok := i.(sdk.Coins)
if !ok {
return sdkerrors.ErrInvalidType.Wrapf("invalid parameter type: %T", i)
}

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

return nil
}

// NewParams creates a new Params object.
func NewParams(creditClassFee, basketCreationFee sdk.Coins, allowlist []string, allowlistEnabled bool, creditTypes []*CreditType) Params {
return Params{
CreditClassFee: creditClassFee,
AllowedClassCreators: allowlist,
AllowlistEnabled: allowlistEnabled,
CreditTypes: creditTypes,
BasketFee: basketCreationFee,
}
}

// DefaultParams returns a default set of parameters.
func DefaultParams() Params {
return NewParams(
sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, DefaultCreditClassFeeTokens)),
sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, DefaultBasketCreationFee)),
[]string{},
false,
[]*CreditType{
{
Name: "carbon",
Abbreviation: "C",
Unit: "metric ton CO2 equivalent",
Precision: PRECISION,
},
},
)
}
Loading

0 comments on commit f39b517

Please sign in to comment.