Skip to content

Commit

Permalink
x/ibc ICS24 (#5588)
Browse files Browse the repository at this point in the history
* x/ibc ICS24

* changelog

* move regex to /types

* address @alexanderbez comments

Co-authored-by: Jack Zampolin <jack.zampolin@gmail.com>
Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 19, 2020
1 parent 4cb77f0 commit 4aa078b
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ and provided directly the IAVL store.
* (types) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Refactored `AppModuleBasic` and `AppModuleGenesis`
to now accept a `codec.JSONMarshaler` for modular serialization of genesis state.

### Features

* (x/ibc) [\#5588](https://github.com/cosmos/cosmos-sdk/pull/5588) Add [ICS 024 - Host State Machine Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements) subpackage to `x/ibc` module.

### Bug Fixes

* (client) [\#5618](https://github.com/cosmos/cosmos-sdk/pull/5618) Fix crash on the client when the verifier is not set.
Expand Down
24 changes: 21 additions & 3 deletions types/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,27 @@ package types

import "regexp"

// IsAlphaNumeric defines a regular expression for matching against alpha-numeric
// values.
var IsAlphaNumeric = regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString
var (
// IsAlphaNumeric defines a regular expression for matching against alpha-numeric
// values.
IsAlphaNumeric = regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString

// IsAlphaLower defines regular expression to check if the string has lowercase
// alphabetic characters only.
IsAlphaLower = regexp.MustCompile(`^[a-z]+$`).MatchString

// IsAlphaUpper defines regular expression to check if the string has uppercase
// alphabetic characters only.
IsAlphaUpper = regexp.MustCompile(`^[A-Z]+$`).MatchString

// IsAlpha defines regular expression to check if the string has alphabetic
// characters only.
IsAlpha = regexp.MustCompile(`^[a-zA-Z]+$`).MatchString

// IsNumeric defines regular expression to check if the string has numeric
// characters only.
IsNumeric = regexp.MustCompile(`^[0-9]+$`).MatchString
)

// Router provides handlers for each transaction type.
type Router interface {
Expand Down
15 changes: 15 additions & 0 deletions x/ibc/24-host/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package host

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

// SubModuleName defines the ICS 24 host
const SubModuleName = "host"

// IBC client sentinel errors
var (
ErrInvalidID = sdkerrors.Register(SubModuleName, 1, "invalid identifier")
ErrInvalidPath = sdkerrors.Register(SubModuleName, 2, "invalid path")
ErrInvalidPacket = sdkerrors.Register(SubModuleName, 3, "invalid packet")
)
11 changes: 11 additions & 0 deletions x/ibc/24-host/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package host

// RemovePath is an util function to remove a path from a set.
func RemovePath(paths []string, path string) ([]string, bool) {
for i, p := range paths {
if p == path {
return append(paths[:i], paths[i+1:]...), true
}
}
return paths, false
}
96 changes: 96 additions & 0 deletions x/ibc/24-host/validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package host

import (
"strings"

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

// ICS 024 Identifier and Path Validation Implementation
//
// This file defines ValidateFn to validate identifier and path strings
// The spec for ICS 024 can be located here:
// https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements

// ValidateFn function type to validate path and identifier bytestrings
type ValidateFn func(string) error

func defaultIdentifierValidator(id string, min, max int) error {
// valid id MUST NOT contain "/" separator
if strings.Contains(id, "/") {
return sdkerrors.Wrapf(ErrInvalidID, "identifier %s cannot contain separator '/'", id)
}
// valid id must be between 10 and 20 characters
if len(id) < min || len(id) > max {
return sdkerrors.Wrapf(ErrInvalidID, "identifier %s has invalid length: %d, must be between %d-%d characters", id, len(id), min, max)
}
// valid id must contain only lower alphabetic characters
if !sdk.IsAlphaLower(id) {
return sdkerrors.Wrapf(ErrInvalidID, "identifier %s must contain only lowercase alphabetic characters", id)
}
return nil
}

// DefaultClientIdentifierValidator is the default validator function for Client identifiers
// A valid Identifier must be between 10-20 characters and only contain lowercase
// alphabetic characters,
func DefaultClientIdentifierValidator(id string) error {
return defaultIdentifierValidator(id, 10, 20)
}

// DefaultConnectionIdentifierValidator is the default validator function for Connection identifiers
// A valid Identifier must be between 10-20 characters and only contain lowercase
// alphabetic characters,
func DefaultConnectionIdentifierValidator(id string) error {
return defaultIdentifierValidator(id, 10, 20)
}

// DefaultChannelIdentifierValidator is the default validator function for Channel identifiers
// A valid Identifier must be between 10-20 characters and only contain lowercase
// alphabetic characters,
func DefaultChannelIdentifierValidator(id string) error {
return defaultIdentifierValidator(id, 10, 20)
}

// DefaultPortIdentifierValidator is the default validator function for Port identifiers
// A valid Identifier must be between 2-20 characters and only contain lowercase
// alphabetic characters,
func DefaultPortIdentifierValidator(id string) error {
return defaultIdentifierValidator(id, 2, 20)
}

// NewPathValidator takes in a Identifier Validator function and returns
// a Path Validator function which requires path only has valid identifiers
// alphanumeric character strings, and "/" separators
func NewPathValidator(idValidator ValidateFn) ValidateFn {
return func(path string) error {
pathArr := strings.Split(path, "/")
for _, p := range pathArr {
// Each path element must either be valid identifier or alphanumeric
err := idValidator(p)
if err != nil && !sdk.IsAlphaNumeric(p) {
return sdkerrors.Wrapf(ErrInvalidPath, "path %s contains invalid identifier or non-alphanumeric path element: %s", path, p)
}
}
return nil
}
}

// DefaultPathValidator takes in path string and validates
// with default identifier rules. This is optimized by simply
// checking that all path elements are alphanumeric
func DefaultPathValidator(path string) error {
pathArr := strings.Split(path, "/")
if pathArr[0] == path {
return sdkerrors.Wrapf(ErrInvalidPath, "path %s doesn't contain any separator '/'", path)
}

for _, p := range pathArr {
// Each path element must be alphanumeric and non-blank
if strings.TrimSpace(p) == "" || !sdk.IsAlphaNumeric(p) {
return sdkerrors.Wrapf(ErrInvalidPath, "path %s contains an invalid non-alphanumeric character: '%s'", path, p)
}
}
return nil
}

0 comments on commit 4aa078b

Please sign in to comment.