Skip to content

Commit

Permalink
Switch to regex for location validation and update command line
Browse files Browse the repository at this point in the history
  • Loading branch information
ruhatch committed Jun 29, 2021
1 parent f078aa5 commit 8a03ae6
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 103 deletions.
26 changes: 17 additions & 9 deletions x/ecocredit/client/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ Parameters:
class_id: credit class
metadata: base64 encoded issuance metadata
issuance: YAML encode issuance list. Note: numerical values must be written in strings.
eg: '[{recipient: "xrn:sdgkjhs2345u79ghisodg", tradable_units: "10", retired_units: "2"}]'
Note: "tradable_units" and "retired_units" default to 0.`,
eg: '[{recipient: "xrn:sdgkjhs2345u79ghisodg", tradable_units: "10", retired_units: "2", retirement_location: "YY-ZZ 12345"}]'
Note: "tradable_units" and "retired_units" default to 0.
Note: "retirement_location" is only required when "retired_units" is positive.`,
Args: cobra.ExactArgs(4),
RunE: func(cmd *cobra.Command, args []string) error {
b, err := base64.StdEncoding.DecodeString(args[2])
Expand Down Expand Up @@ -124,7 +125,8 @@ func txSend() *cobra.Command {
Parameters:
recipient: recipient address
credits: YAML encoded credit list. Note: numerical values must be written in strings.
eg: '[{batch_denom: "100/2", tradable_units: "5", retired_units: "0"}]'`,
eg: '[{batch_denom: "100/2", tradable_units: "5", retired_units: "0", retirement_location: "YY-ZZ 12345"}]'
Note: "retirement_location" is only required when "retired_units" is positive.`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
var credits = []*ecocredit.MsgSendRequest_SendUnits{}
Expand All @@ -146,14 +148,19 @@ Parameters:

func txRetire() *cobra.Command {
return &cobra.Command{
Use: "retire [credits]",
Use: "retire [credits] [retirement_location]",
Short: "Retires a specified amounts of credits from the account of the transaction author (--from)",
Long: `Retires a specified amounts of credits from the account of the transaction author (--from)
Parameters:
credits: YAML encoded credit list. Note: numerical values must be written in strings.
eg: '[{batch_denom: "100/2", units: "5"}]'`,
Args: cobra.ExactArgs(1),
credits: YAML encoded credit list. Note: numerical values must be written in strings.
eg: '[{batch_denom: "100/2", units: "5"}]'
retirement_location: A string representing the location of the buyer or
beneficiary of retired credits. It has the form
<country-code>[-<region-code>[ <postal-code>]], where
country-code and region-code are taken from ISO 3166.
eg: 'AA-BB 12345'`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
var credits = []*ecocredit.MsgRetireRequest_RetireUnits{}
if err := yaml.Unmarshal([]byte(args[0]), &credits); err != nil {
Expand All @@ -164,8 +171,9 @@ Parameters:
return err
}
msg := ecocredit.MsgRetireRequest{
Holder: clientCtx.GetFromAddress().String(),
Credits: credits,
Holder: clientCtx.GetFromAddress().String(),
Credits: credits,
Location: args[1],
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
Expand Down
23 changes: 23 additions & 0 deletions x/ecocredit/location.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ecocredit

import (
"regexp"

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

var reLocation = regexp.MustCompile(`^([A-Z]{2})(?:-([A-Z0-9]{1,3})(?: ([a-zA-Z0-9 \-]{1,64}))?)?$`)

// validateLocation checks that the country and region conform to ISO 3166 and
// the postal code is valid. This is a simple regex check and doesn't check that
// the country or subdivision codes actually exist. This is because the codes
// could change at short notice and we don't want to hardfork to keep up-to-date
// with that information.
func validateLocation(location string) error {
matches := reLocation.FindStringSubmatch(location)
if matches == nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "Invalid retirement location: %s.\nLocation should have format <country-code>[-<region-code>[-<postal-code>]].\n", location)
}

return nil
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package server
package ecocredit

import (
"testing"
Expand All @@ -24,7 +24,7 @@ func TestValidateLocation(t *testing.T) {
},
{
name: "can't validate invalid country code",
location: "ZZ",
location: "ZZZ",
expectErr: true,
},
{
Expand All @@ -44,22 +44,22 @@ func TestValidateLocation(t *testing.T) {
},
{
name: "can't validate invalid region code",
location: "BF-ZZ",
location: "BF-ZZZZ",
expectErr: true,
},
{
name: "can validate valid postal code",
location: "BF-BAL-1",
location: "BF-BAL 1",
expectErr: false,
},
{
name: "can validate valid postal code 2",
location: "BF-BAL-0123456789",
location: "BF-BAL 0123456789",
expectErr: false,
},
{
name: "can't validate invalid postal code",
location: "BF-BAL-01234567890",
location: "BF-BAL 0123456789012345678901234567890123456789012345678901234567890123456789",
expectErr: true,
},
}
Expand Down
24 changes: 22 additions & 2 deletions x/ecocredit/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,17 @@ func (m *MsgCreateBatchRequest) ValidateBasic() error {
return err
}

_, err = math.ParseNonNegativeDecimal(iss.RetiredUnits)
retiredUnits, err := math.ParseNonNegativeDecimal(iss.RetiredUnits)
if err != nil {
return err
}

if !retiredUnits.IsZero() {
err = validateLocation(iss.RetirementLocation)
if err != nil {
return err
}
}
}
return nil
}
Expand All @@ -60,10 +67,17 @@ func (m *MsgSendRequest) ValidateBasic() error {
return err
}

_, err = math.ParseNonNegativeDecimal(iss.RetiredUnits)
retiredUnits, err := math.ParseNonNegativeDecimal(iss.RetiredUnits)
if err != nil {
return err
}

if !retiredUnits.IsZero() {
err = validateLocation(iss.RetirementLocation)
if err != nil {
return err
}
}
}
return nil
}
Expand All @@ -84,6 +98,12 @@ func (m *MsgRetireRequest) ValidateBasic() error {
return err
}
}

err := validateLocation(m.Location)
if err != nil {
return err
}

return nil
}

Expand Down
62 changes: 0 additions & 62 deletions x/ecocredit/server/location.go

This file was deleted.

17 changes: 0 additions & 17 deletions x/ecocredit/server/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,6 @@ func (s serverImpl) CreateBatch(ctx types.Context, req *ecocredit.MsgCreateBatch
return nil, err
}

// Validate retirement location
err = validateLocation(issuance.RetirementLocation)
if err != nil {
return nil, err
}

err = retire(ctx, store, recipient, batchDenom, retired, issuance.RetirementLocation)
if err != nil {
return nil, err
Expand Down Expand Up @@ -226,12 +220,6 @@ func (s serverImpl) Send(ctx types.Context, req *ecocredit.MsgSendRequest) (*eco
return nil, err
}

// Validate retirement location
err = validateLocation(credit.RetirementLocation)
if err != nil {
return nil, err
}

// Add retired balance
err = retire(ctx, store, recipient, denom, retired, credit.RetirementLocation)
if err != nil {
Expand Down Expand Up @@ -263,11 +251,6 @@ func (s serverImpl) Retire(ctx types.Context, req *ecocredit.MsgRetireRequest) (
store := ctx.KVStore(s.storeKey)
holder := req.Holder

err := validateLocation(req.Location)
if err != nil {
return nil, err
}

for _, credit := range req.Credits {
denom := batchDenomT(credit.BatchDenom)
if !s.batchInfoTable.Has(ctx, orm.RowID(denom)) {
Expand Down
14 changes: 7 additions & 7 deletions x/ecocredit/server/testsuite/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,19 +197,19 @@ func (s *IntegrationTestSuite) TestScenario() {
{
name: "can't retire to an invalid country",
toRetire: "0.0001",
retirementLocation: "ZZ",
retirementLocation: "ZZZ",
expectErr: true,
},
{
name: "can't retire to an invalid region",
toRetire: "0.0001",
retirementLocation: "AF-ZZ",
retirementLocation: "AF-ZZZZ",
expectErr: true,
},
{
name: "can't retire to an invalid postal code",
toRetire: "0.0001",
retirementLocation: "AF-BDS-01234567890",
retirementLocation: "AF-BDS 0123456789012345678901234567890123456789012345678901234567890123456789",
expectErr: true,
},
{
Expand Down Expand Up @@ -241,7 +241,7 @@ func (s *IntegrationTestSuite) TestScenario() {
{
name: "can retire all credits",
toRetire: "0.3699",
retirementLocation: "AF-BDS-12345",
retirementLocation: "AF-BDS 12345",
expectErr: false,
expTradeable: "0",
expRetired: "14.656",
Expand Down Expand Up @@ -325,21 +325,21 @@ func (s *IntegrationTestSuite) TestScenario() {
name: "can't send to an invalid country",
sendTradeable: "10",
sendRetired: "20",
retirementLocation: "ZZ",
retirementLocation: "ZZZ",
expectErr: true,
},
{
name: "can't send to an invalid region",
sendTradeable: "10",
sendRetired: "20",
retirementLocation: "AF-ZZ",
retirementLocation: "AF-ZZZZ",
expectErr: true,
},
{
name: "can't send to an invalid postal code",
sendTradeable: "10",
sendRetired: "20",
retirementLocation: "AF-BDS-01234567890",
retirementLocation: "AF-BDS 0123456789012345678901234567890123456789012345678901234567890123456789",
expectErr: true,
},
{
Expand Down

0 comments on commit 8a03ae6

Please sign in to comment.