Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Implement bottom up validation #398

Merged
merged 8 commits into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 122 additions & 2 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,17 @@ func cfgFilesAdd(dir string) (cfg *Config, err error) {
}

pthName := strings.Split(f.Name(), ".")[0]
if err = config.ValidatePath(p); err != nil {
fmt.Printf("%s: %s\n", pth, err.Error())
continue
}
if err = cfg.AddPath(pthName, p); err != nil {
fmt.Printf("%s: %s\n", pth, err.Error())
continue
}

// TODO: Do bottom up validation
// For now, we assume that all chain files must have same filename as chain-id
// this is to ensure non-chain files (global config) does not get parsed into chain struct.
// Future work should implement bottom-up validation.
if c.ChainID != pthName {
fmt.Printf("Skipping non chain file: %s\n", f.Name())
continue
Expand Down Expand Up @@ -420,3 +422,121 @@ func overWriteConfig(cmd *cobra.Command, cfg *Config) error {
}
return err
}

// ValidatePath checks that a path is valid
func (c *Config) ValidatePath(p *relayer.Path) (err error) {
if p.Src.Version == "" {
return fmt.Errorf("source must specify a version")
}
if err = c.ValidatePathEnd(p.Src); err != nil {
return err
}
if err = c.ValidatePathEnd(p.Dst); err != nil {
return err
}
if _, err = p.GetStrategy(); err != nil {
return err
}
if p.Src.Order != p.Dst.Order {
return fmt.Errorf("both sides must have same order ('ORDERED' or 'UNORDERED'), got src(%s) and dst(%s)",
p.Src.Order, p.Dst.Order)
}
return nil
}

// ValidatePathEnd validates provided pathend and returns error for invalid identifiers
func (c *Config) ValidatePathEnd(pe *relayer.PathEnd) error {
if err := pe.ValidateBasic(); err != nil {
return err
}

chain, err := c.Chains.Get(pe.ChainID)
if err != nil {
return err
}

height, err := chain.QueryLatestHeight()
if err != nil {
return err
}

if pe.ClientID != "" {
if err := c.ValidateClient(chain, height, pe); err != nil {
return err
}

if pe.ConnectionID != "" {
if err := c.ValidateConnection(chain, height, pe); err != nil {
return err
}

if pe.ChannelID != "" {
if err := c.ValidateChannel(chain, height, pe); err != nil {
return err
}
}
}

if pe.ConnectionID == "" && pe.ChannelID != "" {
return fmt.Errorf("connectionID is not configured for the channel: %s", pe.ChannelID)
}
}

if pe.ClientID == "" && pe.ConnectionID != "" {
return fmt.Errorf("clientID is not configured for the connection: %s", pe.ConnectionID)
}

return nil
}

// ValidateClient validates client id in provided pathend
func (c *Config) ValidateClient(chain *relayer.Chain, height int64, pe *relayer.PathEnd) error {
if err := pe.Vclient(); err != nil {
return err
}

_, err := chain.QueryClientState(height)
if err != nil {
return err
}

return nil
}

// ValidateConnection validates connection id in provided pathend
func (c *Config) ValidateConnection(chain *relayer.Chain, height int64, pe *relayer.PathEnd) error {
if err := pe.Vconn(); err != nil {
return err
}

connection, err := chain.QueryConnection(height)
if err != nil {
return err
}

if connection.Connection.ClientId != pe.ClientID {
return fmt.Errorf("clientID of connection: %s didn't match with provided ClientID", pe.ConnectionID)
}

return nil
}

// ValidateChannel validates channel id in provided pathend
func (c *Config) ValidateChannel(chain *relayer.Chain, height int64, pe *relayer.PathEnd) error {
if err := pe.Vchan(); err != nil {
return err
}

channel, err := chain.QueryChannel(height)
if err != nil {
return err
}

for _, connection := range channel.Channel.ConnectionHops {
if connection == pe.ConnectionID {
return nil
}
}

return fmt.Errorf("connectionID of channel: %s didn't match with provided ConnectionID", pe.ChannelID)
}
29 changes: 29 additions & 0 deletions cmd/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ $ %s pth gen ibc-0 ibc-1 demo-path --unordered false --version ics20-2`, appName
path.GenSrcConnID()
path.GenSrcChanID()
path.GenDstChanID()
if err = config.ValidatePath(path); err != nil {
return err
}
if err = config.Paths.Add(pth, path); err != nil {
return err
}
Expand All @@ -166,6 +169,9 @@ $ %s pth gen ibc-0 ibc-1 demo-path --unordered false --version ics20-2`, appName
path.GenSrcConnID()
path.GenSrcChanID()
path.GenDstChanID()
if err = config.ValidatePath(path); err != nil {
return err
}
if err = config.Paths.Add(pth, path); err != nil {
return err
}
Expand All @@ -177,6 +183,9 @@ $ %s pth gen ibc-0 ibc-1 demo-path --unordered false --version ics20-2`, appName
path.GenSrcConnID()
path.GenSrcChanID()
path.GenDstChanID()
if err = config.ValidatePath(path); err != nil {
return err
}
if err = config.Paths.Add(pth, path); err != nil {
return err
}
Expand Down Expand Up @@ -225,6 +234,9 @@ $ %s pth gen ibc-0 ibc-1 demo-path --unordered false --version ics20-2`, appName
path.GenDstConnID()
path.GenSrcChanID()
path.GenDstChanID()
if err = config.ValidatePath(path); err != nil {
return err
}
if err = config.Paths.Add(pth, path); err != nil {
return err
}
Expand All @@ -236,6 +248,9 @@ $ %s pth gen ibc-0 ibc-1 demo-path --unordered false --version ics20-2`, appName
path.GenDstConnID()
path.GenSrcChanID()
path.GenDstChanID()
if err = config.ValidatePath(path); err != nil {
return err
}
if err = config.Paths.Add(pth, path); err != nil {
return err
}
Expand Down Expand Up @@ -289,6 +304,9 @@ $ %s pth gen ibc-0 ibc-1 demo-path --unordered false --version ics20-2`, appName
path.GenSrcChanID()
path.GenDstChanID()
}
if err = config.ValidatePath(path); err != nil {
return err
}
if err = config.Paths.Add(pth, path); err != nil {
return err
}
Expand All @@ -297,6 +315,9 @@ $ %s pth gen ibc-0 ibc-1 demo-path --unordered false --version ics20-2`, appName
default:
path.GenSrcChanID()
path.GenDstChanID()
if err = config.ValidatePath(path); err != nil {
return err
}
if err = config.Paths.Add(pth, path); err != nil {
return err
}
Expand Down Expand Up @@ -497,6 +518,10 @@ func fileInputPathAdd(file, name string) (cfg *Config, err error) {
return nil, err
}

if err = config.ValidatePath(p); err != nil {
return nil, err
}

if err = config.Paths.Add(name, p); err != nil {
return nil, err
}
Expand Down Expand Up @@ -631,6 +656,10 @@ func userInputPathAdd(src, dst, name string) (*Config, error) {
return nil, err
}

if err = config.ValidatePath(path); err != nil {
return nil, err
}

if err = config.Paths.Add(name, path); err != nil {
return nil, err
}
Expand Down
1 change: 0 additions & 1 deletion relayer/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ func (p Paths) MustGet(name string) *Path {

// Add adds a path by its name
func (p Paths) Add(name string, path *Path) error {
// TODO: Do bottomo up validation of path
if _, found := p[name]; found {
return fmt.Errorf("path with name %s already exists", name)
}
Expand Down