From abe42b2af5c539535329a352cbecd38cf7158873 Mon Sep 17 00:00:00 2001 From: Tyler <48813565+technicallyty@users.noreply.github.com> Date: Mon, 9 Aug 2021 02:23:36 -0700 Subject: [PATCH] feat: Add credit types (#424) +Adds credit types which includes type name, unit type (kg, tonne, etc), and precision (currently locked @ 6). +Adds query to get all credit types on CLI and grpc/http +Updates CreateClass tx command to include credit class arg +Adds tests for validating the credit type params -removes per-class precision setting functionality Closes: #424 --- CHANGELOG.md | 1 + docs/modules/ecocredit/protobuf.md | 78 ++- proto/regen/ecocredit/v1alpha1/query.proto | 29 +- proto/regen/ecocredit/v1alpha1/tx.proto | 47 +- proto/regen/ecocredit/v1alpha1/types.proto | 23 + x/ecocredit/client/query.go | 16 +- x/ecocredit/client/testsuite/query.go | 47 +- x/ecocredit/client/testsuite/tx.go | 39 +- x/ecocredit/client/tx.go | 51 +- x/ecocredit/msgs.go | 26 +- x/ecocredit/msgs_test.go | 30 +- x/ecocredit/params.go | 89 ++- x/ecocredit/params_test.go | 99 +++- x/ecocredit/query.pb.go | 332 +++++------ x/ecocredit/query.pb.gw.go | 64 +-- x/ecocredit/server/credit_type.go | 25 + x/ecocredit/server/data_prefixes.go | 5 - x/ecocredit/server/msg_server.go | 103 ++-- x/ecocredit/server/query_server.go | 13 +- x/ecocredit/server/server.go | 15 +- x/ecocredit/server/testsuite/suite.go | 184 +++--- x/ecocredit/tx.pb.go | 633 ++++----------------- x/ecocredit/types.go | 8 + x/ecocredit/types.pb.go | 557 ++++++++++++++++-- x/ecocredit/util/utils.go | 13 + x/group/server/testsuite/suite.go | 5 +- 26 files changed, 1346 insertions(+), 1186 deletions(-) create mode 100644 x/ecocredit/server/credit_type.go diff --git a/CHANGELOG.md b/CHANGELOG.md index db51f91f80..0c29acbbf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * add dates as top level fields in credit batches (#393) * add project location as field in credit batches (#394) * use dec wrapper for decimal operations (#435) +* add credit types to credit class (#424) * add params for an allowlist of permissioned credit designers (#425) ## [1.0.0] - 2021-04-13 diff --git a/docs/modules/ecocredit/protobuf.md b/docs/modules/ecocredit/protobuf.md index d4411632ae..857c0548b0 100644 --- a/docs/modules/ecocredit/protobuf.md +++ b/docs/modules/ecocredit/protobuf.md @@ -14,6 +14,7 @@ - [regen/ecocredit/v1alpha1/types.proto](#regen/ecocredit/v1alpha1/types.proto) - [BatchInfo](#regen.ecocredit.v1alpha1.BatchInfo) - [ClassInfo](#regen.ecocredit.v1alpha1.ClassInfo) + - [CreditType](#regen.ecocredit.v1alpha1.CreditType) - [GenesisState](#regen.ecocredit.v1alpha1.GenesisState) - [Params](#regen.ecocredit.v1alpha1.Params) @@ -24,8 +25,8 @@ - [QueryBatchInfoResponse](#regen.ecocredit.v1alpha1.QueryBatchInfoResponse) - [QueryClassInfoRequest](#regen.ecocredit.v1alpha1.QueryClassInfoRequest) - [QueryClassInfoResponse](#regen.ecocredit.v1alpha1.QueryClassInfoResponse) - - [QueryPrecisionRequest](#regen.ecocredit.v1alpha1.QueryPrecisionRequest) - - [QueryPrecisionResponse](#regen.ecocredit.v1alpha1.QueryPrecisionResponse) + - [QueryCreditTypesRequest](#regen.ecocredit.v1alpha1.QueryCreditTypesRequest) + - [QueryCreditTypesResponse](#regen.ecocredit.v1alpha1.QueryCreditTypesResponse) - [QuerySupplyRequest](#regen.ecocredit.v1alpha1.QuerySupplyRequest) - [QuerySupplyResponse](#regen.ecocredit.v1alpha1.QuerySupplyResponse) @@ -46,8 +47,6 @@ - [MsgSend](#regen.ecocredit.v1alpha1.MsgSend) - [MsgSend.SendCredits](#regen.ecocredit.v1alpha1.MsgSend.SendCredits) - [MsgSendResponse](#regen.ecocredit.v1alpha1.MsgSendResponse) - - [MsgSetPrecision](#regen.ecocredit.v1alpha1.MsgSetPrecision) - - [MsgSetPrecisionResponse](#regen.ecocredit.v1alpha1.MsgSetPrecisionResponse) - [Msg](#regen.ecocredit.v1alpha1.Msg) @@ -209,6 +208,26 @@ ClassInfo represents the high-level on-chain information for a credit class. | designer | [string](#string) | | designer is the designer of the credit class. | | issuers | [string](#string) | repeated | issuers are the approved issuers of the credit class. | | metadata | [bytes](#bytes) | | metadata is any arbitrary metadata to attached to the credit class. | +| credit_type | [CreditType](#regen.ecocredit.v1alpha1.CreditType) | | credit_type describes the type of credit (e.g. carbon, biodiversity), as well as unit and precision. | + + + + + + + + +### CreditType +CreditType defines the measurement unit/precision of a certain credit type +(e.g. carbon, biodiversity...) + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | the type of credit (e.g. carbon, biodiversity, etc) | +| abbreviation | [string](#string) | | abbreviation is a 1-3 character uppercase abbreviation of the CreditType name, used in batch denominations within the CreditType. It must be unique. | +| unit | [string](#string) | | the measurement unit (e.g. kg, ton, etc) | +| precision | [uint32](#uint32) | | the decimal precision | @@ -242,6 +261,7 @@ use with the x/params module. | 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 | | allowed_class_designers | [string](#string) | repeated | allowed_class_designers is an allowlist defining the addresses with the required permissions to create credit classes | | allowlist_enabled | [bool](#bool) | | allowlist_enabled is a param that enables/disables the allowlist for credit creation | +| credit_types | [CreditType](#regen.ecocredit.v1alpha1.CreditType) | repeated | credit_types is a list of definitions for credit types | @@ -356,30 +376,25 @@ QueryClassInfoResponse is the Query/ClassInfo request type. - + -### QueryPrecisionRequest -QueryPrecisionRequest is the Query/Precision request type. +### QueryCreditTypesRequest +QueryCreditTypesRequest is the Query/Credit_Types request type -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| batch_denom | [string](#string) | | batch_denom is the unique ID of credit batch to query. | + - - - -### QueryPrecisionResponse -QueryPrecisionResponse is the Query/Precision response type. +### QueryCreditTypesResponse +QueryCreditTypesRequest is the Query/Credit_Types response type | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| max_decimal_places | [uint32](#uint32) | | max_decimal_places is the maximum number of decimal places that can be used to represent some quantity of credits. It is an experimental feature to concretely explore an idea proposed in https://github.com/cosmos/cosmos-sdk/issues/7113. | +| credit_types | [CreditType](#regen.ecocredit.v1alpha1.CreditType) | repeated | list of credit types | @@ -434,7 +449,7 @@ Msg is the regen.ecocredit.v1alpha1 Query service. | BatchInfo | [QueryBatchInfoRequest](#regen.ecocredit.v1alpha1.QueryBatchInfoRequest) | [QueryBatchInfoResponse](#regen.ecocredit.v1alpha1.QueryBatchInfoResponse) | BatchInfo queries for information on a credit batch. | | Balance | [QueryBalanceRequest](#regen.ecocredit.v1alpha1.QueryBalanceRequest) | [QueryBalanceResponse](#regen.ecocredit.v1alpha1.QueryBalanceResponse) | Balance queries the balance (both tradable and retired) of a given credit batch for a given account. | | Supply | [QuerySupplyRequest](#regen.ecocredit.v1alpha1.QuerySupplyRequest) | [QuerySupplyResponse](#regen.ecocredit.v1alpha1.QuerySupplyResponse) | Supply queries the tradable and retired supply of a credit batch. | -| Precision | [QueryPrecisionRequest](#regen.ecocredit.v1alpha1.QueryPrecisionRequest) | [QueryPrecisionResponse](#regen.ecocredit.v1alpha1.QueryPrecisionResponse) | Precision queries the number of decimal places that can be used to represent credits in a batch. See Tx/SetPrecision for more details. | +| CreditTypes | [QueryCreditTypesRequest](#regen.ecocredit.v1alpha1.QueryCreditTypesRequest) | [QueryCreditTypesResponse](#regen.ecocredit.v1alpha1.QueryCreditTypesResponse) | CreditTypes returns the list of allowed types that credit classes can have. See Types/CreditType for more details. | @@ -555,6 +570,7 @@ MsgCreateClass is the Msg/CreateClass request type. | designer | [string](#string) | | designer is the address of the account which designed the credit class. The designer has special permissions to change the list of issuers and perform other administrative operations. | | issuers | [string](#string) | repeated | issuers are the account addresses of the approved issuers. | | metadata | [bytes](#bytes) | | metadata is any arbitrary metadata to attached to the credit class. | +| credit_type | [string](#string) | | credit_type describes the type of credit (e.g. "carbon", "biodiversity"). | @@ -665,33 +681,6 @@ MsgSendResponse is the Msg/Send response type. - - - -### MsgSetPrecision -MsgRetire is the Msg/SetPrecision request type. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| issuer | [string](#string) | | issuer is the address of the batch issuer. | -| batch_denom | [string](#string) | | batch_denom is the unique ID of the credit batch. | -| max_decimal_places | [uint32](#uint32) | | max_decimal_places is the new maximum number of decimal places that can be used to represent some quantity of credits. It is an experimental feature to concretely explore an idea proposed in https://github.com/cosmos/cosmos-sdk/issues/7113. | - - - - - - - - -### MsgSetPrecisionResponse -MsgRetire is the Msg/SetPrecision response type. - - - - - @@ -711,7 +700,6 @@ Msg is the regen.ecocredit.v1alpha1 Msg service. | Send | [MsgSend](#regen.ecocredit.v1alpha1.MsgSend) | [MsgSendResponse](#regen.ecocredit.v1alpha1.MsgSendResponse) | Send sends tradable credits from one account to another account. Sent credits can either be tradable or retired on receipt. | | Retire | [MsgRetire](#regen.ecocredit.v1alpha1.MsgRetire) | [MsgRetireResponse](#regen.ecocredit.v1alpha1.MsgRetireResponse) | Retire retires a specified number of credits in the holder's account. | | Cancel | [MsgCancel](#regen.ecocredit.v1alpha1.MsgCancel) | [MsgCancelResponse](#regen.ecocredit.v1alpha1.MsgCancelResponse) | Cancel removes a number of credits from the holder's account and also deducts them from the tradable supply, effectively cancelling their issuance on Regen Ledger | -| SetPrecision | [MsgSetPrecision](#regen.ecocredit.v1alpha1.MsgSetPrecision) | [MsgSetPrecisionResponse](#regen.ecocredit.v1alpha1.MsgSetPrecisionResponse) | SetPrecision allows an issuer to increase the decimal precision of a credit batch. It is an experimental feature to concretely explore an idea proposed in https://github.com/cosmos/cosmos-sdk/issues/7113. The number of decimal places allowed for a credit batch is determined by the original number of decimal places used with calling CreatBatch. SetPrecision allows the number of allowed decimal places to be increased, effectively making the supply more granular without actually changing any balances. It allows asset issuers to be able to issue an asset without needing to think about how many subdivisions are needed upfront. While it may not be relevant for credits which likely have a fairly stable market value, I wanted to experiment a bit and this serves as a proof of concept for a broader bank redesign where say for instance a coin like the ATOM or XRN could be issued in its own units rather than micro or nano-units. Instead an operation like SetPrecision would allow trading in micro, nano or pico in the future based on market demand. Arbitrary, unbounded precision is not desirable because this can lead to spam attacks (like sending 0.000000000000000000000000000001 coins). This is effectively fixed precision so under the hood it is still basically an integer, but the fixed precision can be increased so its more adaptable long term than just an integer. | diff --git a/proto/regen/ecocredit/v1alpha1/query.proto b/proto/regen/ecocredit/v1alpha1/query.proto index 9e0aa33adb..8919f478c5 100644 --- a/proto/regen/ecocredit/v1alpha1/query.proto +++ b/proto/regen/ecocredit/v1alpha1/query.proto @@ -34,11 +34,11 @@ service Query { "/regen/ecocredit/v1alpha1/batch_info/{batch_denom}/supply"; } - // Precision queries the number of decimal places that can be used to - // represent credits in a batch. See Tx/SetPrecision for more details. - rpc Precision(QueryPrecisionRequest) returns (QueryPrecisionResponse) { + // CreditTypes returns the list of allowed types that credit classes can have. + // See Types/CreditType for more details. + rpc CreditTypes(QueryCreditTypesRequest) returns (QueryCreditTypesResponse) { option (google.api.http).get = - "/regen/ecocredit/v1alpha1/batches/{batch_denom}/precision"; + "/regen/ecocredit/v1alpha1/credit-types"; } } @@ -113,20 +113,11 @@ message QuerySupplyResponse { [ (gogoproto.moretags) = "yaml:\"retired_supply\"" ]; } -// QueryPrecisionRequest is the Query/Precision request type. -message QueryPrecisionRequest { +// QueryCreditTypesRequest is the Query/Credit_Types request type +message QueryCreditTypesRequest {} - // batch_denom is the unique ID of credit batch to query. - string batch_denom = 1 [ (gogoproto.moretags) = "yaml:\"batch_denom\"" ]; -} - -// QueryPrecisionResponse is the Query/Precision response type. -message QueryPrecisionResponse { - - // max_decimal_places is the maximum number of decimal places that can be used - // to represent some quantity of credits. It is an experimental feature - // to concretely explore an idea proposed in - // https://github.com/cosmos/cosmos-sdk/issues/7113. - uint32 max_decimal_places = 1 - [ (gogoproto.moretags) = "yaml:\"max_decimal_places\"" ]; +// QueryCreditTypesRequest is the Query/Credit_Types response type +message QueryCreditTypesResponse { + // list of credit types + repeated CreditType credit_types = 1; } diff --git a/proto/regen/ecocredit/v1alpha1/tx.proto b/proto/regen/ecocredit/v1alpha1/tx.proto index 0472a9c79c..4476ceb590 100644 --- a/proto/regen/ecocredit/v1alpha1/tx.proto +++ b/proto/regen/ecocredit/v1alpha1/tx.proto @@ -30,28 +30,6 @@ service Msg { // deducts them from the tradable supply, effectively cancelling their // issuance on Regen Ledger rpc Cancel(MsgCancel) returns (MsgCancelResponse); - - // SetPrecision allows an issuer to increase the decimal precision of a credit - // batch. It is an experimental feature to concretely explore an idea proposed - // in https://github.com/cosmos/cosmos-sdk/issues/7113. The number of decimal - // places allowed for a credit batch is determined by the original number of - // decimal places used with calling CreatBatch. SetPrecision allows the number - // of allowed decimal places to be increased, effectively making the supply - // more granular without actually changing any balances. It allows asset - // issuers to be able to issue an asset without needing to think about how - // many subdivisions are needed upfront. While it may not be relevant for - // credits which likely have a fairly stable market value, I wanted to - // experiment a bit and this serves as a proof of concept for a broader bank - // redesign where say for instance a coin like the ATOM or XRN could be issued - // in its own units rather than micro or nano-units. Instead an operation like - // SetPrecision would allow trading in micro, nano or pico in the future based - // on market demand. Arbitrary, unbounded precision is not desirable because - // this can lead to spam attacks (like sending - // 0.000000000000000000000000000001 coins). This is effectively fixed - // precision so under the hood it is still basically an integer, but the fixed - // precision can be increased so its more adaptable long term than just an - // integer. - rpc SetPrecision(MsgSetPrecision) returns (MsgSetPrecisionResponse); } // MsgCreateClass is the Msg/CreateClass request type. @@ -67,6 +45,9 @@ message MsgCreateClass { // metadata is any arbitrary metadata to attached to the credit class. bytes metadata = 3; + + // credit_type describes the type of credit (e.g. "carbon", "biodiversity"). + string credit_type = 4; } // MsgCreateClassResponse is the Msg/CreateClass response type. @@ -246,24 +227,4 @@ message MsgCancel { } // MsgCancelResponse is the Msg/Cancel response type. -message MsgCancelResponse {} - -// MsgRetire is the Msg/SetPrecision request type. -message MsgSetPrecision { - - // issuer is the address of the batch issuer. - string issuer = 1; - - // batch_denom is the unique ID of the credit batch. - string batch_denom = 2 [ (gogoproto.moretags) = "yaml:\"batch_denom\"" ]; - - // max_decimal_places is the new maximum number of decimal places that can be - // used to represent some quantity of credits. It is an experimental - // feature to concretely explore an idea proposed in - // https://github.com/cosmos/cosmos-sdk/issues/7113. - uint32 max_decimal_places = 3 - [ (gogoproto.moretags) = "yaml:\"max_decimal_places\"" ]; -} - -// MsgRetire is the Msg/SetPrecision response type. -message MsgSetPrecisionResponse {} +message MsgCancelResponse {} \ No newline at end of file diff --git a/proto/regen/ecocredit/v1alpha1/types.proto b/proto/regen/ecocredit/v1alpha1/types.proto index 506096205a..5e918a0525 100644 --- a/proto/regen/ecocredit/v1alpha1/types.proto +++ b/proto/regen/ecocredit/v1alpha1/types.proto @@ -22,6 +22,9 @@ message ClassInfo { // metadata is any arbitrary metadata to attached to the credit class. bytes metadata = 4; + + // credit_type describes the type of credit (e.g. carbon, biodiversity), as well as unit and precision. + CreditType credit_type = 5; } // BatchInfo represents the high-level on-chain information for a credit batch. @@ -83,6 +86,9 @@ message Params { // allowlist_enabled is a param that enables/disables the allowlist for credit // creation bool allowlist_enabled = 3; + + // credit_types is a list of definitions for credit types + repeated CreditType credit_types = 4; } // GenesisState defines the state of the ecocredit module that is needed at genesis @@ -90,3 +96,20 @@ 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\""]; } + +// CreditType defines the measurement unit/precision of a certain credit type +// (e.g. carbon, biodiversity...) +message CreditType { + // the type of credit (e.g. carbon, biodiversity, etc) + string name = 1; + + // abbreviation is a 1-3 character uppercase abbreviation of the CreditType + // name, used in batch denominations within the CreditType. It must be unique. + string abbreviation = 2; + + // the measurement unit (e.g. kg, ton, etc) + string unit = 3; + + // the decimal precision + uint32 precision = 4; +} diff --git a/x/ecocredit/client/query.go b/x/ecocredit/client/query.go index 468bec5278..f97ac786a1 100644 --- a/x/ecocredit/client/query.go +++ b/x/ecocredit/client/query.go @@ -24,7 +24,7 @@ func QueryCmd(name string) *cobra.Command { QueryBatchInfoCmd(), QueryBalanceCmd(), QuerySupplyCmd(), - QueryPrecisionCmd(), + QueryCreditTypesCmd(), ) return cmd } @@ -109,20 +109,18 @@ func QuerySupplyCmd() *cobra.Command { }) } -func QueryPrecisionCmd() *cobra.Command { +func QueryCreditTypesCmd() *cobra.Command { return qflags(&cobra.Command{ - Use: "precision [batch_denom]", - 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), + Use: "types", + Short: "Retrieve the list of credit types", + Long: "Retrieve the list of credit types that contains the type name, measurement unit and precision", + Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) error { c, ctx, err := mkQueryClient(cmd) if err != nil { return err } - res, err := c.Precision(cmd.Context(), &ecocredit.QueryPrecisionRequest{ - BatchDenom: args[0], - }) + res, err := c.CreditTypes(cmd.Context(), &ecocredit.QueryCreditTypesRequest{}) return print(ctx, res, err) }, }) diff --git a/x/ecocredit/client/testsuite/query.go b/x/ecocredit/client/testsuite/query.go index b23289c9b8..f5c246da8e 100644 --- a/x/ecocredit/client/testsuite/query.go +++ b/x/ecocredit/client/testsuite/query.go @@ -257,46 +257,29 @@ func (s *IntegrationTestSuite) TestQuerySupply() { } } -func (s *IntegrationTestSuite) TestQueryPrecision() { +func (s *IntegrationTestSuite) TestQueryCreditTypes() { val := s.network.Validators[0] clientCtx := val.ClientCtx - + clientCtx.OutputFormat = "JSON" testCases := []struct { - name string - args []string - expectErr bool - expectedErrMsg string - expectedMaxDecimalPlaces uint32 + name string + args []string + expectErr bool + expectedErrMsg string + expectedCreditType []*ecocredit.CreditType }{ { - name: "missing credit batch", - args: []string{}, - expectErr: true, - expectedErrMsg: "Error: accepts 1 arg(s), received 0", - }, - { - name: "too many args", - args: []string{"abcde", "abcde"}, - expectErr: true, - expectedErrMsg: "Error: accepts 1 arg(s), received 2", - }, - { - name: "invalid credit batch", - args: []string{"abcde", fmt.Sprintf("--%s=json", tmcli.OutputFlag)}, - expectErr: false, - expectedMaxDecimalPlaces: 0, - }, - { - name: "valid credit batch", - args: []string{s.batchInfo.BatchDenom, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}, - expectErr: false, - expectedMaxDecimalPlaces: 6, + name: "should give credit type", + args: []string{}, + expectErr: false, + expectedErrMsg: "", + expectedCreditType: []*ecocredit.CreditType{s.classInfo.CreditType}, }, } for _, tc := range testCases { s.Run(tc.name, func() { - cmd := client.QueryPrecisionCmd() + cmd := client.QueryCreditTypesCmd() out, err := cli.ExecTestCLICmd(clientCtx, cmd, tc.args) if tc.expectErr { s.Require().Error(err) @@ -304,9 +287,9 @@ func (s *IntegrationTestSuite) TestQueryPrecision() { } else { s.Require().NoError(err, out.String()) - var res ecocredit.QueryPrecisionResponse + var res ecocredit.QueryCreditTypesResponse s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &res)) - s.Require().Equal(tc.expectedMaxDecimalPlaces, res.MaxDecimalPlaces) + s.Require().Equal(tc.expectedCreditType, res.CreditTypes) } }) } diff --git a/x/ecocredit/client/testsuite/tx.go b/x/ecocredit/client/testsuite/tx.go index e45e997d85..f6b2d2722b 100644 --- a/x/ecocredit/client/testsuite/tx.go +++ b/x/ecocredit/client/testsuite/tx.go @@ -30,9 +30,10 @@ type IntegrationTestSuite struct { } const ( - validMetadata = "AQ==" - classId = "18AV53K" - batchId = "1Lb4WV1" + validCreditType = "carbon" + validMetadata = "AQ==" + classId = "18AV53K" + batchId = "1Lb4WV1" ) var validMetadataBytes = []byte{0x1} @@ -86,6 +87,7 @@ func (s *IntegrationTestSuite) SetupSuite() { []string{ val.Address.String(), val.Address.String(), + validCreditType, validMetadata, fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), }, @@ -99,10 +101,11 @@ func (s *IntegrationTestSuite) SetupSuite() { s.Require().Equal(uint32(0), txResp.Code, out.String()) s.classInfo = &ecocredit.ClassInfo{ - ClassId: classId, - Designer: val.Address.String(), - Issuers: []string{val.Address.String()}, - Metadata: validMetadataBytes, + ClassId: classId, + Designer: val.Address.String(), + Issuers: []string{val.Address.String()}, + CreditType: ecocredit.DefaultParams().CreditTypes[0], + Metadata: validMetadataBytes, } startDate, err := client.ParseDate("start date", "2021-01-01") @@ -193,25 +196,31 @@ func (s *IntegrationTestSuite) TestTxCreateClass() { name: "missing designer", args: []string{}, expectErr: true, - expectedErrMsg: "Error: accepts 3 arg(s), received 0", + expectedErrMsg: "accepts 4 arg(s), received 0", }, { name: "missing issuer", args: []string{val0.Address.String()}, expectErr: true, - expectedErrMsg: "Error: accepts 3 arg(s), received 1", + expectedErrMsg: "accepts 4 arg(s), received 1", + }, + { + name: "missing credit type", + args: []string{validCreditType}, + expectErr: true, + expectedErrMsg: "accepts 4 arg(s), received 1", }, { name: "missing metadata", args: []string{val0.Address.String(), val0.Address.String()}, expectErr: true, - expectedErrMsg: "Error: accepts 3 arg(s), received 2", + expectedErrMsg: "accepts 4 arg(s), received 2", }, { name: "too many args", - args: []string{"abcde", "abcde", "abcde", "abcde"}, + args: []string{"abcde", "abcde", "abcde", "abcde", "dlskjf"}, expectErr: true, - expectedErrMsg: "Error: accepts 3 arg(s), received 4", + expectedErrMsg: "accepts 4 arg(s), received 5", }, { name: "invalid designer", @@ -219,6 +228,7 @@ func (s *IntegrationTestSuite) TestTxCreateClass() { []string{ "abcde", val0.Address.String(), + validCreditType, validMetadata, makeFlagFrom(val0.Address.String()), }, @@ -233,6 +243,7 @@ func (s *IntegrationTestSuite) TestTxCreateClass() { []string{ val0.Address.String(), "abcde", + validCreditType, validMetadata, makeFlagFrom(val0.Address.String()), }, @@ -247,6 +258,7 @@ func (s *IntegrationTestSuite) TestTxCreateClass() { []string{ val0.Address.String(), val0.Address.String(), + validCreditType, "=", makeFlagFrom(val0.Address.String()), }, @@ -261,6 +273,7 @@ func (s *IntegrationTestSuite) TestTxCreateClass() { []string{ val0.Address.String(), val0.Address.String(), + validCreditType, validMetadata, }, s.commonTxFlags()..., @@ -274,6 +287,7 @@ func (s *IntegrationTestSuite) TestTxCreateClass() { []string{ val0.Address.String(), val0.Address.String(), + validCreditType, validMetadata, makeFlagFrom(val0.Address.String()), }, @@ -298,6 +312,7 @@ func (s *IntegrationTestSuite) TestTxCreateClass() { }, ",", ), + validCreditType, validMetadata, makeFlagFrom(val0.Address.String()), }, diff --git a/x/ecocredit/client/tx.go b/x/ecocredit/client/tx.go index 314d4eb825..2cc0c7b787 100644 --- a/x/ecocredit/client/tx.go +++ b/x/ecocredit/client/tx.go @@ -5,7 +5,6 @@ import ( "encoding/json" "errors" "fmt" - "strconv" "strings" "time" @@ -37,7 +36,6 @@ func TxCmd(name string) *cobra.Command { TxSendCmd(), TxRetireCmd(), TxCancelCmd(), - TxSetPrecisionCmd(), ) return cmd } @@ -50,26 +48,31 @@ func txflags(cmd *cobra.Command) *cobra.Command { func TxCreateClassCmd() *cobra.Command { return txflags(&cobra.Command{ - Use: "create-class [designer] [issuer[,issuer]*] [metadata]", + Use: "create-class [designer] [issuer[,issuer]*] [credit type] [metadata]", Short: "Creates a new credit class", Long: `Creates a new credit class. Parameters: - 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), + designer: address of the account which designed the credit class + issuer: comma separated (no spaces) list of issuer account addresses. Example: "addr1,addr2" + credit type: the credit class type (e.g. carbon, biodiversity, etc) + metadata: base64 encoded metadata - arbitrary data attached to the credit class info`, + Args: cobra.ExactArgs(4), 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 sdkerrors.ErrInvalidRequest.Wrap("credit type is required") + } + creditType := args[2] + if args[3] == "" { return errors.New("base64_metadata is required") } - b, err := base64.StdEncoding.DecodeString(args[2]) + b, err := base64.StdEncoding.DecodeString(args[3]) if err != nil { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "metadata is malformed, proper base64 string is required") + return sdkerrors.ErrInvalidRequest.Wrap("metadata is malformed, proper base64 string is required") } clientCtx, err := sdkclient.GetClientTxContext(cmd) @@ -77,7 +80,7 @@ Parameters: return err } msg := ecocredit.MsgCreateClass{ - Designer: args[0], Issuers: issuers, Metadata: b, + Designer: args[0], Issuers: issuers, Metadata: b, CreditType: creditType, } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) }, @@ -348,31 +351,3 @@ Parameters: }, }) } - -func TxSetPrecisionCmd() *cobra.Command { - return txflags(&cobra.Command{ - Use: "set_precision [batch_denom] [decimals]", - Short: "Allows an issuer to increase the decimal precision of a credit batch", - Long: `Allows an issuer to increase the decimal precision of a credit batch. It is an experimental feature. - -Parameters: - batch_denom: credit batch ID - decimals: maximum number of decimals of precision`, - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - decimals, err := strconv.ParseUint(args[1], 10, 32) - if err != nil { - return err - } - clientCtx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - msg := ecocredit.MsgSetPrecision{ - Issuer: clientCtx.GetFromAddress().String(), - BatchDenom: args[0], MaxDecimalPlaces: uint32(decimals), - } - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) - }, - }) -} diff --git a/x/ecocredit/msgs.go b/x/ecocredit/msgs.go index 568cc4905e..5b5f0c7016 100644 --- a/x/ecocredit/msgs.go +++ b/x/ecocredit/msgs.go @@ -8,8 +8,8 @@ import ( ) var ( - _, _, _, _, _, _ sdk.Msg = &MsgCreateClass{}, &MsgCreateBatch{}, &MsgSend{}, - &MsgRetire{}, &MsgCancel{}, &MsgSetPrecision{} + _, _, _, _, _ sdk.Msg = &MsgCreateClass{}, &MsgCreateBatch{}, &MsgSend{}, + &MsgRetire{}, &MsgCancel{} ) func (m *MsgCreateClass) ValidateBasic() error { @@ -19,7 +19,11 @@ func (m *MsgCreateClass) ValidateBasic() error { } if len(m.Issuers) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "issuers cannot be empty") + return sdkerrors.ErrInvalidRequest.Wrap("issuers cannot be empty") + } + + if len(m.CreditType) == 0 { + return sdkerrors.ErrInvalidRequest.Wrap("credit class must have a credit type") } for _, issuer := range m.Issuers { _, err := sdk.AccAddressFromBech32(issuer) @@ -228,19 +232,3 @@ func (m *MsgCancel) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{addr} } - -func (m *MsgSetPrecision) ValidateBasic() error { - if len(m.BatchDenom) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "missing batch_denom") - } - return nil -} - -func (m *MsgSetPrecision) GetSigners() []sdk.AccAddress { - addr, err := sdk.AccAddressFromBech32(m.Issuer) - if err != nil { - panic(err) - } - - return []sdk.AccAddress{addr} -} diff --git a/x/ecocredit/msgs_test.go b/x/ecocredit/msgs_test.go index b42f4c0429..600111f83c 100644 --- a/x/ecocredit/msgs_test.go +++ b/x/ecocredit/msgs_test.go @@ -17,16 +17,18 @@ func TestMsgCreateClass(t *testing.T) { }{ "valid msg": { src: MsgCreateClass{ - Designer: addr1.String(), - Issuers: []string{addr1.String(), addr2.String()}, - Metadata: []byte("hello"), + Designer: addr1.String(), + Issuers: []string{addr1.String(), addr2.String()}, + CreditType: "carbon", + Metadata: []byte("hello"), }, expErr: false, }, "valid msg without metadata": { src: MsgCreateClass{ - Designer: addr1.String(), - Issuers: []string{addr1.String(), addr2.String()}, + Designer: addr1.String(), + CreditType: "carbon", + Issuers: []string{addr1.String(), addr2.String()}, }, expErr: false, }, @@ -36,20 +38,30 @@ func TestMsgCreateClass(t *testing.T) { }, "invalid without issuers": { src: MsgCreateClass{ - Designer: addr1.String(), + Designer: addr1.String(), + CreditType: "carbon", }, expErr: true, }, "invalid with wrong issuers": { src: MsgCreateClass{ - Designer: addr1.String(), - Issuers: []string{"xyz", "xyz1"}, + Designer: addr1.String(), + CreditType: "carbon", + Issuers: []string{"xyz", "xyz1"}, }, expErr: true, }, "invalid with wrong designer": { src: MsgCreateClass{ - Designer: "wrongDesigner", + Designer: "wrongDesigner", + CreditType: "carbon", + Issuers: []string{addr1.String(), addr2.String()}, + }, + expErr: true, + }, + "invalid with no credit type": { + src: MsgCreateClass{ + Designer: addr1.String(), Issuers: []string{addr1.String(), addr2.String()}, }, expErr: true, diff --git a/x/ecocredit/params.go b/x/ecocredit/params.go index b01c2d09b3..e292489588 100644 --- a/x/ecocredit/params.go +++ b/x/ecocredit/params.go @@ -2,8 +2,10 @@ package ecocredit import ( "fmt" + "regexp" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) @@ -13,6 +15,12 @@ var ( KeyCreditClassFee = []byte("CreditClassFee") KeyAllowedClassDesigners = []byte("AllowedClassDesigners") KeyAllowlistEnabled = []byte("AllowlistEnabled") + KeyCreditTypes = []byte("CreditTypes") +) + +// TODO: remove after we open governance changes for precision +const ( + PRECISION uint32 = 6 ) func ParamKeyTable() paramtypes.KeyTable { @@ -25,6 +33,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyCreditClassFee, &p.CreditClassFee, validateCreditClassFee), paramtypes.NewParamSetPair(KeyAllowedClassDesigners, &p.AllowedClassDesigners, validateAllowlistCreditDesigners), paramtypes.NewParamSetPair(KeyAllowlistEnabled, &p.AllowlistEnabled, validateAllowlistEnabled), + paramtypes.NewParamSetPair(KeyCreditTypes, &p.CreditTypes, validateCreditTypes), } } @@ -64,14 +73,90 @@ func validateAllowlistEnabled(i interface{}) error { return nil } -func NewParams(creditClassFee sdk.Coins, allowlist []string, allowlistEnabled bool) Params { +func validateCreditTypes(i interface{}) error { + creditTypes, ok := i.([]*CreditType) + if !ok { + return fmt.Errorf("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 := 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 types 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 letters: got %s", abbr) + } + return nil +} + +func NewParams(creditClassFee sdk.Coins, allowlist []string, allowlistEnabled bool, creditTypes []*CreditType) Params { return Params{ CreditClassFee: creditClassFee, AllowedClassDesigners: allowlist, AllowlistEnabled: allowlistEnabled, + CreditTypes: creditTypes, } } func DefaultParams() Params { - return NewParams(sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, DefaultCreditClassFeeTokens)), []string{}, false) + return NewParams( + sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, DefaultCreditClassFeeTokens)), + []string{}, + false, + []*CreditType{ + { + Name: "carbon", + Abbreviation: "C", + Unit: "ton", + Precision: PRECISION, + }, + }, + ) } diff --git a/x/ecocredit/params_test.go b/x/ecocredit/params_test.go index 38cc44e4bb..9e7476d9ce 100644 --- a/x/ecocredit/params_test.go +++ b/x/ecocredit/params_test.go @@ -2,9 +2,10 @@ package ecocredit import ( "fmt" + "testing" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "testing" ) func TestDefaultParams(t *testing.T) { @@ -12,6 +13,14 @@ func TestDefaultParams(t *testing.T) { CreditClassFee: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, DefaultCreditClassFeeTokens)), AllowedClassDesigners: []string{}, AllowlistEnabled: false, + CreditTypes: []*CreditType{ + { + Name: "carbon", + Abbreviation: "C", + Unit: "ton", + Precision: PRECISION, + }, + }, } df := DefaultParams() @@ -132,3 +141,91 @@ func Test_validateCreditClassFee(t *testing.T) { }) } } + +func Test_validateCreditTypes(t *testing.T) { + tests := []struct { + name string + args interface{} + wantErr bool + }{ + { + name: "valid credit types", + args: []*CreditType{ + {Name: "carbon", Abbreviation: "C", Unit: "ton", Precision: 6}, + {Name: "biodiversity", Abbreviation: "BIO", Unit: "mi", Precision: 6}, + }, + wantErr: false, + }, + { + name: "wrong type", + args: []*ClassInfo{ + { + ClassId: "foo", + Designer: "0xdeadbeef", + Issuers: []string{"not", "an", "address"}, + Metadata: nil, + CreditType: nil, + }, + }, + wantErr: true, + }, + { + name: "cant have duplicate names", + args: []*CreditType{ + {Name: "carbon", Abbreviation: "C", Unit: "ton", Precision: 6}, + {Name: "carbon", Abbreviation: "CAR", Unit: "ton", Precision: 6}, + }, + wantErr: true, + }, + { + name: "cant use non-normalized credit type name", + args: []*CreditType{{Name: "biODiVerSitY", Abbreviation: "BIO", Unit: "ton", Precision: 6}}, + wantErr: true, + }, + { + name: "cant use empty name", + args: []*CreditType{{Name: "", Abbreviation: "C", Unit: "ton", Precision: 6}}, + wantErr: true, + }, + { + name: "cant have duplicate abbreviations", + args: []*CreditType{ + {Name: "carbon", Abbreviation: "C", Unit: "ton", Precision: 6}, + {Name: "carbonic-acid", Abbreviation: "C", Unit: "ton", Precision: 6}, + }, + wantErr: true, + }, + { + name: "cant use empty abbreviation", + args: []*CreditType{{Name: "carbon", Unit: "ton", Precision: 6}}, + wantErr: true, + }, + { + name: "cant use lowercase abbreviation", + args: []*CreditType{{Name: "carbon", Abbreviation: "c", Unit: "ton", Precision: 6}}, + wantErr: true, + }, + { + name: "cant use longer than 3 letter abbreviation", + args: []*CreditType{{Name: "carbon", Abbreviation: "CARB", Unit: "ton", Precision: 6}}, + wantErr: true, + }, + { + name: "cant use precision other than 6", + args: []*CreditType{{Name: "carbon", Abbreviation: "C", Unit: "ton", Precision: 0}}, + wantErr: true, + }, + { + name: "cant use empty units", + args: []*CreditType{{Name: "carbon", Abbreviation: "C", Unit: "", Precision: 6}}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := validateCreditTypes(tt.args); (err != nil) != tt.wantErr { + t.Errorf("validateCreditTypes() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/x/ecocredit/query.pb.go b/x/ecocredit/query.pb.go index 5c267473e9..6cf4990288 100644 --- a/x/ecocredit/query.pb.go +++ b/x/ecocredit/query.pb.go @@ -426,24 +426,22 @@ func (m *QuerySupplyResponse) GetRetiredSupply() string { return "" } -// QueryPrecisionRequest is the Query/Precision request type. -type QueryPrecisionRequest struct { - // batch_denom is the unique ID of credit batch to query. - BatchDenom string `protobuf:"bytes,1,opt,name=batch_denom,json=batchDenom,proto3" json:"batch_denom,omitempty" yaml:"batch_denom"` +// QueryCreditTypesRequest is the Query/Credit_Types request type +type QueryCreditTypesRequest struct { } -func (m *QueryPrecisionRequest) Reset() { *m = QueryPrecisionRequest{} } -func (m *QueryPrecisionRequest) String() string { return proto.CompactTextString(m) } -func (*QueryPrecisionRequest) ProtoMessage() {} -func (*QueryPrecisionRequest) Descriptor() ([]byte, []int) { +func (m *QueryCreditTypesRequest) Reset() { *m = QueryCreditTypesRequest{} } +func (m *QueryCreditTypesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryCreditTypesRequest) ProtoMessage() {} +func (*QueryCreditTypesRequest) Descriptor() ([]byte, []int) { return fileDescriptor_6a16cc4c1db940dc, []int{8} } -func (m *QueryPrecisionRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryCreditTypesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryPrecisionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryCreditTypesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryPrecisionRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryCreditTypesRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -453,46 +451,36 @@ func (m *QueryPrecisionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byt return b[:n], nil } } -func (m *QueryPrecisionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryPrecisionRequest.Merge(m, src) +func (m *QueryCreditTypesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryCreditTypesRequest.Merge(m, src) } -func (m *QueryPrecisionRequest) XXX_Size() int { +func (m *QueryCreditTypesRequest) XXX_Size() int { return m.Size() } -func (m *QueryPrecisionRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryPrecisionRequest.DiscardUnknown(m) +func (m *QueryCreditTypesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryCreditTypesRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryPrecisionRequest proto.InternalMessageInfo - -func (m *QueryPrecisionRequest) GetBatchDenom() string { - if m != nil { - return m.BatchDenom - } - return "" -} +var xxx_messageInfo_QueryCreditTypesRequest proto.InternalMessageInfo -// QueryPrecisionResponse is the Query/Precision response type. -type QueryPrecisionResponse struct { - // max_decimal_places is the maximum number of decimal places that can be used - // to represent some quantity of credits. It is an experimental feature - // to concretely explore an idea proposed in - // https://github.com/cosmos/cosmos-sdk/issues/7113. - MaxDecimalPlaces uint32 `protobuf:"varint,1,opt,name=max_decimal_places,json=maxDecimalPlaces,proto3" json:"max_decimal_places,omitempty" yaml:"max_decimal_places"` +// QueryCreditTypesRequest is the Query/Credit_Types response type +type QueryCreditTypesResponse struct { + // list of credit types + CreditTypes []*CreditType `protobuf:"bytes,1,rep,name=credit_types,json=creditTypes,proto3" json:"credit_types,omitempty"` } -func (m *QueryPrecisionResponse) Reset() { *m = QueryPrecisionResponse{} } -func (m *QueryPrecisionResponse) String() string { return proto.CompactTextString(m) } -func (*QueryPrecisionResponse) ProtoMessage() {} -func (*QueryPrecisionResponse) Descriptor() ([]byte, []int) { +func (m *QueryCreditTypesResponse) Reset() { *m = QueryCreditTypesResponse{} } +func (m *QueryCreditTypesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryCreditTypesResponse) ProtoMessage() {} +func (*QueryCreditTypesResponse) Descriptor() ([]byte, []int) { return fileDescriptor_6a16cc4c1db940dc, []int{9} } -func (m *QueryPrecisionResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryCreditTypesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryPrecisionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryCreditTypesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryPrecisionResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryCreditTypesResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -502,23 +490,23 @@ func (m *QueryPrecisionResponse) XXX_Marshal(b []byte, deterministic bool) ([]by return b[:n], nil } } -func (m *QueryPrecisionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryPrecisionResponse.Merge(m, src) +func (m *QueryCreditTypesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryCreditTypesResponse.Merge(m, src) } -func (m *QueryPrecisionResponse) XXX_Size() int { +func (m *QueryCreditTypesResponse) XXX_Size() int { return m.Size() } -func (m *QueryPrecisionResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryPrecisionResponse.DiscardUnknown(m) +func (m *QueryCreditTypesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryCreditTypesResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryPrecisionResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryCreditTypesResponse proto.InternalMessageInfo -func (m *QueryPrecisionResponse) GetMaxDecimalPlaces() uint32 { +func (m *QueryCreditTypesResponse) GetCreditTypes() []*CreditType { if m != nil { - return m.MaxDecimalPlaces + return m.CreditTypes } - return 0 + return nil } func init() { @@ -530,8 +518,8 @@ func init() { proto.RegisterType((*QueryBalanceResponse)(nil), "regen.ecocredit.v1alpha1.QueryBalanceResponse") proto.RegisterType((*QuerySupplyRequest)(nil), "regen.ecocredit.v1alpha1.QuerySupplyRequest") proto.RegisterType((*QuerySupplyResponse)(nil), "regen.ecocredit.v1alpha1.QuerySupplyResponse") - proto.RegisterType((*QueryPrecisionRequest)(nil), "regen.ecocredit.v1alpha1.QueryPrecisionRequest") - proto.RegisterType((*QueryPrecisionResponse)(nil), "regen.ecocredit.v1alpha1.QueryPrecisionResponse") + proto.RegisterType((*QueryCreditTypesRequest)(nil), "regen.ecocredit.v1alpha1.QueryCreditTypesRequest") + proto.RegisterType((*QueryCreditTypesResponse)(nil), "regen.ecocredit.v1alpha1.QueryCreditTypesResponse") } func init() { @@ -539,52 +527,52 @@ func init() { } var fileDescriptor_6a16cc4c1db940dc = []byte{ - // 718 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0x4f, 0x6f, 0xd3, 0x3e, - 0x18, 0xc7, 0x97, 0xe9, 0xf7, 0xdb, 0xa8, 0xa7, 0x6d, 0xc8, 0xfb, 0xa3, 0xad, 0x82, 0x16, 0x05, - 0x0e, 0x1c, 0x58, 0x4c, 0x07, 0xd2, 0xc4, 0xb8, 0xb0, 0x6e, 0x12, 0x1a, 0x13, 0xd2, 0x16, 0x6e, - 0x5c, 0x2a, 0x37, 0xf1, 0xd2, 0x88, 0xc4, 0xce, 0x12, 0x17, 0x56, 0x4d, 0xbb, 0xf0, 0x0a, 0x90, - 0xb8, 0xc2, 0x19, 0xc4, 0x0d, 0x89, 0x17, 0xc1, 0x71, 0x12, 0x17, 0x4e, 0x15, 0x5a, 0x79, 0x05, - 0x15, 0x2f, 0x00, 0xd5, 0x7f, 0xda, 0xb4, 0x5d, 0x49, 0xa7, 0xdd, 0xe2, 0xc7, 0x8f, 0xbf, 0xfe, - 0x7c, 0x6d, 0x3f, 0x4f, 0xc0, 0x9d, 0x98, 0x78, 0x84, 0x22, 0xe2, 0x30, 0x27, 0x26, 0xae, 0xcf, - 0xd1, 0xeb, 0x12, 0x0e, 0xa2, 0x1a, 0x2e, 0xa1, 0xa3, 0x3a, 0x89, 0x1b, 0x56, 0x14, 0x33, 0xce, - 0xe0, 0x8a, 0xc8, 0xb2, 0xba, 0x59, 0x96, 0xce, 0xca, 0xdf, 0xf0, 0x18, 0xf3, 0x02, 0x82, 0x70, - 0xe4, 0x23, 0x4c, 0x29, 0xe3, 0x98, 0xfb, 0x8c, 0x26, 0x72, 0x5d, 0x7e, 0xb4, 0x3a, 0x6f, 0x44, - 0x44, 0x67, 0x2d, 0x7a, 0xcc, 0x63, 0xe2, 0x13, 0x75, 0xbe, 0x64, 0xd4, 0x7c, 0x0a, 0x96, 0x0e, - 0x3a, 0x08, 0xdb, 0x01, 0x4e, 0x92, 0x5d, 0x7a, 0xc8, 0x6c, 0x72, 0x54, 0x27, 0x09, 0x87, 0x16, - 0xb8, 0xe6, 0x74, 0x62, 0x15, 0xdf, 0x5d, 0x31, 0x6e, 0x19, 0x77, 0x73, 0xe5, 0x85, 0x76, 0xb3, - 0x38, 0xdf, 0xc0, 0x61, 0xb0, 0x69, 0xea, 0x19, 0xd3, 0x9e, 0x16, 0x9f, 0xbb, 0xae, 0x79, 0x00, - 0x96, 0x07, 0x85, 0x92, 0x88, 0xd1, 0x84, 0xc0, 0x0d, 0xf0, 0x9f, 0x4f, 0x0f, 0x99, 0x50, 0x99, - 0x59, 0xbf, 0x6d, 0x8d, 0x72, 0x69, 0xf5, 0x96, 0x8a, 0x05, 0xe6, 0xbe, 0x62, 0x2b, 0x63, 0xee, - 0xd4, 0xd2, 0x6c, 0x1b, 0x60, 0xa6, 0xda, 0x89, 0x55, 0x5c, 0x42, 0x59, 0xa8, 0xf0, 0x96, 0xdb, - 0xcd, 0x22, 0x94, 0x78, 0xa9, 0x49, 0xd3, 0x06, 0x62, 0xb4, 0x23, 0x06, 0x1a, 0x32, 0xa5, 0x78, - 0x59, 0xc8, 0xde, 0x52, 0x09, 0x59, 0x03, 0x0b, 0x4a, 0x32, 0xc0, 0xd4, 0x21, 0x1a, 0x71, 0x05, - 0x4c, 0x63, 0xc7, 0x61, 0x75, 0xca, 0x25, 0x9e, 0xad, 0x87, 0x83, 0xf0, 0x93, 0x63, 0xc3, 0x7f, - 0x34, 0xc0, 0x62, 0xff, 0x56, 0x8a, 0x7d, 0x1b, 0xcc, 0xf3, 0x18, 0xbb, 0xb8, 0x1a, 0x90, 0x0a, - 0x0e, 0x7b, 0x7b, 0x96, 0xf3, 0xed, 0x66, 0x71, 0x59, 0xaa, 0x0e, 0x24, 0x98, 0xf6, 0x9c, 0x8e, - 0x6c, 0x89, 0x00, 0x7c, 0x02, 0xe6, 0x62, 0xc2, 0xfd, 0x98, 0xb8, 0x5a, 0x43, 0x92, 0xad, 0xb6, - 0x9b, 0xc5, 0x25, 0xa9, 0xd1, 0x3f, 0x6f, 0xda, 0xb3, 0x2a, 0x20, 0x15, 0xcc, 0xe7, 0x00, 0x0a, - 0xbc, 0x17, 0xf5, 0x28, 0x0a, 0x1a, 0x57, 0xbe, 0xab, 0x0f, 0x86, 0x3a, 0x59, 0xad, 0x77, 0x81, - 0xdb, 0x44, 0x4c, 0xfd, 0xc3, 0xad, 0x4c, 0x48, 0xb9, 0x95, 0x62, 0x69, 0xb7, 0x4a, 0x63, 0xa4, - 0x5b, 0x2d, 0xa1, 0xdd, 0x4a, 0x85, 0xee, 0xe3, 0xdc, 0x8f, 0x89, 0xe3, 0x27, 0x3e, 0xa3, 0x57, - 0x36, 0x4c, 0xd4, 0xe3, 0x4c, 0x29, 0x2a, 0xcb, 0x7b, 0x00, 0x86, 0xf8, 0xb8, 0xe2, 0x12, 0xc7, - 0x0f, 0x71, 0x50, 0x89, 0x02, 0xec, 0x90, 0x44, 0x28, 0xcf, 0x96, 0x6f, 0xb6, 0x9b, 0xc5, 0x55, - 0xa9, 0x3c, 0x9c, 0x63, 0xda, 0xd7, 0x43, 0x7c, 0xbc, 0x23, 0x63, 0xfb, 0x22, 0xb4, 0xfe, 0x67, - 0x0a, 0xfc, 0x2f, 0xf6, 0x81, 0x9f, 0x0c, 0x90, 0xeb, 0xd6, 0x1c, 0x44, 0xa3, 0xdf, 0xfc, 0x85, - 0x1d, 0x22, 0x7f, 0x7f, 0xfc, 0x05, 0xd2, 0x87, 0xb9, 0xf1, 0xf6, 0xc7, 0xef, 0xf7, 0x93, 0x25, - 0x88, 0xd0, 0xc8, 0x8e, 0xa5, 0x3a, 0x0b, 0x3d, 0x64, 0xe8, 0x44, 0x77, 0x99, 0x53, 0xf8, 0xc5, - 0x00, 0xb9, 0x6e, 0xe1, 0x65, 0x92, 0x0e, 0xf6, 0x8b, 0x4c, 0xd2, 0xa1, 0x76, 0x60, 0x6e, 0x0a, - 0xd2, 0x87, 0x70, 0x7d, 0x34, 0xa9, 0xbc, 0x47, 0x49, 0x9a, 0xba, 0xd3, 0x53, 0xf8, 0xcd, 0x00, - 0xd3, 0xaa, 0x44, 0xe1, 0x5a, 0xe6, 0xce, 0xe9, 0xae, 0x91, 0xb7, 0xc6, 0x4d, 0x57, 0x98, 0xcf, - 0x04, 0xe6, 0x0e, 0x2c, 0x67, 0x60, 0x92, 0xa4, 0x9f, 0x11, 0x55, 0xa5, 0x50, 0x82, 0x4e, 0x54, - 0x5b, 0x3a, 0x85, 0x9f, 0x0d, 0x30, 0xa5, 0xaa, 0xe3, 0x5e, 0x06, 0x46, 0x5f, 0x85, 0xe7, 0xd7, - 0xc6, 0xcc, 0x56, 0xcc, 0x5b, 0x82, 0xf9, 0x31, 0x7c, 0x74, 0xf9, 0xa3, 0x45, 0xb2, 0x16, 0xe1, - 0x57, 0x03, 0xe4, 0xba, 0x55, 0x92, 0xf9, 0x1c, 0x06, 0x2b, 0x34, 0xf3, 0x39, 0x0c, 0x15, 0xe0, - 0xd8, 0xcc, 0x43, 0xe7, 0x1c, 0x69, 0xa9, 0xf2, 0xde, 0xf7, 0xf3, 0x82, 0x71, 0x76, 0x5e, 0x30, - 0x7e, 0x9d, 0x17, 0x8c, 0x77, 0xad, 0xc2, 0xc4, 0x59, 0xab, 0x30, 0xf1, 0xb3, 0x55, 0x98, 0x78, - 0x59, 0xf2, 0x7c, 0x5e, 0xab, 0x57, 0x2d, 0x87, 0x85, 0x52, 0x7e, 0x8d, 0x12, 0xfe, 0x86, 0xc5, - 0xaf, 0xd4, 0x28, 0x20, 0xae, 0x47, 0x62, 0x74, 0xdc, 0xdb, 0xb5, 0x3a, 0x25, 0x7e, 0xde, 0x0f, - 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x31, 0xbc, 0xd9, 0xb3, 0x58, 0x08, 0x00, 0x00, + // 711 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xcf, 0x6b, 0x13, 0x41, + 0x14, 0xc7, 0x3b, 0x55, 0x5b, 0x3b, 0xd1, 0x16, 0xa6, 0x3f, 0x4c, 0x17, 0x49, 0xca, 0x58, 0xa4, + 0x07, 0xb3, 0x63, 0xa2, 0x50, 0xac, 0x17, 0x9b, 0x16, 0x4a, 0x15, 0xc1, 0xae, 0x9e, 0xbc, 0x84, + 0xc9, 0xee, 0x74, 0xb3, 0xb8, 0xd9, 0xd9, 0xee, 0x6e, 0xd4, 0x50, 0x7a, 0xf1, 0x2f, 0x10, 0xbc, + 0xea, 0x4d, 0x50, 0x3c, 0xfb, 0x47, 0x78, 0x2c, 0x78, 0xf1, 0x14, 0xa4, 0x15, 0xbc, 0xe7, 0x2f, + 0x90, 0xcc, 0xcc, 0x26, 0x9b, 0xb4, 0xe9, 0x26, 0x78, 0x9b, 0x79, 0xf3, 0xde, 0x77, 0x3e, 0x6f, + 0xf3, 0xbe, 0x13, 0xb8, 0x1a, 0x30, 0x9b, 0x79, 0x84, 0x99, 0xdc, 0x0c, 0x98, 0xe5, 0x44, 0xe4, + 0x75, 0x91, 0xba, 0x7e, 0x8d, 0x16, 0xc9, 0x41, 0x83, 0x05, 0x4d, 0xdd, 0x0f, 0x78, 0xc4, 0x51, + 0x56, 0x64, 0xe9, 0xdd, 0x2c, 0x3d, 0xce, 0xd2, 0x6e, 0xda, 0x9c, 0xdb, 0x2e, 0x23, 0xd4, 0x77, + 0x08, 0xf5, 0x3c, 0x1e, 0xd1, 0xc8, 0xe1, 0x5e, 0x28, 0xeb, 0xb4, 0xe1, 0xea, 0x51, 0xd3, 0x67, + 0x71, 0xd6, 0x82, 0xcd, 0x6d, 0x2e, 0x96, 0xa4, 0xb3, 0x92, 0x51, 0xbc, 0x03, 0x17, 0xf7, 0x3a, + 0x08, 0x5b, 0x2e, 0x0d, 0xc3, 0x5d, 0x6f, 0x9f, 0x1b, 0xec, 0xa0, 0xc1, 0xc2, 0x08, 0xe9, 0xf0, + 0xaa, 0xd9, 0x89, 0x55, 0x1c, 0x2b, 0x0b, 0x56, 0xc0, 0xda, 0x4c, 0x79, 0xbe, 0xdd, 0xca, 0xcf, + 0x35, 0x69, 0xdd, 0xdd, 0xc0, 0xf1, 0x09, 0x36, 0xa6, 0xc5, 0x72, 0xd7, 0xc2, 0x7b, 0x70, 0x69, + 0x50, 0x28, 0xf4, 0xb9, 0x17, 0x32, 0xb4, 0x0e, 0x2f, 0x3b, 0xde, 0x3e, 0x17, 0x2a, 0x99, 0xd2, + 0x2d, 0x7d, 0x58, 0x97, 0x7a, 0xaf, 0x54, 0x14, 0xe0, 0x67, 0x8a, 0xad, 0x4c, 0x23, 0xb3, 0x96, + 0x64, 0x5b, 0x87, 0x99, 0x6a, 0x27, 0x56, 0xb1, 0x98, 0xc7, 0xeb, 0x0a, 0x6f, 0xa9, 0xdd, 0xca, + 0x23, 0x89, 0x97, 0x38, 0xc4, 0x06, 0x14, 0xbb, 0x6d, 0xb1, 0x89, 0x21, 0x13, 0x8a, 0xe3, 0x42, + 0xf6, 0x4a, 0x25, 0x64, 0x0d, 0xce, 0x2b, 0x49, 0x97, 0x7a, 0x26, 0x8b, 0x11, 0xb3, 0x70, 0x9a, + 0x9a, 0x26, 0x6f, 0x78, 0x91, 0xc4, 0x33, 0xe2, 0xed, 0x20, 0xfc, 0xe4, 0xc8, 0xf0, 0x9f, 0x00, + 0x5c, 0xe8, 0xbf, 0x4a, 0xb1, 0x6f, 0xc1, 0xb9, 0x28, 0xa0, 0x16, 0xad, 0xba, 0xac, 0x42, 0xeb, + 0xbd, 0x3b, 0xcb, 0x5a, 0xbb, 0x95, 0x5f, 0x92, 0xaa, 0x03, 0x09, 0xd8, 0x98, 0x8d, 0x23, 0x9b, + 0x22, 0x80, 0x1e, 0xc1, 0xd9, 0x80, 0x45, 0x4e, 0xc0, 0xac, 0x58, 0x43, 0x92, 0x2d, 0xb7, 0x5b, + 0xf9, 0x45, 0xa9, 0xd1, 0x7f, 0x8e, 0x8d, 0xeb, 0x2a, 0x20, 0x15, 0xf0, 0x53, 0x88, 0x04, 0xde, + 0xf3, 0x86, 0xef, 0xbb, 0xcd, 0xff, 0xfe, 0xad, 0x3e, 0x02, 0xf5, 0x65, 0x63, 0xbd, 0x73, 0xba, + 0x0d, 0xc5, 0xd1, 0x05, 0xdd, 0xca, 0x84, 0x44, 0xb7, 0x52, 0x2c, 0xd9, 0xad, 0xd2, 0x18, 0xda, + 0x6d, 0x2c, 0x11, 0x77, 0x2b, 0x15, 0xf0, 0x32, 0xbc, 0x21, 0xe7, 0x5d, 0xcc, 0xc7, 0x8b, 0x8e, + 0xd1, 0x54, 0xcb, 0xd8, 0x84, 0xd9, 0xb3, 0x47, 0x8a, 0x7e, 0x07, 0x5e, 0x93, 0x13, 0x55, 0x11, + 0xde, 0xcc, 0x82, 0x95, 0x4b, 0x6b, 0x99, 0xd2, 0xea, 0x05, 0xa6, 0xe8, 0x8a, 0x18, 0x19, 0xb3, + 0x27, 0x58, 0xfa, 0x3b, 0x05, 0xaf, 0x88, 0x5b, 0xd0, 0x17, 0x00, 0x67, 0xba, 0xd6, 0x41, 0x64, + 0xb8, 0xd4, 0xb9, 0x46, 0xd7, 0xee, 0x8e, 0x5e, 0x20, 0x7b, 0xc0, 0xeb, 0xef, 0x7e, 0xfe, 0xf9, + 0x30, 0x59, 0x44, 0x84, 0x0c, 0x7d, 0x78, 0xd4, 0x03, 0xe1, 0xed, 0x73, 0x72, 0x18, 0x3f, 0x16, + 0x47, 0xe8, 0x1b, 0x80, 0x33, 0x5d, 0xff, 0xa4, 0x92, 0x0e, 0xda, 0x3e, 0x95, 0xf4, 0x8c, 0xab, + 0xf1, 0x86, 0x20, 0xbd, 0x8f, 0x4a, 0xc3, 0x49, 0xe5, 0xfc, 0x49, 0xd2, 0xc4, 0x2c, 0x1e, 0xa1, + 0xef, 0x00, 0x4e, 0x2b, 0xa7, 0xa1, 0x42, 0xea, 0xcd, 0x49, 0xf3, 0x6b, 0xfa, 0xa8, 0xe9, 0x0a, + 0xf3, 0xb1, 0xc0, 0xdc, 0x46, 0xe5, 0x14, 0x4c, 0x16, 0xf6, 0x33, 0x92, 0xaa, 0x14, 0x0a, 0xc9, + 0xa1, 0x7a, 0x5d, 0x8e, 0xd0, 0x57, 0x00, 0xa7, 0xd4, 0x90, 0xdf, 0x49, 0xc1, 0xe8, 0x33, 0xaa, + 0x56, 0x18, 0x31, 0x5b, 0x31, 0x6f, 0x0a, 0xe6, 0x87, 0xe8, 0xc1, 0xf8, 0x9f, 0x96, 0x48, 0x4b, + 0xa1, 0xcf, 0x00, 0x66, 0x12, 0x1e, 0x41, 0xc5, 0xb4, 0x49, 0x3c, 0x63, 0x35, 0xad, 0x34, 0x4e, + 0x89, 0x22, 0xd7, 0x05, 0xf9, 0x1a, 0xba, 0x7d, 0xc1, 0xf8, 0x8a, 0x7d, 0x41, 0x58, 0xb4, 0xfc, + 0xe4, 0xc7, 0x49, 0x0e, 0x1c, 0x9f, 0xe4, 0xc0, 0xef, 0x93, 0x1c, 0x78, 0x7f, 0x9a, 0x9b, 0x38, + 0x3e, 0xcd, 0x4d, 0xfc, 0x3a, 0xcd, 0x4d, 0xbc, 0x2c, 0xda, 0x4e, 0x54, 0x6b, 0x54, 0x75, 0x93, + 0xd7, 0xa5, 0x56, 0xc1, 0x63, 0xd1, 0x1b, 0x1e, 0xbc, 0x52, 0x3b, 0x97, 0x59, 0x36, 0x0b, 0xc8, + 0xdb, 0xde, 0x15, 0xd5, 0x29, 0xf1, 0xb7, 0x7b, 0xef, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xac, + 0xb5, 0x76, 0xe7, 0x12, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -608,9 +596,9 @@ type QueryClient interface { Balance(ctx context.Context, in *QueryBalanceRequest, opts ...grpc.CallOption) (*QueryBalanceResponse, error) // Supply queries the tradable and retired supply of a credit batch. Supply(ctx context.Context, in *QuerySupplyRequest, opts ...grpc.CallOption) (*QuerySupplyResponse, error) - // Precision queries the number of decimal places that can be used to - // represent credits in a batch. See Tx/SetPrecision for more details. - Precision(ctx context.Context, in *QueryPrecisionRequest, opts ...grpc.CallOption) (*QueryPrecisionResponse, error) + // CreditTypes returns the list of allowed types that credit classes can have. + // See Types/CreditType for more details. + CreditTypes(ctx context.Context, in *QueryCreditTypesRequest, opts ...grpc.CallOption) (*QueryCreditTypesResponse, error) } type queryClient struct { @@ -657,9 +645,9 @@ func (c *queryClient) Supply(ctx context.Context, in *QuerySupplyRequest, opts . return out, nil } -func (c *queryClient) Precision(ctx context.Context, in *QueryPrecisionRequest, opts ...grpc.CallOption) (*QueryPrecisionResponse, error) { - out := new(QueryPrecisionResponse) - err := c.cc.Invoke(ctx, "/regen.ecocredit.v1alpha1.Query/Precision", in, out, opts...) +func (c *queryClient) CreditTypes(ctx context.Context, in *QueryCreditTypesRequest, opts ...grpc.CallOption) (*QueryCreditTypesResponse, error) { + out := new(QueryCreditTypesResponse) + err := c.cc.Invoke(ctx, "/regen.ecocredit.v1alpha1.Query/CreditTypes", in, out, opts...) if err != nil { return nil, err } @@ -677,9 +665,9 @@ type QueryServer interface { Balance(context.Context, *QueryBalanceRequest) (*QueryBalanceResponse, error) // Supply queries the tradable and retired supply of a credit batch. Supply(context.Context, *QuerySupplyRequest) (*QuerySupplyResponse, error) - // Precision queries the number of decimal places that can be used to - // represent credits in a batch. See Tx/SetPrecision for more details. - Precision(context.Context, *QueryPrecisionRequest) (*QueryPrecisionResponse, error) + // CreditTypes returns the list of allowed types that credit classes can have. + // See Types/CreditType for more details. + CreditTypes(context.Context, *QueryCreditTypesRequest) (*QueryCreditTypesResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -698,8 +686,8 @@ func (*UnimplementedQueryServer) Balance(ctx context.Context, req *QueryBalanceR func (*UnimplementedQueryServer) Supply(ctx context.Context, req *QuerySupplyRequest) (*QuerySupplyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Supply not implemented") } -func (*UnimplementedQueryServer) Precision(ctx context.Context, req *QueryPrecisionRequest) (*QueryPrecisionResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Precision not implemented") +func (*UnimplementedQueryServer) CreditTypes(ctx context.Context, req *QueryCreditTypesRequest) (*QueryCreditTypesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreditTypes not implemented") } func RegisterQueryServer(s grpc1.Server, srv QueryServer) { @@ -778,20 +766,20 @@ func _Query_Supply_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } -func _Query_Precision_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryPrecisionRequest) +func _Query_CreditTypes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryCreditTypesRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).Precision(ctx, in) + return srv.(QueryServer).CreditTypes(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/regen.ecocredit.v1alpha1.Query/Precision", + FullMethod: "/regen.ecocredit.v1alpha1.Query/CreditTypes", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Precision(ctx, req.(*QueryPrecisionRequest)) + return srv.(QueryServer).CreditTypes(ctx, req.(*QueryCreditTypesRequest)) } return interceptor(ctx, in, info, handler) } @@ -817,8 +805,8 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Handler: _Query_Supply_Handler, }, { - MethodName: "Precision", - Handler: _Query_Precision_Handler, + MethodName: "CreditTypes", + Handler: _Query_CreditTypes_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -1096,7 +1084,7 @@ func (m *QuerySupplyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *QueryPrecisionRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryCreditTypesRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1106,27 +1094,20 @@ func (m *QueryPrecisionRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryPrecisionRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryCreditTypesRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryPrecisionRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryCreditTypesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.BatchDenom) > 0 { - i -= len(m.BatchDenom) - copy(dAtA[i:], m.BatchDenom) - i = encodeVarintQuery(dAtA, i, uint64(len(m.BatchDenom))) - i-- - dAtA[i] = 0xa - } return len(dAtA) - i, nil } -func (m *QueryPrecisionResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryCreditTypesResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1136,20 +1117,29 @@ func (m *QueryPrecisionResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryPrecisionResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryCreditTypesResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryPrecisionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryCreditTypesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.MaxDecimalPlaces != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.MaxDecimalPlaces)) - i-- - dAtA[i] = 0x8 + if len(m.CreditTypes) > 0 { + for iNdEx := len(m.CreditTypes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.CreditTypes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } } return len(dAtA) - i, nil } @@ -1281,27 +1271,26 @@ func (m *QuerySupplyResponse) Size() (n int) { return n } -func (m *QueryPrecisionRequest) Size() (n int) { +func (m *QueryCreditTypesRequest) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.BatchDenom) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } return n } -func (m *QueryPrecisionResponse) Size() (n int) { +func (m *QueryCreditTypesResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.MaxDecimalPlaces != 0 { - n += 1 + sovQuery(uint64(m.MaxDecimalPlaces)) + if len(m.CreditTypes) > 0 { + for _, e := range m.CreditTypes { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } } return n } @@ -2096,7 +2085,7 @@ func (m *QuerySupplyResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryPrecisionRequest) Unmarshal(dAtA []byte) error { +func (m *QueryCreditTypesRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2119,44 +2108,12 @@ func (m *QueryPrecisionRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryPrecisionRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryCreditTypesRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryPrecisionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryCreditTypesRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BatchDenom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BatchDenom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -2181,7 +2138,7 @@ func (m *QueryPrecisionRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryPrecisionResponse) Unmarshal(dAtA []byte) error { +func (m *QueryCreditTypesResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2204,17 +2161,17 @@ func (m *QueryPrecisionResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryPrecisionResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryCreditTypesResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryPrecisionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryCreditTypesResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxDecimalPlaces", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreditTypes", wireType) } - m.MaxDecimalPlaces = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2224,11 +2181,26 @@ func (m *QueryPrecisionResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.MaxDecimalPlaces |= uint32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CreditTypes = append(m.CreditTypes, &CreditType{}) + if err := m.CreditTypes[len(m.CreditTypes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/ecocredit/query.pb.gw.go b/x/ecocredit/query.pb.gw.go index 4c3309ea77..7f65ead42d 100644 --- a/x/ecocredit/query.pb.gw.go +++ b/x/ecocredit/query.pb.gw.go @@ -269,56 +269,20 @@ func local_request_Query_Supply_0(ctx context.Context, marshaler runtime.Marshal } -func request_Query_Precision_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryPrecisionRequest +func request_Query_CreditTypes_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryCreditTypesRequest var metadata runtime.ServerMetadata - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["batch_denom"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_denom") - } - - protoReq.BatchDenom, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_denom", err) - } - - msg, err := client.Precision(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.CreditTypes(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_Precision_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryPrecisionRequest +func local_request_Query_CreditTypes_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryCreditTypesRequest var metadata runtime.ServerMetadata - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["batch_denom"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_denom") - } - - protoReq.BatchDenom, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_denom", err) - } - - msg, err := server.Precision(ctx, &protoReq) + msg, err := server.CreditTypes(ctx, &protoReq) return msg, metadata, err } @@ -409,7 +373,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("GET", pattern_Query_Precision_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_CreditTypes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -418,14 +382,14 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_Precision_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_CreditTypes_0(rctx, inboundMarshaler, server, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Precision_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_CreditTypes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -550,7 +514,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("GET", pattern_Query_Precision_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_CreditTypes_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -559,14 +523,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_Precision_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_CreditTypes_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Precision_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_CreditTypes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -582,7 +546,7 @@ var ( pattern_Query_Supply_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"regen", "ecocredit", "v1alpha1", "batch_info", "batch_denom", "supply"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_Precision_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"regen", "ecocredit", "v1alpha1", "batches", "batch_denom", "precision"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_CreditTypes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"regen", "ecocredit", "v1alpha1", "credit-types"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -594,5 +558,5 @@ var ( forward_Query_Supply_0 = runtime.ForwardResponseMessage - forward_Query_Precision_0 = runtime.ForwardResponseMessage + forward_Query_CreditTypes_0 = runtime.ForwardResponseMessage ) diff --git a/x/ecocredit/server/credit_type.go b/x/ecocredit/server/credit_type.go new file mode 100644 index 0000000000..4681c3c78e --- /dev/null +++ b/x/ecocredit/server/credit_type.go @@ -0,0 +1,25 @@ +package server + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/regen-network/regen-ledger/x/ecocredit" +) + +func (s serverImpl) getCreditType(ctx sdk.Context, creditTypeName string) (*ecocredit.CreditType, error) { + creditTypes := s.getAllCreditTypes(ctx) + creditTypeName = ecocredit.NormalizeCreditTypeName(creditTypeName) + for _, creditType := range creditTypes { + if creditType.Name == creditTypeName { + return creditType, nil + } + } + return nil, fmt.Errorf("%s is not a valid credit type", creditTypeName) +} + +func (s serverImpl) getAllCreditTypes(ctx sdk.Context) []*ecocredit.CreditType { + var params ecocredit.Params + s.paramSpace.GetParamSet(ctx, ¶ms) + return params.CreditTypes +} diff --git a/x/ecocredit/server/data_prefixes.go b/x/ecocredit/server/data_prefixes.go index f269f3e875..af8b11865d 100644 --- a/x/ecocredit/server/data_prefixes.go +++ b/x/ecocredit/server/data_prefixes.go @@ -27,8 +27,3 @@ 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 72a55a047c..78b5c3173b 100644 --- a/x/ecocredit/server/msg_server.go +++ b/x/ecocredit/server/msg_server.go @@ -45,11 +45,17 @@ func (s serverImpl) CreateClass(goCtx context.Context, req *ecocredit.MsgCreateC return nil, err } + creditType, err := s.getCreditType(ctx.Context, req.CreditType) + if err != nil { + return nil, err + } + err = s.classInfoTable.Create(ctx, &ecocredit.ClassInfo{ - ClassId: classIDStr, - Designer: req.Designer, - Issuers: req.Issuers, - Metadata: req.Metadata, + ClassId: classIDStr, + Designer: req.Designer, + Issuers: req.Issuers, + Metadata: req.Metadata, + CreditType: creditType, }) if err != nil { return nil, err @@ -72,12 +78,16 @@ func (s serverImpl) CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateB if err := s.assertClassIssuer(ctx, classID, req.Issuer); err != nil { return nil, err } + classInfo, err := s.getClassInfo(ctx, classID) + if err != nil { + return nil, err + } + maxDecimalPlaces := classInfo.CreditType.Precision batchID := s.idSeq.NextVal(ctx) batchDenom := batchDenomT(fmt.Sprintf("%s/%s", classID, util.Uint64ToBase58Check(batchID))) tradableSupply := math.NewDecFromInt64(0) retiredSupply := math.NewDecFromInt64(0) - var maxDecimalPlaces uint32 = 0 store := ctx.KVStore(s.storeKey) @@ -93,7 +103,8 @@ func (s serverImpl) CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateB decPlaces := tradable.NumDecimalPlaces() if decPlaces > maxDecimalPlaces { - maxDecimalPlaces = decPlaces + return nil, sdkerrors.ErrInvalidRequest.Wrapf("tradable amount exceeds precision for credit type: "+ + "is %v, should be < %v", decPlaces, maxDecimalPlaces) } } @@ -105,7 +116,8 @@ func (s serverImpl) CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateB decPlaces := retired.NumDecimalPlaces() if decPlaces > maxDecimalPlaces { - maxDecimalPlaces = decPlaces + return nil, sdkerrors.ErrInvalidRequest.Wrapf("retired amount does not conform to credit type "+ + "precision: %v should be %v", decPlaces, maxDecimalPlaces) } } @@ -176,11 +188,6 @@ func (s serverImpl) CreateBatch(goCtx context.Context, req *ecocredit.MsgCreateB return nil, err } - err = setUInt32(store, MaxDecimalPlacesKey(batchDenom), maxDecimalPlaces) - if err != nil { - return nil, err - } - err = ctx.EventManager().EmitTypedEvent(&ecocredit.EventCreateBatch{ ClassId: classID, BatchDenom: string(batchDenom), @@ -209,7 +216,7 @@ func (s serverImpl) Send(goCtx context.Context, req *ecocredit.MsgSend) (*ecocre return nil, sdkerrors.ErrInvalidRequest.Wrapf("%s is not a valid credit batch denom", denom) } - maxDecimalPlaces, err := getUint32(store, MaxDecimalPlacesKey(denom)) + maxDecimalPlaces, err := s.getBatchPrecision(ctx, denom) if err != nil { return nil, err } @@ -286,7 +293,7 @@ func (s serverImpl) Retire(goCtx context.Context, req *ecocredit.MsgRetire) (*ec return nil, sdkerrors.ErrInvalidRequest.Wrapf("%s is not a valid credit batch denom", denom) } - maxDecimalPlaces, err := getUint32(store, MaxDecimalPlacesKey(denom)) + maxDecimalPlaces, err := s.getBatchPrecision(ctx, denom) if err != nil { return nil, err } @@ -330,12 +337,21 @@ func (s serverImpl) Cancel(goCtx context.Context, req *ecocredit.MsgCancel) (*ec return nil, sdkerrors.ErrInvalidRequest.Wrapf("%s is not a valid credit batch denom", denom) } - // Fetch the max precision of decimal values in this batch - maxDecimalPlaces, err := getUint32(store, MaxDecimalPlacesKey(denom)) + // Remove the credits from the total_amount in the batch and add + // them to amount_cancelled + var batchInfo ecocredit.BatchInfo + err := s.batchInfoTable.GetOne(ctx, orm.RowID(denom), &batchInfo) + if err != nil { + return nil, err + } + + classInfo, err := s.getClassInfo(ctx, batchInfo.ClassId) if err != nil { return nil, err } + maxDecimalPlaces := classInfo.CreditType.Precision + // Parse the amount of credits to cancel, checking it conforms // to the precision toCancel, err := math.NewPositiveFixedDecFromString(credit.Amount, maxDecimalPlaces) @@ -350,14 +366,6 @@ func (s serverImpl) Cancel(goCtx context.Context, req *ecocredit.MsgCancel) (*ec return nil, err } - // Remove the credits from the total_amount in the batch and add - // them to amount_cancelled - var batchInfo ecocredit.BatchInfo - err = s.batchInfoTable.GetOne(ctx, orm.RowID(denom), &batchInfo) - if err != nil { - return nil, err - } - totalAmount, err := math.NewPositiveFixedDecFromString(batchInfo.TotalAmount, maxDecimalPlaces) if err != nil { return nil, err @@ -396,38 +404,6 @@ func (s serverImpl) Cancel(goCtx context.Context, req *ecocredit.MsgCancel) (*ec return &ecocredit.MsgCancelResponse{}, nil } -func (s serverImpl) SetPrecision(goCtx context.Context, req *ecocredit.MsgSetPrecision) (*ecocredit.MsgSetPrecisionResponse, error) { - ctx := types.UnwrapSDKContext(goCtx) - var batchInfo ecocredit.BatchInfo - - err := s.batchInfoTable.GetOne(ctx, orm.RowID(req.BatchDenom), &batchInfo) - if err != nil { - return nil, err - } - - if req.Issuer != batchInfo.Issuer { - return nil, sdkerrors.ErrUnauthorized - } - - store := ctx.KVStore(s.storeKey) - key := MaxDecimalPlacesKey(batchDenomT(req.BatchDenom)) - x, err := getUint32(store, key) - if err != nil { - return nil, err - } - - if req.MaxDecimalPlaces <= x { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("Maximum decimal can only be increased, it is currently %d, and %d was requested", x, req.MaxDecimalPlaces)) - } - - err = setUInt32(store, key, req.MaxDecimalPlaces) - if err != nil { - return nil, err - } - - return &ecocredit.MsgSetPrecisionResponse{}, nil -} - // assertClassIssuer makes sure that the issuer is part of issuers of given classID. // Returns ErrUnauthorized otherwise. func (s serverImpl) assertClassIssuer(goCtx context.Context, classID, issuer string) error { @@ -474,6 +450,21 @@ func subtractTradableBalanceAndSupply(store sdk.KVStore, holder string, batchDen return nil } +func (s serverImpl) getBatchPrecision(ctx types.Context, denom batchDenomT) (uint32, error) { + var batchInfo ecocredit.BatchInfo + err := s.batchInfoTable.GetOne(ctx, orm.RowID(denom), &batchInfo) + if err != nil { + return 0, err + } + + classInfo, err := s.getClassInfo(ctx, batchInfo.ClassId) + if err != nil { + return 0, err + } + + return classInfo.CreditType.Precision, nil +} + // Checks if the given address is in the allowlist of credit class designers func (s serverImpl) isDesignerAllowListed(ctx sdk.Context, addr sdk.Address) (bool, error) { var params ecocredit.Params diff --git a/x/ecocredit/server/query_server.go b/x/ecocredit/server/query_server.go index 93601a0695..cc469c7b5d 100644 --- a/x/ecocredit/server/query_server.go +++ b/x/ecocredit/server/query_server.go @@ -75,13 +75,8 @@ func (s serverImpl) Supply(goCtx context.Context, request *ecocredit.QuerySupply }, nil } -func (s serverImpl) Precision(goCtx context.Context, request *ecocredit.QueryPrecisionRequest) (*ecocredit.QueryPrecisionResponse, error) { - ctx := types.UnwrapSDKContext(goCtx) - store := ctx.KVStore(s.storeKey) - x, err := getUint32(store, MaxDecimalPlacesKey(batchDenomT(request.BatchDenom))) - if err != nil { - return nil, err - } - - return &ecocredit.QueryPrecisionResponse{MaxDecimalPlaces: x}, nil +func (s serverImpl) CreditTypes(goCtx context.Context, _ *ecocredit.QueryCreditTypesRequest) (*ecocredit.QueryCreditTypesResponse, error) { + ctx := types.UnwrapSDKContext(goCtx).Context + creditTypes := s.getAllCreditTypes(ctx) + return &ecocredit.QueryCreditTypesResponse{CreditTypes: creditTypes}, nil } diff --git a/x/ecocredit/server/server.go b/x/ecocredit/server/server.go index 778b86e027..84c9eafb0a 100644 --- a/x/ecocredit/server/server.go +++ b/x/ecocredit/server/server.go @@ -11,14 +11,13 @@ import ( ) const ( - TradableBalancePrefix byte = 0x0 - TradableSupplyPrefix byte = 0x1 - RetiredBalancePrefix byte = 0x2 - RetiredSupplyPrefix byte = 0x3 - IDSeqPrefix byte = 0x4 - ClassInfoTablePrefix byte = 0x5 - BatchInfoTablePrefix byte = 0x6 - MaxDecimalPlacesPrefix byte = 0x7 + TradableBalancePrefix byte = 0x0 + TradableSupplyPrefix byte = 0x1 + RetiredBalancePrefix byte = 0x2 + RetiredSupplyPrefix byte = 0x3 + IDSeqPrefix byte = 0x4 + ClassInfoTablePrefix byte = 0x5 + BatchInfoTablePrefix byte = 0x6 ) type serverImpl struct { diff --git a/x/ecocredit/server/testsuite/suite.go b/x/ecocredit/server/testsuite/suite.go index 614aac9b2a..7751381d02 100644 --- a/x/ecocredit/server/testsuite/suite.go +++ b/x/ecocredit/server/testsuite/suite.go @@ -78,9 +78,10 @@ func (s *IntegrationTestSuite) TestScenario() { // create class with insufficient funds and it should fail createClsRes, err := s.msgClient.CreateClass(s.ctx, &ecocredit.MsgCreateClass{ - Designer: designer.String(), - Issuers: []string{issuer1, issuer2}, - Metadata: nil, + Designer: designer.String(), + Issuers: []string{issuer1, issuer2}, + Metadata: nil, + CreditType: "carbon", }) s.Require().Error(err) s.Require().Nil(createClsRes) @@ -89,9 +90,10 @@ func (s *IntegrationTestSuite) TestScenario() { s.Require().NoError(fundAccount(s.bankKeeper, s.sdkCtx, designer, sdk.NewCoins(sdk.NewInt64Coin("stake", 10000)))) createClsRes, err = s.msgClient.CreateClass(s.ctx, &ecocredit.MsgCreateClass{ - Designer: designer.String(), - Issuers: []string{issuer1, issuer2}, - Metadata: nil, + Designer: designer.String(), + Issuers: []string{issuer1, issuer2}, + Metadata: nil, + CreditType: "carbon", }) s.Require().NoError(err) s.Require().NotNil(createClsRes) @@ -105,8 +107,8 @@ func (s *IntegrationTestSuite) TestScenario() { // create batch t0, t1, t2 := "10.37", "1007.3869", "100" tSupply0 := "1117.7569" - r0, r1, r2 := "4.286", "10000.4589902", "0" - rSupply0 := "10004.7449902" + r0, r1, r2 := "4.286", "10000.45899", "0" + rSupply0 := "10004.74499" time1 := time.Now() time2 := time.Now() @@ -212,6 +214,12 @@ func (s *IntegrationTestSuite) TestScenario() { toCancel: "101", expectErr: true, }, + { + name: "can't cancel with a higher precision than the credit type", + holder: addr4, + toCancel: "0.1234567", + expectErr: true, + }, { name: "can't cancel no credits", holder: addr4, @@ -232,7 +240,7 @@ func (s *IntegrationTestSuite) TestScenario() { expTradable: "97.9998", expTradableSupply: "1115.7567", expRetired: "0", - expTotalAmount: "11120.5016902", + expTotalAmount: "11120.50169", expAmountCancelled: "2.0002", }, { @@ -243,7 +251,7 @@ func (s *IntegrationTestSuite) TestScenario() { expTradable: "0", expTradableSupply: "1017.7569", expRetired: "0", - expTotalAmount: "11022.5018902", + expTotalAmount: "11022.50189", expAmountCancelled: "100.0000", }, { @@ -260,7 +268,7 @@ func (s *IntegrationTestSuite) TestScenario() { expTradable: "9.37", expTradableSupply: "1016.7569", expRetired: "4.286", - expTotalAmount: "11021.5018902", + expTotalAmount: "11021.50189", expAmountCancelled: "101.0000", }, } @@ -327,7 +335,7 @@ func (s *IntegrationTestSuite) TestScenario() { expectErr: true, }, { - name: "can't use more than 7 decimal places", + name: "can't use more precision than the credit type allows (6)", toRetire: "10.00000001", retirementLocation: "AF", expectErr: true, @@ -364,7 +372,7 @@ func (s *IntegrationTestSuite) TestScenario() { expTradable: "9.3699", expRetired: "4.2861", expTradableSupply: "1016.7568", - expRetiredSupply: "10004.7450902", + expRetiredSupply: "10004.74509", }, { name: "can retire more credits", @@ -374,7 +382,7 @@ func (s *IntegrationTestSuite) TestScenario() { expTradable: "0.3699", expRetired: "13.2861", expTradableSupply: "1007.7568", - expRetiredSupply: "10013.7450902", + expRetiredSupply: "10013.74509", }, { name: "can retire all credits", @@ -384,7 +392,7 @@ func (s *IntegrationTestSuite) TestScenario() { expTradable: "0", expRetired: "13.656", expTradableSupply: "1007.3869", - expRetiredSupply: "10014.1149902", + expRetiredSupply: "10014.11499", }, { name: "can't retire any more credits", @@ -487,11 +495,11 @@ func (s *IntegrationTestSuite) TestScenario() { retirementLocation: "AF", expectErr: false, expTradableSender: "977.3869", - expRetiredSender: "10000.4589902", + expRetiredSender: "10000.45899", expTradableRecipient: "10", expRetiredRecipient: "20", expTradableSupply: "987.3869", - expRetiredSupply: "10034.1149902", + expRetiredSupply: "10034.11499", }, { name: "can send with no retirement location", @@ -500,11 +508,11 @@ func (s *IntegrationTestSuite) TestScenario() { retirementLocation: "", expectErr: false, expTradableSender: "967.3869", - expRetiredSender: "10000.4589902", + expRetiredSender: "10000.45899", expTradableRecipient: "20", expRetiredRecipient: "20", expTradableSupply: "987.3869", - expRetiredSupply: "10034.1149902", + expRetiredSupply: "10034.11499", }, { name: "can send all tradable", @@ -513,11 +521,11 @@ func (s *IntegrationTestSuite) TestScenario() { retirementLocation: "AF", expectErr: false, expTradableSender: "0", - expRetiredSender: "10000.4589902", + expRetiredSender: "10000.45899", expTradableRecipient: "87.3869", expRetiredRecipient: "920", expTradableSupply: "87.3869", - expRetiredSupply: "10934.1149902", + expRetiredSupply: "10934.11499", }, { name: "can't send any more", @@ -578,49 +586,6 @@ func (s *IntegrationTestSuite) TestScenario() { }) } - /**** TEST SET PRECISION ****/ - precisionCases := []struct { - name string - msg ecocredit.MsgSetPrecision - ok bool - }{ - { - "can NOT decrease the decimals", ecocredit.MsgSetPrecision{ - Issuer: issuer1, BatchDenom: batchDenom, MaxDecimalPlaces: 2}, - false, - }, { - "can NOT set to the same value", ecocredit.MsgSetPrecision{ - Issuer: issuer1, BatchDenom: batchDenom, MaxDecimalPlaces: 7}, - false, - }, { - "can increase", ecocredit.MsgSetPrecision{ - Issuer: issuer1, BatchDenom: batchDenom, MaxDecimalPlaces: 8}, - true, - }, { - "can NOT change precision of not existing denom", ecocredit.MsgSetPrecision{ - Issuer: issuer1, BatchDenom: "not/existing", MaxDecimalPlaces: 1}, - false, - }, - } - require := s.Require() - for _, tc := range precisionCases { - tc := tc - s.Run(tc.name, func() { - _, err := s.msgClient.SetPrecision(s.ctx, &tc.msg) - - if !tc.ok { - require.Error(err) - } else { - require.NoError(err) - res, err := s.queryClient.Precision(s.ctx, - &ecocredit.QueryPrecisionRequest{ - BatchDenom: tc.msg.BatchDenom}) - require.NoError(err) - require.Equal(tc.msg.MaxDecimalPlaces, res.MaxDecimalPlaces) - } - }) - } - /**** TEST ALLOWLIST CREDIT DESIGNERS ****/ allowlistCases := []struct { name string @@ -676,9 +641,10 @@ func (s *IntegrationTestSuite) TestScenario() { s.Require().NoError(fundAccount(s.bankKeeper, s.sdkCtx, tc.designerAcc, sdk.NewCoins(sdk.NewInt64Coin("stake", 10000)))) createClsRes, err = s.msgClient.CreateClass(s.ctx, &ecocredit.MsgCreateClass{ - Designer: tc.designerAcc.String(), - Issuers: []string{issuer1, issuer2}, - Metadata: nil, + Designer: tc.designerAcc.String(), + Issuers: []string{issuer1, issuer2}, + CreditType: "carbon", + Metadata: nil, }) if tc.wantErr { s.Require().Error(err) @@ -689,4 +655,88 @@ func (s *IntegrationTestSuite) TestScenario() { } }) } + + // Disable credit class allowlist for credit type tests + s.paramSpace.Set(s.sdkCtx, ecocredit.KeyAllowlistEnabled, false) + + /**** TEST CREDIT TYPES ****/ + creditTypeCases := []struct { + name string + creditTypes []*ecocredit.CreditType + msg ecocredit.MsgCreateClass + wantErr bool + }{ + { + name: "valid eco credit creation", + creditTypes: []*ecocredit.CreditType{ + {Name: "carbon", Abbreviation: "C", Unit: "ton", Precision: 3}, + }, + msg: ecocredit.MsgCreateClass{ + Designer: s.signers[0].String(), + Issuers: []string{s.signers[1].String(), s.signers[2].String()}, + Metadata: nil, + CreditType: "carbon", + }, + wantErr: false, + }, + { + name: "invalid request - not a valid credit type", + creditTypes: []*ecocredit.CreditType{ + {Name: "carbon", Abbreviation: "C", Unit: "ton", Precision: 3}, + }, + msg: ecocredit.MsgCreateClass{ + Designer: s.signers[0].String(), + Issuers: []string{s.signers[1].String(), s.signers[2].String()}, + Metadata: nil, + CreditType: "biodiversity", + }, + wantErr: true, + }, + { + name: "request with strange font should be valid", + creditTypes: []*ecocredit.CreditType{ + {Name: "carbon", Abbreviation: "C", Unit: "ton", Precision: 3}, + }, + msg: ecocredit.MsgCreateClass{ + Designer: s.signers[0].String(), + Issuers: []string{s.signers[1].String(), s.signers[2].String()}, + Metadata: nil, + CreditType: "cArBoN", + }, + wantErr: false, + }, + { + name: "empty credit types should error", + creditTypes: []*ecocredit.CreditType{}, + msg: ecocredit.MsgCreateClass{ + Designer: s.signers[0].String(), + Issuers: []string{s.signers[1].String(), s.signers[2].String()}, + Metadata: nil, + CreditType: "carbon", + }, + wantErr: true, + }, + } + + for _, tc := range creditTypeCases { + tc := tc + + s.Run(tc.name, func() { + require := s.Require() + s.paramSpace.Set(s.sdkCtx, ecocredit.KeyCreditTypes, tc.creditTypes) + designer, err := sdk.AccAddressFromBech32(tc.msg.Designer) + require.NoError(err) + + // fund the designer account so tx will go through + s.Require().NoError(fundAccount(s.bankKeeper, s.sdkCtx, designer, sdk.NewCoins(sdk.NewInt64Coin("stake", 10000)))) + res, err := s.msgClient.CreateClass(s.ctx, &tc.msg) + if tc.wantErr { + require.Error(err) + require.Nil(res) + } else { + require.NoError(err) + require.NotNil(res) + } + }) + } } diff --git a/x/ecocredit/tx.pb.go b/x/ecocredit/tx.pb.go index 4138712a8f..c9ab69f7a6 100644 --- a/x/ecocredit/tx.pb.go +++ b/x/ecocredit/tx.pb.go @@ -42,6 +42,8 @@ type MsgCreateClass struct { Issuers []string `protobuf:"bytes,2,rep,name=issuers,proto3" json:"issuers,omitempty"` // metadata is any arbitrary metadata to attached to the credit class. Metadata []byte `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"` + // credit_type describes the type of credit (e.g. "carbon", "biodiversity"). + CreditType string `protobuf:"bytes,4,opt,name=credit_type,json=creditType,proto3" json:"credit_type,omitempty"` } func (m *MsgCreateClass) Reset() { *m = MsgCreateClass{} } @@ -98,6 +100,13 @@ func (m *MsgCreateClass) GetMetadata() []byte { return nil } +func (m *MsgCreateClass) GetCreditType() string { + if m != nil { + return m.CreditType + } + return "" +} + // MsgCreateClassResponse is the Msg/CreateClass response type. type MsgCreateClassResponse struct { // class_id is the unique ID of the newly created credit class. @@ -875,110 +884,6 @@ func (m *MsgCancelResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCancelResponse proto.InternalMessageInfo -// MsgRetire is the Msg/SetPrecision request type. -type MsgSetPrecision struct { - // issuer is the address of the batch issuer. - Issuer string `protobuf:"bytes,1,opt,name=issuer,proto3" json:"issuer,omitempty"` - // batch_denom is the unique ID of the credit batch. - BatchDenom string `protobuf:"bytes,2,opt,name=batch_denom,json=batchDenom,proto3" json:"batch_denom,omitempty" yaml:"batch_denom"` - // max_decimal_places is the new maximum number of decimal places that can be - // used to represent some quantity of credits. It is an experimental - // feature to concretely explore an idea proposed in - // https://github.com/cosmos/cosmos-sdk/issues/7113. - MaxDecimalPlaces uint32 `protobuf:"varint,3,opt,name=max_decimal_places,json=maxDecimalPlaces,proto3" json:"max_decimal_places,omitempty" yaml:"max_decimal_places"` -} - -func (m *MsgSetPrecision) Reset() { *m = MsgSetPrecision{} } -func (m *MsgSetPrecision) String() string { return proto.CompactTextString(m) } -func (*MsgSetPrecision) ProtoMessage() {} -func (*MsgSetPrecision) Descriptor() ([]byte, []int) { - return fileDescriptor_96891bdd11ac56ed, []int{10} -} -func (m *MsgSetPrecision) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *MsgSetPrecision) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_MsgSetPrecision.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *MsgSetPrecision) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgSetPrecision.Merge(m, src) -} -func (m *MsgSetPrecision) XXX_Size() int { - return m.Size() -} -func (m *MsgSetPrecision) XXX_DiscardUnknown() { - xxx_messageInfo_MsgSetPrecision.DiscardUnknown(m) -} - -var xxx_messageInfo_MsgSetPrecision proto.InternalMessageInfo - -func (m *MsgSetPrecision) GetIssuer() string { - if m != nil { - return m.Issuer - } - return "" -} - -func (m *MsgSetPrecision) GetBatchDenom() string { - if m != nil { - return m.BatchDenom - } - return "" -} - -func (m *MsgSetPrecision) GetMaxDecimalPlaces() uint32 { - if m != nil { - return m.MaxDecimalPlaces - } - return 0 -} - -// MsgRetire is the Msg/SetPrecision response type. -type MsgSetPrecisionResponse struct { -} - -func (m *MsgSetPrecisionResponse) Reset() { *m = MsgSetPrecisionResponse{} } -func (m *MsgSetPrecisionResponse) String() string { return proto.CompactTextString(m) } -func (*MsgSetPrecisionResponse) ProtoMessage() {} -func (*MsgSetPrecisionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_96891bdd11ac56ed, []int{11} -} -func (m *MsgSetPrecisionResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *MsgSetPrecisionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_MsgSetPrecisionResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *MsgSetPrecisionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgSetPrecisionResponse.Merge(m, src) -} -func (m *MsgSetPrecisionResponse) XXX_Size() int { - return m.Size() -} -func (m *MsgSetPrecisionResponse) XXX_DiscardUnknown() { - xxx_messageInfo_MsgSetPrecisionResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_MsgSetPrecisionResponse proto.InternalMessageInfo - func init() { proto.RegisterType((*MsgCreateClass)(nil), "regen.ecocredit.v1alpha1.MsgCreateClass") proto.RegisterType((*MsgCreateClassResponse)(nil), "regen.ecocredit.v1alpha1.MsgCreateClassResponse") @@ -994,73 +899,67 @@ func init() { proto.RegisterType((*MsgCancel)(nil), "regen.ecocredit.v1alpha1.MsgCancel") proto.RegisterType((*MsgCancel_CancelCredits)(nil), "regen.ecocredit.v1alpha1.MsgCancel.CancelCredits") proto.RegisterType((*MsgCancelResponse)(nil), "regen.ecocredit.v1alpha1.MsgCancelResponse") - proto.RegisterType((*MsgSetPrecision)(nil), "regen.ecocredit.v1alpha1.MsgSetPrecision") - proto.RegisterType((*MsgSetPrecisionResponse)(nil), "regen.ecocredit.v1alpha1.MsgSetPrecisionResponse") } func init() { proto.RegisterFile("regen/ecocredit/v1alpha1/tx.proto", fileDescriptor_96891bdd11ac56ed) } var fileDescriptor_96891bdd11ac56ed = []byte{ - // 940 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0x41, 0x73, 0xdb, 0x44, - 0x14, 0x8e, 0xec, 0xd4, 0x8e, 0x9f, 0xeb, 0xa4, 0x51, 0xc0, 0x71, 0x04, 0xd8, 0xae, 0x7a, 0x31, - 0xc3, 0x54, 0xc6, 0x61, 0x06, 0x66, 0x38, 0x81, 0x9d, 0x01, 0x3a, 0x21, 0x50, 0x44, 0x4e, 0xbd, - 0xb8, 0x6b, 0xe9, 0xa1, 0x08, 0x24, 0xad, 0x47, 0xbb, 0x81, 0xf0, 0x03, 0xb8, 0xf7, 0x17, 0x70, - 0xe7, 0xc4, 0x3f, 0xe0, 0xcc, 0xb1, 0xc3, 0x05, 0x4e, 0x86, 0x49, 0xee, 0x1c, 0xfc, 0x0b, 0x18, - 0xed, 0xae, 0x64, 0xc9, 0x9d, 0xd6, 0x9a, 0x0e, 0x5c, 0xb8, 0xd8, 0x7a, 0x6f, 0xbf, 0xf7, 0xbd, - 0xb7, 0xef, 0xdb, 0xb7, 0x12, 0xdc, 0x8d, 0xd1, 0xc3, 0x68, 0x88, 0x0e, 0x75, 0x62, 0x74, 0x7d, - 0x3e, 0xfc, 0x76, 0x44, 0x82, 0xf9, 0x05, 0x19, 0x0d, 0xf9, 0x95, 0x35, 0x8f, 0x29, 0xa7, 0x7a, - 0x47, 0x40, 0xac, 0x0c, 0x62, 0xa5, 0x10, 0xe3, 0x15, 0x8f, 0x7a, 0x54, 0x80, 0x86, 0xc9, 0x93, - 0xc4, 0x1b, 0x3d, 0x8f, 0x52, 0x2f, 0xc0, 0xa1, 0xb0, 0x66, 0x97, 0x5f, 0x0d, 0xb9, 0x1f, 0x22, - 0xe3, 0x24, 0x9c, 0x4b, 0x80, 0x39, 0x83, 0xdd, 0x33, 0xe6, 0x4d, 0x62, 0x24, 0x1c, 0x27, 0x01, - 0x61, 0x4c, 0x37, 0x60, 0xc7, 0x45, 0xe6, 0x7b, 0x11, 0xc6, 0x1d, 0xad, 0xaf, 0x0d, 0x1a, 0x76, - 0x66, 0xeb, 0x1d, 0xa8, 0xfb, 0x8c, 0x5d, 0x62, 0xcc, 0x3a, 0x95, 0x7e, 0x75, 0xd0, 0xb0, 0x53, - 0x33, 0x89, 0x0a, 0x91, 0x13, 0x97, 0x70, 0xd2, 0xa9, 0xf6, 0xb5, 0xc1, 0x6d, 0x3b, 0xb3, 0xcd, - 0x4f, 0xa0, 0x5d, 0xcc, 0x61, 0x23, 0x9b, 0xd3, 0x88, 0xa1, 0x6e, 0xc1, 0x8e, 0x93, 0x38, 0xa6, - 0xbe, 0x2b, 0x73, 0x8d, 0x0f, 0x96, 0x8b, 0xde, 0xde, 0xf7, 0x24, 0x0c, 0xde, 0x37, 0xd3, 0x15, - 0xd3, 0xae, 0x8b, 0xc7, 0x07, 0xae, 0xf9, 0xcb, 0xad, 0x5c, 0xb9, 0x63, 0xc2, 0x9d, 0x0b, 0xbd, - 0x0d, 0x35, 0x59, 0x83, 0x2a, 0x56, 0x59, 0x05, 0xea, 0xca, 0x66, 0x6a, 0xdd, 0x86, 0x9d, 0x24, - 0x92, 0x44, 0x0e, 0x76, 0xaa, 0xfd, 0xea, 0xa0, 0x79, 0xfc, 0xae, 0xf5, 0xbc, 0x66, 0x5b, 0xc5, - 0x1a, 0x2c, 0xf1, 0xfb, 0x40, 0x45, 0xdb, 0x19, 0x4f, 0xa1, 0x29, 0xdb, 0xc5, 0xa6, 0xe8, 0xe7, - 0x00, 0x8c, 0x93, 0x98, 0x4f, 0x5d, 0xc2, 0xb1, 0x73, 0xab, 0xaf, 0x0d, 0x9a, 0xc7, 0x86, 0x25, - 0xe5, 0xb2, 0x52, 0xb9, 0xac, 0xf3, 0x54, 0xae, 0xf1, 0xd1, 0x72, 0xd1, 0xdb, 0x97, 0xd5, 0xaf, - 0xe2, 0xcc, 0x27, 0x7f, 0xf6, 0x34, 0xbb, 0x21, 0x1c, 0x27, 0x84, 0xa3, 0xfe, 0x19, 0xec, 0x60, - 0xe4, 0x4a, 0xce, 0xda, 0x46, 0xce, 0xc3, 0x55, 0x47, 0xd2, 0x28, 0xc9, 0x58, 0xc7, 0xc8, 0x15, - 0x7c, 0x1f, 0xc1, 0x9d, 0x79, 0x4c, 0xbf, 0x46, 0x87, 0x4f, 0x03, 0xea, 0x10, 0xee, 0xd3, 0xa8, - 0x53, 0x17, 0xdd, 0x7c, 0x6d, 0xb9, 0xe8, 0x1d, 0xca, 0xd8, 0x75, 0x84, 0x69, 0xef, 0x29, 0xd7, - 0xa7, 0xca, 0x63, 0xfc, 0x50, 0x81, 0x56, 0xa1, 0x4b, 0xfa, 0xeb, 0xd0, 0x88, 0xd1, 0xf1, 0xe7, - 0x3e, 0x46, 0x5c, 0x49, 0xb7, 0x72, 0xe8, 0x13, 0xd8, 0xe3, 0x31, 0x71, 0xc9, 0x2c, 0xc0, 0x29, - 0x09, 0xe9, 0x65, 0xc4, 0x95, 0x88, 0xc6, 0x72, 0xd1, 0x6b, 0xcb, 0xb4, 0x6b, 0x00, 0xd3, 0xde, - 0x4d, 0x3d, 0x1f, 0x0a, 0x87, 0xfe, 0x01, 0xec, 0xc6, 0xc8, 0xfd, 0x18, 0xdd, 0x94, 0xa3, 0x2a, - 0x38, 0x92, 0x56, 0xbe, 0x2a, 0x39, 0x8a, 0xeb, 0xa6, 0xdd, 0x52, 0x0e, 0xc5, 0xf0, 0x39, 0x1c, - 0x48, 0x47, 0x88, 0x51, 0xae, 0x03, 0xdb, 0x82, 0xa6, 0xbb, 0x5c, 0xf4, 0x8c, 0x3c, 0x4d, 0x01, - 0x64, 0xda, 0xfa, 0xca, 0x9b, 0xf6, 0xc1, 0xfc, 0x22, 0x37, 0x0a, 0xa2, 0x1f, 0xd9, 0x28, 0xbc, - 0x07, 0xcd, 0x59, 0xe2, 0x98, 0xba, 0x18, 0xd1, 0x50, 0x4d, 0x43, 0x7b, 0xb9, 0xe8, 0xe9, 0x32, - 0x45, 0x6e, 0xd1, 0xb4, 0x41, 0x58, 0x27, 0xc2, 0xf8, 0xa9, 0x0a, 0xf5, 0x33, 0xe6, 0x7d, 0x89, - 0x91, 0x9b, 0x0c, 0x03, 0xc3, 0xc8, 0x5d, 0x0d, 0x83, 0xb4, 0x8a, 0xcd, 0xae, 0xac, 0x37, 0xfb, - 0x63, 0xa8, 0xcb, 0x03, 0xce, 0xd4, 0xc9, 0xbf, 0xff, 0xc2, 0x93, 0x9f, 0x64, 0xb2, 0x92, 0x9f, - 0x89, 0x0c, 0xb2, 0xd3, 0x68, 0xe3, 0xc7, 0x0a, 0x34, 0x73, 0x0b, 0x2f, 0xbd, 0xa7, 0xff, 0xad, - 0xfc, 0xfb, 0xb0, 0xa7, 0x1a, 0x98, 0xea, 0x6e, 0xfe, 0xad, 0x41, 0xe3, 0x8c, 0x79, 0xb6, 0x00, - 0x27, 0x02, 0x5e, 0xd0, 0x20, 0x27, 0xa0, 0xb4, 0xf4, 0xd3, 0x95, 0x44, 0x15, 0x21, 0xd1, 0xe8, - 0x85, 0x12, 0x49, 0x36, 0x4b, 0xfe, 0xad, 0xcb, 0x94, 0x5c, 0x4b, 0xd9, 0x5e, 0xaa, 0xf2, 0x86, - 0x4f, 0x6d, 0xe3, 0x31, 0xb4, 0x0a, 0x51, 0x2f, 0xaf, 0x61, 0x1b, 0x6a, 0x79, 0xe9, 0x6c, 0x65, - 0x99, 0x07, 0xb0, 0x9f, 0x55, 0x98, 0x75, 0xe1, 0x37, 0xd9, 0x85, 0x49, 0x72, 0x35, 0x04, 0xff, - 0x56, 0x17, 0x24, 0x9b, 0x25, 0xff, 0x9e, 0x39, 0xac, 0x8f, 0xa1, 0x55, 0x58, 0xf9, 0xaf, 0x76, - 0x2a, 0x93, 0x64, 0x3b, 0xfd, 0x59, 0x53, 0x67, 0x80, 0x3f, 0x4c, 0x26, 0x90, 0xf9, 0x34, 0x7a, - 0xee, 0x3b, 0x6c, 0xad, 0xa2, 0x4a, 0xe9, 0x8a, 0x4e, 0x41, 0x0f, 0xc9, 0xd5, 0xd4, 0x45, 0xc7, - 0x0f, 0x49, 0x30, 0x9d, 0x07, 0xc4, 0x41, 0x26, 0xb4, 0x6e, 0x8d, 0xdf, 0x58, 0x2e, 0x7a, 0x47, - 0x32, 0xfe, 0x59, 0x8c, 0x69, 0xdf, 0x09, 0xc9, 0xd5, 0x89, 0xf4, 0x3d, 0x94, 0xae, 0x23, 0x38, - 0x5c, 0x2b, 0x38, 0xdd, 0xcc, 0xf1, 0xef, 0xdb, 0x50, 0x3d, 0x63, 0x9e, 0xee, 0x43, 0x33, 0xff, - 0x09, 0x31, 0x28, 0xf1, 0xe6, 0x14, 0x48, 0xe3, 0xed, 0xb2, 0xc8, 0xec, 0x9e, 0xcc, 0x52, 0xc9, - 0xd7, 0xff, 0xa0, 0xec, 0x4b, 0xba, 0x54, 0xaa, 0xe2, 0x95, 0x7c, 0x0e, 0xdb, 0xe2, 0x56, 0xbd, - 0xbb, 0xf1, 0x3a, 0x34, 0xde, 0xdc, 0x08, 0xc9, 0x58, 0x1f, 0x41, 0x4d, 0x0d, 0xfb, 0xbd, 0x12, - 0x33, 0x6c, 0xbc, 0x55, 0x02, 0x94, 0xe7, 0x56, 0x23, 0x74, 0xaf, 0xc4, 0x64, 0x6c, 0xe0, 0x2e, - 0x1e, 0x5c, 0x3d, 0x80, 0xdb, 0x85, 0x43, 0xbb, 0x69, 0xcb, 0x2b, 0xa8, 0x31, 0x2a, 0x0d, 0x4d, - 0xb3, 0x8d, 0x4f, 0x7f, 0xbd, 0xee, 0x6a, 0x4f, 0xaf, 0xbb, 0xda, 0x5f, 0xd7, 0x5d, 0xed, 0xc9, - 0x4d, 0x77, 0xeb, 0xe9, 0x4d, 0x77, 0xeb, 0x8f, 0x9b, 0xee, 0xd6, 0xa3, 0x91, 0xe7, 0xf3, 0x8b, - 0xcb, 0x99, 0xe5, 0xd0, 0x70, 0x28, 0x68, 0xef, 0x47, 0xc8, 0xbf, 0xa3, 0xf1, 0x37, 0xca, 0x0a, - 0xd0, 0xf5, 0x30, 0x1e, 0x5e, 0xad, 0xbe, 0xa3, 0x67, 0x35, 0xf1, 0xed, 0xf3, 0xce, 0x3f, 0x01, - 0x00, 0x00, 0xff, 0xff, 0x8b, 0xb1, 0x23, 0xa6, 0x61, 0x0b, 0x00, 0x00, + // 876 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0x41, 0x6f, 0xe3, 0x44, + 0x14, 0xae, 0xe3, 0x6e, 0xd2, 0xbc, 0xd0, 0x96, 0xba, 0x90, 0x35, 0x06, 0xc5, 0x59, 0xef, 0x25, + 0x08, 0xad, 0x43, 0x8b, 0x04, 0x12, 0x27, 0x48, 0x56, 0xc0, 0x6a, 0x29, 0x08, 0xd3, 0xd3, 0x5e, + 0xb2, 0x13, 0xfb, 0xe1, 0x1a, 0x1c, 0x8f, 0xe5, 0x99, 0xc0, 0xf6, 0x8c, 0xb8, 0xef, 0x2f, 0xe0, + 0xce, 0x9f, 0xe0, 0xcc, 0x71, 0xc5, 0x89, 0x53, 0x40, 0xed, 0x89, 0x0b, 0x87, 0xfc, 0x02, 0xe4, + 0x99, 0xb1, 0x63, 0x07, 0xb1, 0x89, 0x2a, 0xb8, 0xec, 0x25, 0xc9, 0x7b, 0xf3, 0xbd, 0x6f, 0x66, + 0xbe, 0xef, 0xcd, 0x4c, 0xe0, 0x4e, 0x86, 0x21, 0x26, 0x43, 0xf4, 0xa9, 0x9f, 0x61, 0x10, 0xf1, + 0xe1, 0xb7, 0x27, 0x24, 0x4e, 0x2f, 0xc8, 0xc9, 0x90, 0x3f, 0x71, 0xd3, 0x8c, 0x72, 0x6a, 0x98, + 0x02, 0xe2, 0x96, 0x10, 0xb7, 0x80, 0x58, 0xaf, 0x84, 0x34, 0xa4, 0x02, 0x34, 0xcc, 0x7f, 0x49, + 0xbc, 0x65, 0x87, 0x94, 0x86, 0x31, 0x0e, 0x45, 0x34, 0x9d, 0x7f, 0x35, 0xe4, 0xd1, 0x0c, 0x19, + 0x27, 0xb3, 0x54, 0x02, 0x9c, 0xef, 0x35, 0x38, 0x38, 0x63, 0xe1, 0x38, 0x43, 0xc2, 0x71, 0x1c, + 0x13, 0xc6, 0x0c, 0x0b, 0xf6, 0x02, 0x64, 0x51, 0x98, 0x60, 0x66, 0x6a, 0x7d, 0x6d, 0xd0, 0xf6, + 0xca, 0xd8, 0x30, 0xa1, 0x15, 0x31, 0x36, 0xc7, 0x8c, 0x99, 0x8d, 0xbe, 0x3e, 0x68, 0x7b, 0x45, + 0x98, 0x57, 0xcd, 0x90, 0x93, 0x80, 0x70, 0x62, 0xea, 0x7d, 0x6d, 0xf0, 0x92, 0x57, 0xc6, 0x86, + 0x0d, 0x1d, 0xb9, 0xdc, 0x09, 0xbf, 0x4c, 0xd1, 0xdc, 0x15, 0xa4, 0x20, 0x53, 0xe7, 0x97, 0x29, + 0x3a, 0x9f, 0x40, 0xb7, 0xbe, 0x08, 0x0f, 0x59, 0x4a, 0x13, 0x86, 0x86, 0x0b, 0x7b, 0x7e, 0x9e, + 0x98, 0x44, 0x81, 0x5c, 0xcc, 0xe8, 0x78, 0xb9, 0xb0, 0x0f, 0x2f, 0xc9, 0x2c, 0x7e, 0xdf, 0x29, + 0x46, 0x1c, 0xaf, 0x25, 0x7e, 0x3e, 0x08, 0x9c, 0x9f, 0x6f, 0x55, 0xf6, 0x33, 0x22, 0xdc, 0xbf, + 0x30, 0xba, 0xd0, 0x94, 0x8b, 0x54, 0xbb, 0x51, 0x51, 0x8d, 0xba, 0xb1, 0x99, 0xda, 0xf0, 0x60, + 0x2f, 0xaf, 0x24, 0x89, 0x8f, 0xa6, 0xde, 0xd7, 0x07, 0x9d, 0xd3, 0x77, 0xdd, 0x7f, 0xb3, 0xc3, + 0xad, 0xaf, 0xc1, 0x15, 0x9f, 0x0f, 0x54, 0xb5, 0x57, 0xf2, 0xd4, 0x54, 0xdb, 0x5d, 0x53, 0xed, + 0x1c, 0x80, 0x71, 0x92, 0xf1, 0x49, 0x40, 0x38, 0x9a, 0xb7, 0xfa, 0xda, 0xa0, 0x73, 0x6a, 0xb9, + 0xd2, 0x50, 0xb7, 0x30, 0xd4, 0x3d, 0x2f, 0x0c, 0x1d, 0xbd, 0xb6, 0x5c, 0xd8, 0x47, 0x72, 0xf5, + 0xab, 0x3a, 0xe7, 0xe9, 0xef, 0xb6, 0xe6, 0xb5, 0x45, 0xe2, 0x3e, 0xe1, 0x68, 0x7c, 0x06, 0x7b, + 0x98, 0x04, 0x92, 0xb3, 0xb9, 0x91, 0xf3, 0xf6, 0x4a, 0x91, 0xa2, 0x4a, 0x32, 0xb6, 0x30, 0x09, + 0x04, 0xdf, 0x47, 0xf0, 0x72, 0x9a, 0xd1, 0xaf, 0xd1, 0xe7, 0x93, 0x98, 0xfa, 0x84, 0x47, 0x34, + 0x31, 0x5b, 0x42, 0xcd, 0xd7, 0x97, 0x0b, 0xfb, 0xb6, 0xac, 0x5d, 0x47, 0x38, 0xde, 0xa1, 0x4a, + 0x7d, 0xaa, 0x32, 0xd6, 0x0f, 0x0d, 0xd8, 0xaf, 0xa9, 0x64, 0xbc, 0x01, 0xed, 0x0c, 0xfd, 0x28, + 0x8d, 0x30, 0xe1, 0xca, 0xba, 0x55, 0xc2, 0x18, 0xc3, 0x21, 0xcf, 0x48, 0x40, 0xa6, 0x31, 0x4e, + 0xc8, 0x8c, 0xce, 0x13, 0xae, 0x4c, 0xb4, 0x96, 0x0b, 0xbb, 0x2b, 0xa7, 0x5d, 0x03, 0x38, 0xde, + 0x41, 0x91, 0xf9, 0x50, 0x24, 0x8c, 0x0f, 0xe0, 0x20, 0x43, 0x1e, 0x65, 0x18, 0x14, 0x1c, 0xba, + 0xe0, 0xc8, 0xa5, 0x7c, 0x55, 0x72, 0xd4, 0xc7, 0x1d, 0x6f, 0x5f, 0x25, 0x14, 0xc3, 0xe7, 0x70, + 0x2c, 0x13, 0x33, 0x4c, 0x2a, 0x0a, 0x88, 0x16, 0x1f, 0xf5, 0x96, 0x0b, 0xdb, 0xaa, 0xd2, 0xd4, + 0x40, 0x8e, 0x67, 0xac, 0xb2, 0x85, 0x0e, 0xce, 0x17, 0x95, 0xa3, 0x20, 0xf4, 0x28, 0x8f, 0xc2, + 0x7b, 0xd0, 0x99, 0xe6, 0x89, 0x49, 0x80, 0x09, 0x9d, 0xa9, 0xd3, 0xd0, 0x5d, 0x2e, 0x6c, 0x43, + 0x4e, 0x51, 0x19, 0x74, 0x3c, 0x10, 0xd1, 0x7d, 0x11, 0xfc, 0xa4, 0x43, 0xeb, 0x8c, 0x85, 0x5f, + 0x62, 0x12, 0xe4, 0x87, 0x81, 0x61, 0x12, 0xac, 0x0e, 0x83, 0x8c, 0xea, 0x62, 0x37, 0xd6, 0xc5, + 0xfe, 0x18, 0x5a, 0xb2, 0xc1, 0x99, 0xea, 0xfc, 0x7b, 0xcf, 0xed, 0xfc, 0x7c, 0x26, 0x37, 0xff, + 0x18, 0xcb, 0x22, 0xaf, 0xa8, 0xb6, 0x7e, 0x6c, 0x40, 0xa7, 0x32, 0x70, 0xe3, 0x3d, 0xbd, 0xb0, + 0xf6, 0x1f, 0xc1, 0xa1, 0x12, 0xb0, 0xf0, 0xdd, 0xf9, 0x4b, 0x83, 0xf6, 0x19, 0x0b, 0x3d, 0x01, + 0xce, 0x0d, 0xbc, 0xa0, 0x71, 0xc5, 0x40, 0x19, 0x19, 0x0f, 0x57, 0x16, 0x35, 0x84, 0x45, 0x27, + 0xcf, 0xb5, 0x48, 0xb2, 0xb9, 0xf2, 0x6b, 0xdd, 0xa6, 0xfc, 0x5a, 0x2a, 0xf7, 0xa2, 0xcb, 0x27, + 0xa0, 0x88, 0xad, 0xc7, 0xb0, 0x5f, 0xab, 0xba, 0xb9, 0x87, 0x5d, 0x68, 0x56, 0xad, 0xf3, 0x54, + 0xe4, 0x1c, 0xc3, 0x51, 0xb9, 0xc2, 0x52, 0x85, 0x5f, 0xa5, 0x0a, 0xe3, 0xfc, 0x6a, 0x88, 0xff, + 0x2b, 0x15, 0x24, 0x9b, 0x2b, 0xbf, 0xfe, 0xd1, 0xac, 0x8f, 0x61, 0xbf, 0x36, 0xf2, 0x7f, 0xed, + 0x54, 0x4e, 0x52, 0xec, 0xf4, 0xf4, 0x4f, 0x1d, 0xf4, 0x33, 0x16, 0x1a, 0x11, 0x74, 0xaa, 0xcf, + 0xf2, 0x60, 0x8b, 0xc7, 0x46, 0x20, 0xad, 0xb7, 0xb7, 0x45, 0x96, 0x57, 0x4b, 0x39, 0x95, 0x7c, + 0x31, 0x07, 0xdb, 0xbe, 0x6b, 0x5b, 0x4d, 0x55, 0xbf, 0xc5, 0xce, 0x61, 0x57, 0x5c, 0x44, 0x77, + 0x36, 0xde, 0x20, 0xd6, 0x9b, 0x1b, 0x21, 0x25, 0xeb, 0x23, 0x68, 0xaa, 0xf3, 0x71, 0x77, 0x8b, + 0xb6, 0xb7, 0xde, 0xda, 0x02, 0x54, 0xe5, 0x56, 0x5d, 0x77, 0x77, 0x8b, 0x66, 0xda, 0xc0, 0x5d, + 0xf7, 0x7a, 0xf4, 0xf0, 0x97, 0xab, 0x9e, 0xf6, 0xec, 0xaa, 0xa7, 0xfd, 0x71, 0xd5, 0xd3, 0x9e, + 0x5e, 0xf7, 0x76, 0x9e, 0x5d, 0xf7, 0x76, 0x7e, 0xbb, 0xee, 0xed, 0x3c, 0x3a, 0x09, 0x23, 0x7e, + 0x31, 0x9f, 0xba, 0x3e, 0x9d, 0x0d, 0x05, 0xe1, 0xbd, 0x04, 0xf9, 0x77, 0x34, 0xfb, 0x46, 0x45, + 0x31, 0x06, 0x21, 0x66, 0xc3, 0x27, 0xab, 0xbf, 0x8b, 0xd3, 0xa6, 0x78, 0xc0, 0xdf, 0xf9, 0x3b, + 0x00, 0x00, 0xff, 0xff, 0xdb, 0x9f, 0xa9, 0x74, 0x48, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1091,27 +990,6 @@ type MsgClient interface { // deducts them from the tradable supply, effectively cancelling their // issuance on Regen Ledger Cancel(ctx context.Context, in *MsgCancel, opts ...grpc.CallOption) (*MsgCancelResponse, error) - // SetPrecision allows an issuer to increase the decimal precision of a credit - // batch. It is an experimental feature to concretely explore an idea proposed - // in https://github.com/cosmos/cosmos-sdk/issues/7113. The number of decimal - // places allowed for a credit batch is determined by the original number of - // decimal places used with calling CreatBatch. SetPrecision allows the number - // of allowed decimal places to be increased, effectively making the supply - // more granular without actually changing any balances. It allows asset - // issuers to be able to issue an asset without needing to think about how - // many subdivisions are needed upfront. While it may not be relevant for - // credits which likely have a fairly stable market value, I wanted to - // experiment a bit and this serves as a proof of concept for a broader bank - // redesign where say for instance a coin like the ATOM or XRN could be issued - // in its own units rather than micro or nano-units. Instead an operation like - // SetPrecision would allow trading in micro, nano or pico in the future based - // on market demand. Arbitrary, unbounded precision is not desirable because - // this can lead to spam attacks (like sending - // 0.000000000000000000000000000001 coins). This is effectively fixed - // precision so under the hood it is still basically an integer, but the fixed - // precision can be increased so its more adaptable long term than just an - // integer. - SetPrecision(ctx context.Context, in *MsgSetPrecision, opts ...grpc.CallOption) (*MsgSetPrecisionResponse, error) } type msgClient struct { @@ -1167,15 +1045,6 @@ func (c *msgClient) Cancel(ctx context.Context, in *MsgCancel, opts ...grpc.Call return out, nil } -func (c *msgClient) SetPrecision(ctx context.Context, in *MsgSetPrecision, opts ...grpc.CallOption) (*MsgSetPrecisionResponse, error) { - out := new(MsgSetPrecisionResponse) - err := c.cc.Invoke(ctx, "/regen.ecocredit.v1alpha1.Msg/SetPrecision", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - // MsgServer is the server API for Msg service. type MsgServer interface { // CreateClass creates a new credit class with an approved list of issuers and @@ -1194,27 +1063,6 @@ type MsgServer interface { // deducts them from the tradable supply, effectively cancelling their // issuance on Regen Ledger Cancel(context.Context, *MsgCancel) (*MsgCancelResponse, error) - // SetPrecision allows an issuer to increase the decimal precision of a credit - // batch. It is an experimental feature to concretely explore an idea proposed - // in https://github.com/cosmos/cosmos-sdk/issues/7113. The number of decimal - // places allowed for a credit batch is determined by the original number of - // decimal places used with calling CreatBatch. SetPrecision allows the number - // of allowed decimal places to be increased, effectively making the supply - // more granular without actually changing any balances. It allows asset - // issuers to be able to issue an asset without needing to think about how - // many subdivisions are needed upfront. While it may not be relevant for - // credits which likely have a fairly stable market value, I wanted to - // experiment a bit and this serves as a proof of concept for a broader bank - // redesign where say for instance a coin like the ATOM or XRN could be issued - // in its own units rather than micro or nano-units. Instead an operation like - // SetPrecision would allow trading in micro, nano or pico in the future based - // on market demand. Arbitrary, unbounded precision is not desirable because - // this can lead to spam attacks (like sending - // 0.000000000000000000000000000001 coins). This is effectively fixed - // precision so under the hood it is still basically an integer, but the fixed - // precision can be increased so its more adaptable long term than just an - // integer. - SetPrecision(context.Context, *MsgSetPrecision) (*MsgSetPrecisionResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -1236,9 +1084,6 @@ func (*UnimplementedMsgServer) Retire(ctx context.Context, req *MsgRetire) (*Msg func (*UnimplementedMsgServer) Cancel(ctx context.Context, req *MsgCancel) (*MsgCancelResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Cancel not implemented") } -func (*UnimplementedMsgServer) SetPrecision(ctx context.Context, req *MsgSetPrecision) (*MsgSetPrecisionResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SetPrecision not implemented") -} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -1334,24 +1179,6 @@ func _Msg_Cancel_Handler(srv interface{}, ctx context.Context, dec func(interfac return interceptor(ctx, in, info, handler) } -func _Msg_SetPrecision_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgSetPrecision) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).SetPrecision(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/regen.ecocredit.v1alpha1.Msg/SetPrecision", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).SetPrecision(ctx, req.(*MsgSetPrecision)) - } - return interceptor(ctx, in, info, handler) -} - var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "regen.ecocredit.v1alpha1.Msg", HandlerType: (*MsgServer)(nil), @@ -1376,10 +1203,6 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "Cancel", Handler: _Msg_Cancel_Handler, }, - { - MethodName: "SetPrecision", - Handler: _Msg_SetPrecision_Handler, - }, }, Streams: []grpc.StreamDesc{}, Metadata: "regen/ecocredit/v1alpha1/tx.proto", @@ -1405,6 +1228,13 @@ func (m *MsgCreateClass) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CreditType) > 0 { + i -= len(m.CreditType) + copy(dAtA[i:], m.CreditType) + i = encodeVarintTx(dAtA, i, uint64(len(m.CreditType))) + i-- + dAtA[i] = 0x22 + } if len(m.Metadata) > 0 { i -= len(m.Metadata) copy(dAtA[i:], m.Metadata) @@ -1967,71 +1797,6 @@ func (m *MsgCancelResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *MsgSetPrecision) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MsgSetPrecision) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MsgSetPrecision) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.MaxDecimalPlaces != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.MaxDecimalPlaces)) - i-- - dAtA[i] = 0x18 - } - if len(m.BatchDenom) > 0 { - i -= len(m.BatchDenom) - copy(dAtA[i:], m.BatchDenom) - i = encodeVarintTx(dAtA, i, uint64(len(m.BatchDenom))) - i-- - dAtA[i] = 0x12 - } - if len(m.Issuer) > 0 { - i -= len(m.Issuer) - copy(dAtA[i:], m.Issuer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Issuer))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *MsgSetPrecisionResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *MsgSetPrecisionResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MsgSetPrecisionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -2063,6 +1828,10 @@ func (m *MsgCreateClass) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.CreditType) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -2307,35 +2076,6 @@ func (m *MsgCancelResponse) Size() (n int) { return n } -func (m *MsgSetPrecision) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Issuer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.BatchDenom) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - if m.MaxDecimalPlaces != 0 { - n += 1 + sovTx(uint64(m.MaxDecimalPlaces)) - } - return n -} - -func (m *MsgSetPrecisionResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2469,6 +2209,38 @@ func (m *MsgCreateClass) Unmarshal(dAtA []byte) error { m.Metadata = []byte{} } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreditType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CreditType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -4128,195 +3900,6 @@ func (m *MsgCancelResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSetPrecision) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MsgSetPrecision: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSetPrecision: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Issuer", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Issuer = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BatchDenom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BatchDenom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxDecimalPlaces", wireType) - } - m.MaxDecimalPlaces = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MaxDecimalPlaces |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipTx(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MsgSetPrecisionResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MsgSetPrecisionResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSetPrecisionResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipTx(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ecocredit/types.go b/x/ecocredit/types.go index 2ebe9921c3..9390102f11 100644 --- a/x/ecocredit/types.go +++ b/x/ecocredit/types.go @@ -1,7 +1,10 @@ package ecocredit import ( + "strings" + "github.com/regen-network/regen-ledger/orm" + "github.com/regen-network/regen-ledger/x/ecocredit/util" ) var _, _ orm.PrimaryKeyed = &ClassInfo{}, &BatchInfo{} @@ -19,3 +22,8 @@ func DefaultGenesisState() *GenesisState { Params: DefaultParams(), } } + +// Normalize credit type name by removing whitespace and converting to lowercase +func NormalizeCreditTypeName(name string) string { + return util.FastRemoveWhitespace(strings.ToLower(name)) +} diff --git a/x/ecocredit/types.pb.go b/x/ecocredit/types.pb.go index dd57d4187a..78d9d2a633 100644 --- a/x/ecocredit/types.pb.go +++ b/x/ecocredit/types.pb.go @@ -39,6 +39,8 @@ type ClassInfo struct { Issuers []string `protobuf:"bytes,3,rep,name=issuers,proto3" json:"issuers,omitempty"` // metadata is any arbitrary metadata to attached to the credit class. Metadata []byte `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` + // credit_type describes the type of credit (e.g. carbon, biodiversity), as well as unit and precision. + CreditType *CreditType `protobuf:"bytes,5,opt,name=credit_type,json=creditType,proto3" json:"credit_type,omitempty"` } func (m *ClassInfo) Reset() { *m = ClassInfo{} } @@ -102,6 +104,13 @@ func (m *ClassInfo) GetMetadata() []byte { return nil } +func (m *ClassInfo) GetCreditType() *CreditType { + if m != nil { + return m.CreditType + } + return nil +} + // BatchInfo represents the high-level on-chain information for a credit batch. type BatchInfo struct { // class_id is the unique ID of credit class. @@ -241,6 +250,8 @@ type Params struct { // allowlist_enabled is a param that enables/disables the allowlist for credit // creation AllowlistEnabled bool `protobuf:"varint,3,opt,name=allowlist_enabled,json=allowlistEnabled,proto3" json:"allowlist_enabled,omitempty"` + // credit_types is a list of definitions for credit types + CreditTypes []*CreditType `protobuf:"bytes,4,rep,name=credit_types,json=creditTypes,proto3" json:"credit_types,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -297,6 +308,13 @@ func (m *Params) GetAllowlistEnabled() bool { return false } +func (m *Params) GetCreditTypes() []*CreditType { + if m != nil { + return m.CreditTypes + } + return nil +} + // GenesisState defines the state of the ecocredit module that is needed at genesis type GenesisState struct { // Params contains the updateable global parameters for use with the x/params module @@ -343,11 +361,87 @@ func (m *GenesisState) GetParams() Params { return Params{} } +// CreditType defines the measurement unit/precision of a certain credit type +// (e.g. carbon, biodiversity...) +type CreditType struct { + // the type of credit (e.g. carbon, biodiversity, etc) + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // abbreviation is a 1-3 character uppercase abbreviation of the CreditType + // name, used in batch denominations within the CreditType. It must be unique. + Abbreviation string `protobuf:"bytes,2,opt,name=abbreviation,proto3" json:"abbreviation,omitempty"` + // the measurement unit (e.g. kg, ton, etc) + Unit string `protobuf:"bytes,3,opt,name=unit,proto3" json:"unit,omitempty"` + // the decimal precision + Precision uint32 `protobuf:"varint,4,opt,name=precision,proto3" json:"precision,omitempty"` +} + +func (m *CreditType) Reset() { *m = CreditType{} } +func (m *CreditType) String() string { return proto.CompactTextString(m) } +func (*CreditType) ProtoMessage() {} +func (*CreditType) Descriptor() ([]byte, []int) { + return fileDescriptor_5342f4dcaeff1a84, []int{4} +} +func (m *CreditType) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CreditType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CreditType.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CreditType) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreditType.Merge(m, src) +} +func (m *CreditType) XXX_Size() int { + return m.Size() +} +func (m *CreditType) XXX_DiscardUnknown() { + xxx_messageInfo_CreditType.DiscardUnknown(m) +} + +var xxx_messageInfo_CreditType proto.InternalMessageInfo + +func (m *CreditType) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *CreditType) GetAbbreviation() string { + if m != nil { + return m.Abbreviation + } + return "" +} + +func (m *CreditType) GetUnit() string { + if m != nil { + return m.Unit + } + return "" +} + +func (m *CreditType) GetPrecision() uint32 { + if m != nil { + return m.Precision + } + return 0 +} + func init() { proto.RegisterType((*ClassInfo)(nil), "regen.ecocredit.v1alpha1.ClassInfo") proto.RegisterType((*BatchInfo)(nil), "regen.ecocredit.v1alpha1.BatchInfo") proto.RegisterType((*Params)(nil), "regen.ecocredit.v1alpha1.Params") proto.RegisterType((*GenesisState)(nil), "regen.ecocredit.v1alpha1.GenesisState") + proto.RegisterType((*CreditType)(nil), "regen.ecocredit.v1alpha1.CreditType") } func init() { @@ -355,51 +449,57 @@ func init() { } var fileDescriptor_5342f4dcaeff1a84 = []byte{ - // 692 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xcd, 0x4e, 0xdb, 0x4a, - 0x14, 0x8e, 0x09, 0x37, 0x3f, 0x13, 0xee, 0x25, 0x98, 0x0b, 0x31, 0xb9, 0x52, 0x1c, 0x59, 0x77, - 0x11, 0xa9, 0x62, 0xdc, 0x50, 0xa9, 0x95, 0xd8, 0xd5, 0x50, 0x2a, 0xd4, 0xaa, 0xad, 0x5c, 0x56, - 0xdd, 0x58, 0x63, 0xfb, 0x60, 0x5c, 0xec, 0x99, 0xc8, 0x33, 0x81, 0xf2, 0x10, 0x95, 0x58, 0xf7, - 0x11, 0xfa, 0x24, 0x2c, 0x59, 0x76, 0x65, 0x2a, 0xe8, 0x13, 0xe4, 0x09, 0x2a, 0xcf, 0xd8, 0xe1, - 0x47, 0xaa, 0x2a, 0x75, 0xe5, 0xf9, 0xce, 0x39, 0xdf, 0x37, 0x73, 0xfe, 0x8c, 0xfe, 0xcf, 0x20, - 0x02, 0x6a, 0x43, 0xc0, 0x82, 0x0c, 0xc2, 0x58, 0xd8, 0x27, 0x63, 0x92, 0x4c, 0x8e, 0xc8, 0xd8, - 0x16, 0x67, 0x13, 0xe0, 0x78, 0x92, 0x31, 0xc1, 0x74, 0x43, 0x46, 0xe1, 0x79, 0x14, 0xae, 0xa2, - 0xfa, 0x83, 0x80, 0xf1, 0x94, 0x71, 0xdb, 0x27, 0x1c, 0xec, 0x93, 0xb1, 0x0f, 0x82, 0x8c, 0xed, - 0x80, 0xc5, 0x54, 0x31, 0xfb, 0xff, 0x46, 0x2c, 0x62, 0xf2, 0x68, 0x17, 0xa7, 0xd2, 0x6a, 0x46, - 0x8c, 0x45, 0x09, 0xd8, 0x12, 0xf9, 0xd3, 0x43, 0x5b, 0xc4, 0x29, 0x70, 0x41, 0xd2, 0x89, 0x0a, - 0xb0, 0x3e, 0x6b, 0xa8, 0xbd, 0x93, 0x10, 0xce, 0xf7, 0xe9, 0x21, 0xd3, 0x31, 0x6a, 0x05, 0x05, - 0xf0, 0xe2, 0xd0, 0xd0, 0x86, 0xda, 0xa8, 0xed, 0xac, 0xce, 0x72, 0x73, 0xf9, 0x8c, 0xa4, 0xc9, - 0xb6, 0x55, 0x79, 0x2c, 0xb7, 0x29, 0x8f, 0xfb, 0xa1, 0xde, 0x47, 0xad, 0x10, 0x78, 0x1c, 0x51, - 0xc8, 0x8c, 0x85, 0x22, 0xde, 0x9d, 0x63, 0xdd, 0x40, 0xcd, 0x98, 0xf3, 0x29, 0x64, 0xdc, 0xa8, - 0x0f, 0xeb, 0xa3, 0xb6, 0x5b, 0xc1, 0x82, 0x95, 0x82, 0x20, 0x21, 0x11, 0xc4, 0x58, 0x1c, 0x6a, - 0xa3, 0x25, 0x77, 0x8e, 0xad, 0x2f, 0x8b, 0xa8, 0xed, 0x10, 0x11, 0x1c, 0xfd, 0xd1, 0x7b, 0x9e, - 0xa1, 0x8e, 0x5f, 0x90, 0xbd, 0x10, 0x28, 0x4b, 0xd5, 0x93, 0x9c, 0xf5, 0x59, 0x6e, 0xea, 0x8a, - 0x72, 0xc7, 0x69, 0xb9, 0x48, 0xa2, 0xdd, 0x02, 0xe8, 0xeb, 0xa8, 0xa1, 0x5e, 0x67, 0xd4, 0x65, - 0x1a, 0x25, 0xd2, 0xb7, 0xd1, 0x92, 0x60, 0x82, 0x24, 0x1e, 0x49, 0xd9, 0x94, 0x0a, 0xf9, 0xdc, - 0xb6, 0xd3, 0x9b, 0xe5, 0xe6, 0xaa, 0x52, 0xbc, 0xeb, 0xb5, 0xdc, 0x8e, 0x84, 0xcf, 0x25, 0xba, - 0x97, 0xe6, 0x5f, 0xf7, 0xd3, 0xd4, 0xf7, 0x50, 0x57, 0x71, 0xbc, 0x80, 0xd0, 0x00, 0x92, 0x04, - 0x42, 0xa3, 0x21, 0xb5, 0xff, 0x9b, 0xe5, 0x66, 0x4f, 0x69, 0x3f, 0x8c, 0xb0, 0xdc, 0x65, 0x65, - 0xda, 0xa9, 0x2c, 0xfa, 0x01, 0x42, 0x5c, 0x90, 0x4c, 0x78, 0x21, 0x11, 0x60, 0x34, 0x87, 0xda, - 0xa8, 0xb3, 0xd5, 0xc7, 0xaa, 0xe9, 0xb8, 0x6a, 0x3a, 0x3e, 0xa8, 0x9a, 0xee, 0x6c, 0xcc, 0x72, - 0x73, 0x45, 0xa9, 0xdf, 0xf2, 0xac, 0xf3, 0x2b, 0x53, 0x73, 0xdb, 0xd2, 0xb0, 0x4b, 0x04, 0xe8, - 0x6f, 0x50, 0x0b, 0x68, 0xa8, 0x34, 0x5b, 0xbf, 0xd5, 0xec, 0xdd, 0xb6, 0xa4, 0x62, 0x29, 0xc5, - 0x26, 0xd0, 0x50, 0xea, 0xed, 0xa1, 0xee, 0x24, 0x63, 0x1f, 0x21, 0x10, 0x5e, 0xc2, 0x02, 0x22, - 0x62, 0x46, 0x8d, 0xf6, 0xc3, 0x6c, 0x1f, 0x46, 0x58, 0xee, 0x72, 0x69, 0x7a, 0x5d, 0x59, 0x7e, - 0x68, 0xa8, 0xf1, 0x8e, 0x64, 0x24, 0xe5, 0xfa, 0x14, 0x75, 0xd5, 0x86, 0x78, 0x6a, 0x0c, 0x0e, - 0x01, 0x0c, 0x6d, 0x58, 0x1f, 0x75, 0xb6, 0x36, 0xb0, 0xda, 0x14, 0x5c, 0x6c, 0x0a, 0x2e, 0x37, - 0x05, 0xef, 0xb0, 0x98, 0x3a, 0x8f, 0x2f, 0x72, 0xb3, 0xf6, 0xf5, 0xca, 0x1c, 0x45, 0xb1, 0x38, - 0x9a, 0xfa, 0x38, 0x60, 0xa9, 0x5d, 0xae, 0x95, 0xfa, 0x6c, 0xf2, 0xf0, 0xb8, 0xdc, 0xc7, 0x82, - 0xc0, 0xdd, 0x7f, 0xd4, 0x25, 0x72, 0x43, 0xf6, 0x00, 0xf4, 0xa7, 0xa8, 0x47, 0x92, 0x84, 0x9d, - 0x42, 0x58, 0xde, 0x5b, 0x8d, 0x3b, 0x37, 0x16, 0xe4, 0x90, 0xaf, 0x95, 0x6e, 0xc9, 0xd8, 0xad, - 0x9c, 0xfa, 0x23, 0xb4, 0x22, 0x1d, 0x49, 0xcc, 0x85, 0x07, 0x94, 0xf8, 0x45, 0xc3, 0x8b, 0x51, - 0x6b, 0xb9, 0xdd, 0xb9, 0xe3, 0x85, 0xb2, 0x5b, 0x1e, 0x5a, 0x7a, 0x09, 0x14, 0x78, 0xcc, 0xdf, - 0x8b, 0xa2, 0x7c, 0x6f, 0x51, 0x63, 0x22, 0xb3, 0x96, 0x3b, 0xd0, 0xd9, 0x1a, 0xe2, 0x5f, 0xfd, - 0x25, 0xb0, 0xaa, 0x8e, 0xb3, 0x56, 0x24, 0x3a, 0xcb, 0xcd, 0xbf, 0xcb, 0xd2, 0x4a, 0xab, 0xe5, - 0x96, 0x32, 0xce, 0xab, 0x8b, 0xeb, 0x81, 0x76, 0x79, 0x3d, 0xd0, 0xbe, 0x5f, 0x0f, 0xb4, 0xf3, - 0x9b, 0x41, 0xed, 0xf2, 0x66, 0x50, 0xfb, 0x76, 0x33, 0xa8, 0x7d, 0x18, 0xdf, 0xa9, 0x8c, 0xbc, - 0x64, 0x93, 0x82, 0x38, 0x65, 0xd9, 0x71, 0x89, 0x12, 0x08, 0x23, 0xc8, 0xec, 0x4f, 0xb7, 0xff, - 0x31, 0xbf, 0x21, 0x47, 0xe2, 0xc9, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4e, 0x21, 0xaf, 0x80, - 0xe1, 0x04, 0x00, 0x00, + // 788 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0x4f, 0x8f, 0xdb, 0x44, + 0x14, 0x5f, 0x6f, 0xd2, 0x24, 0x9e, 0xa4, 0x6c, 0x3a, 0xa5, 0x8d, 0x1b, 0x50, 0x1c, 0x59, 0x3d, + 0x44, 0x42, 0xb5, 0xc9, 0x22, 0x81, 0xd4, 0x1b, 0xce, 0x76, 0xab, 0x0a, 0x04, 0xc8, 0xec, 0x89, + 0x8b, 0x35, 0xb6, 0xdf, 0x7a, 0x4d, 0xed, 0x19, 0xcb, 0x33, 0x49, 0xd9, 0x6f, 0xd1, 0x33, 0x1f, + 0x01, 0x89, 0xef, 0xd1, 0x63, 0x0f, 0x1c, 0x38, 0xa5, 0x68, 0xf7, 0x1b, 0xe4, 0x13, 0xa0, 0x99, + 0xb1, 0x93, 0x34, 0x52, 0x05, 0xea, 0xc9, 0xef, 0xf7, 0xde, 0xfb, 0xbd, 0xd1, 0xfb, 0xf3, 0x33, + 0x7a, 0x5c, 0x41, 0x0a, 0xd4, 0x83, 0x98, 0xc5, 0x15, 0x24, 0x99, 0xf0, 0x56, 0x73, 0x92, 0x97, + 0x57, 0x64, 0xee, 0x89, 0xeb, 0x12, 0xb8, 0x5b, 0x56, 0x4c, 0x30, 0x6c, 0xa9, 0x2c, 0x77, 0x9b, + 0xe5, 0x36, 0x59, 0xe3, 0x49, 0xcc, 0x78, 0xc1, 0xb8, 0x17, 0x11, 0x0e, 0xde, 0x6a, 0x1e, 0x81, + 0x20, 0x73, 0x2f, 0x66, 0x19, 0xd5, 0xcc, 0xf1, 0xa7, 0x29, 0x4b, 0x99, 0x32, 0x3d, 0x69, 0xd5, + 0x5e, 0x3b, 0x65, 0x2c, 0xcd, 0xc1, 0x53, 0x28, 0x5a, 0x5e, 0x7a, 0x22, 0x2b, 0x80, 0x0b, 0x52, + 0x94, 0x3a, 0xc1, 0xf9, 0xcb, 0x40, 0xe6, 0x22, 0x27, 0x9c, 0xbf, 0xa0, 0x97, 0x0c, 0xbb, 0xa8, + 0x17, 0x4b, 0x10, 0x66, 0x89, 0x65, 0x4c, 0x8d, 0x99, 0xe9, 0xdf, 0xdf, 0xac, 0xed, 0x93, 0x6b, + 0x52, 0xe4, 0x4f, 0x9d, 0x26, 0xe2, 0x04, 0x5d, 0x65, 0xbe, 0x48, 0xf0, 0x18, 0xf5, 0x12, 0xe0, + 0x59, 0x4a, 0xa1, 0xb2, 0x8e, 0x65, 0x7e, 0xb0, 0xc5, 0xd8, 0x42, 0xdd, 0x8c, 0xf3, 0x25, 0x54, + 0xdc, 0x6a, 0x4d, 0x5b, 0x33, 0x33, 0x68, 0xa0, 0x64, 0x15, 0x20, 0x48, 0x42, 0x04, 0xb1, 0xda, + 0x53, 0x63, 0x36, 0x08, 0xb6, 0x18, 0x3f, 0x43, 0x7d, 0xdd, 0x79, 0x28, 0xc7, 0x62, 0xdd, 0x99, + 0x1a, 0xb3, 0xfe, 0xe9, 0x63, 0xf7, 0x43, 0x63, 0x71, 0x17, 0x0a, 0x5f, 0x5c, 0x97, 0x10, 0xa0, + 0x78, 0x6b, 0x3b, 0xbf, 0xb7, 0x91, 0xe9, 0x13, 0x11, 0x5f, 0x7d, 0x54, 0x5b, 0xdf, 0xa0, 0x7e, + 0x24, 0xc9, 0x61, 0x02, 0x94, 0x15, 0xba, 0x33, 0xff, 0xe1, 0x66, 0x6d, 0x63, 0x4d, 0xd9, 0x0b, + 0x3a, 0x01, 0x52, 0xe8, 0x4c, 0x02, 0xfc, 0x10, 0x75, 0x74, 0x93, 0x56, 0x4b, 0x4d, 0xa3, 0x46, + 0xf8, 0x29, 0x1a, 0x08, 0x26, 0x48, 0x1e, 0x92, 0x82, 0x2d, 0xa9, 0x50, 0x5d, 0x9b, 0xfe, 0x68, + 0xb3, 0xb6, 0xef, 0xeb, 0x8a, 0xfb, 0x51, 0x27, 0xe8, 0x2b, 0xf8, 0xad, 0x42, 0xef, 0x4d, 0xeb, + 0xce, 0xc1, 0xb4, 0xce, 0xd1, 0x50, 0x73, 0xc2, 0x98, 0xd0, 0x18, 0xf2, 0x1c, 0x12, 0xab, 0xa3, + 0x6a, 0x7f, 0xb6, 0x59, 0xdb, 0x23, 0x5d, 0xfb, 0x30, 0xc3, 0x09, 0x4e, 0xb4, 0x6b, 0xd1, 0x78, + 0xf0, 0x05, 0x42, 0x5c, 0x90, 0x4a, 0x84, 0x09, 0x11, 0x60, 0x75, 0xd5, 0xd0, 0xc7, 0xae, 0xbe, + 0x1d, 0xb7, 0xb9, 0x1d, 0xf7, 0xa2, 0xb9, 0x1d, 0xff, 0xd1, 0x66, 0x6d, 0xdf, 0xd3, 0xd5, 0x77, + 0x3c, 0xe7, 0xf5, 0x3b, 0xdb, 0x08, 0x4c, 0xe5, 0x38, 0x23, 0x02, 0xf0, 0x0f, 0xa8, 0x07, 0x34, + 0xd1, 0x35, 0x7b, 0xff, 0x59, 0x73, 0xb4, 0x5b, 0x49, 0xc3, 0xd2, 0x15, 0xbb, 0x40, 0x13, 0x55, + 0xef, 0x1c, 0x0d, 0xcb, 0x8a, 0xfd, 0x0a, 0xb1, 0x08, 0x73, 0x16, 0x13, 0x91, 0x31, 0x6a, 0x99, + 0x87, 0xdd, 0x1e, 0x66, 0x38, 0xc1, 0x49, 0xed, 0xfa, 0xbe, 0xf1, 0xfc, 0x79, 0x8c, 0x3a, 0x3f, + 0x91, 0x8a, 0x14, 0x1c, 0x2f, 0xd1, 0xb0, 0x3e, 0x37, 0x7d, 0x06, 0x97, 0x00, 0x96, 0x31, 0x6d, + 0xcd, 0xfa, 0xa7, 0x8f, 0x5c, 0x2d, 0x38, 0x57, 0x0a, 0xce, 0xad, 0x05, 0xe7, 0x2e, 0x58, 0x46, + 0xfd, 0x2f, 0xdf, 0xac, 0xed, 0xa3, 0x3f, 0xde, 0xd9, 0xb3, 0x34, 0x13, 0x57, 0xcb, 0xc8, 0x8d, + 0x59, 0xe1, 0xd5, 0xea, 0xd4, 0x9f, 0x27, 0x3c, 0x79, 0x59, 0xcb, 0x5a, 0x12, 0x78, 0xf0, 0x89, + 0x7e, 0x44, 0x09, 0xed, 0x1c, 0x00, 0x7f, 0x8d, 0x46, 0x24, 0xcf, 0xd9, 0x2b, 0x48, 0xea, 0x77, + 0x1b, 0xd5, 0x70, 0xeb, 0x58, 0x69, 0xe5, 0x41, 0x1d, 0x56, 0x8c, 0xb3, 0x26, 0x88, 0xbf, 0x40, + 0xf7, 0x54, 0x20, 0xcf, 0xb8, 0x08, 0x81, 0x92, 0x48, 0x2e, 0x5c, 0x9e, 0x5a, 0x2f, 0x18, 0x6e, + 0x03, 0xcf, 0xb4, 0x1f, 0x3f, 0x47, 0x83, 0x3d, 0x29, 0x71, 0xab, 0xad, 0xfa, 0xfa, 0x7f, 0x5a, + 0xea, 0xef, 0xb4, 0xc4, 0x9d, 0x10, 0x0d, 0x9e, 0x03, 0x05, 0x9e, 0xf1, 0x9f, 0x85, 0xdc, 0xc3, + 0x8f, 0xa8, 0x53, 0xaa, 0xf1, 0x29, 0x31, 0xf5, 0x4f, 0xa7, 0x1f, 0x2e, 0xa9, 0xc7, 0xec, 0x3f, + 0x90, 0x13, 0xdb, 0xac, 0xed, 0xbb, 0xf5, 0x8e, 0x94, 0xd7, 0x09, 0xea, 0x32, 0xce, 0x0a, 0xa1, + 0xdd, 0xdb, 0x18, 0xa3, 0x36, 0x25, 0x05, 0x68, 0xa5, 0x06, 0xca, 0xc6, 0x0e, 0x1a, 0x90, 0x28, + 0xaa, 0x60, 0x95, 0xe9, 0xb5, 0xeb, 0x9f, 0xcd, 0x7b, 0x3e, 0xc9, 0x5b, 0xd2, 0x4c, 0xd4, 0xd2, + 0x53, 0x36, 0xfe, 0x1c, 0x99, 0x65, 0x05, 0x71, 0xc6, 0x25, 0x49, 0xaa, 0xee, 0x6e, 0xb0, 0x73, + 0xf8, 0xdf, 0xbd, 0xb9, 0x99, 0x18, 0x6f, 0x6f, 0x26, 0xc6, 0x3f, 0x37, 0x13, 0xe3, 0xf5, 0xed, + 0xe4, 0xe8, 0xed, 0xed, 0xe4, 0xe8, 0xef, 0xdb, 0xc9, 0xd1, 0x2f, 0xf3, 0xbd, 0xd5, 0xaa, 0xe6, + 0x9e, 0x50, 0x10, 0xaf, 0x58, 0xf5, 0xb2, 0x46, 0x39, 0x24, 0x29, 0x54, 0xde, 0x6f, 0xbb, 0xff, + 0x79, 0xd4, 0x51, 0x37, 0xfd, 0xd5, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x92, 0xac, 0xe2, + 0xe9, 0x05, 0x00, 0x00, } func (m *ClassInfo) Marshal() (dAtA []byte, err error) { @@ -422,6 +522,18 @@ func (m *ClassInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.CreditType != nil { + { + size, err := m.CreditType.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } if len(m.Metadata) > 0 { i -= len(m.Metadata) copy(dAtA[i:], m.Metadata) @@ -483,22 +595,22 @@ func (m *BatchInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x4a } if m.EndDate != nil { - n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.EndDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.EndDate):]) - if err1 != nil { - return 0, err1 + n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.EndDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.EndDate):]) + if err2 != nil { + return 0, err2 } - i -= n1 - i = encodeVarintTypes(dAtA, i, uint64(n1)) + i -= n2 + i = encodeVarintTypes(dAtA, i, uint64(n2)) i-- dAtA[i] = 0x42 } if m.StartDate != nil { - n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.StartDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.StartDate):]) - if err2 != nil { - return 0, err2 + n3, err3 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.StartDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.StartDate):]) + if err3 != nil { + return 0, err3 } - i -= n2 - i = encodeVarintTypes(dAtA, i, uint64(n2)) + i -= n3 + i = encodeVarintTypes(dAtA, i, uint64(n3)) i-- dAtA[i] = 0x3a } @@ -567,6 +679,20 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CreditTypes) > 0 { + for iNdEx := len(m.CreditTypes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.CreditTypes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } if m.AllowlistEnabled { i-- if m.AllowlistEnabled { @@ -636,6 +762,55 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *CreditType) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CreditType) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CreditType) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Precision != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Precision)) + i-- + dAtA[i] = 0x20 + } + if len(m.Unit) > 0 { + i -= len(m.Unit) + copy(dAtA[i:], m.Unit) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Unit))) + i-- + dAtA[i] = 0x1a + } + if len(m.Abbreviation) > 0 { + i -= len(m.Abbreviation) + copy(dAtA[i:], m.Abbreviation) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Abbreviation))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { offset -= sovTypes(v) base := offset @@ -671,6 +846,10 @@ func (m *ClassInfo) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + if m.CreditType != nil { + l = m.CreditType.Size() + n += 1 + l + sovTypes(uint64(l)) + } return n } @@ -740,6 +919,12 @@ func (m *Params) Size() (n int) { if m.AllowlistEnabled { n += 2 } + if len(m.CreditTypes) > 0 { + for _, e := range m.CreditTypes { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } return n } @@ -754,6 +939,30 @@ func (m *GenesisState) Size() (n int) { return n } +func (m *CreditType) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Abbreviation) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Unit) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Precision != 0 { + n += 1 + sovTypes(uint64(m.Precision)) + } + return n +} + func sovTypes(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -919,6 +1128,42 @@ func (m *ClassInfo) Unmarshal(dAtA []byte) error { m.Metadata = []byte{} } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreditType", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CreditType == nil { + m.CreditType = &CreditType{} + } + if err := m.CreditType.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -1409,6 +1654,40 @@ func (m *Params) Unmarshal(dAtA []byte) error { } } m.AllowlistEnabled = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreditTypes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CreditTypes = append(m.CreditTypes, &CreditType{}) + if err := m.CreditTypes[len(m.CreditTypes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -1519,6 +1798,174 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } return nil } +func (m *CreditType) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CreditType: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CreditType: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Abbreviation", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Abbreviation = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Unit", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Unit = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Precision", wireType) + } + m.Precision = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Precision |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTypes(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ecocredit/util/utils.go b/x/ecocredit/util/utils.go index d3937e3864..a2298f83dd 100644 --- a/x/ecocredit/util/utils.go +++ b/x/ecocredit/util/utils.go @@ -3,6 +3,8 @@ package util import ( "encoding/binary" "fmt" + "strings" + "unicode" "github.com/btcsuite/btcutil/base58" "github.com/enigmampc/btcutil/bech32" @@ -38,3 +40,14 @@ func Uint64ToBase58Check(x uint64) string { n := binary.PutUvarint(buf, x) return base58.CheckEncode(buf[:n], 0) } + +func FastRemoveWhitespace(str string) string { + var b strings.Builder + b.Grow(len(str)) + for _, ch := range str { + if !unicode.IsSpace(ch) { + b.WriteRune(ch) + } + } + return b.String() +} diff --git a/x/group/server/testsuite/suite.go b/x/group/server/testsuite/suite.go index df4a917015..c8177ed140 100644 --- a/x/group/server/testsuite/suite.go +++ b/x/group/server/testsuite/suite.go @@ -1874,8 +1874,9 @@ func (s *IntegrationTestSuite) TestExecProposal() { "proposal with ADR 033 executed when accepted": { setupProposal: func(ctx context.Context) uint64 { msgs := []sdk.Msg{&ecocredit.MsgCreateClass{ - Designer: s.groupAccountAddr.String(), - Issuers: []string{s.groupAccountAddr.String()}, + Designer: s.groupAccountAddr.String(), + Issuers: []string{s.groupAccountAddr.String()}, + CreditType: "carbon", }, } return createProposalAndVote(ctx, s, msgs, proposers, group.Choice_CHOICE_YES)