Skip to content

Commit

Permalink
Merge pull request #139 from siburu/bugfix/provestate-err-handling
Browse files Browse the repository at this point in the history
[bugfix] Fix handling error returned from `QueryClientStatePair`
  • Loading branch information
siburu authored Apr 19, 2024
2 parents f854498 + fe606bb commit 4f3349d
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 194 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DOCKER := $(shell which docker)

protoVer=0.13.1
protoVer=0.14.0
protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer)
protoImage=$(DOCKER) run --user 0 --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName)

Expand Down
13 changes: 7 additions & 6 deletions chains/tendermint/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ func (r *MsgResult) Events() []core.MsgEventLog {
func parseMsgEventLogs(events []abcitypes.Event, msgIndex uint32) ([]core.MsgEventLog, error) {
var msgEventLogs []core.MsgEventLog
for _, ev := range events {
index, err := msgIndexOf(ev)
if err == nil && index == msgIndex {
if index, found, err := msgIndexOf(ev); err != nil {
return nil, err
} else if found && index == msgIndex {
event, err := parseMsgEventLog(ev)
if err != nil {
return nil, fmt.Errorf("failed to parse msg event log: %v", err)
Expand All @@ -63,17 +64,17 @@ func parseMsgEventLogs(events []abcitypes.Event, msgIndex uint32) ([]core.MsgEve
return msgEventLogs, nil
}

func msgIndexOf(event abcitypes.Event) (uint32, error) {
func msgIndexOf(event abcitypes.Event) (uint32, bool, error) {
for _, attr := range event.Attributes {
if attr.Key == MsgIndexAttributeKey {
intValue, err := strconv.ParseUint(attr.Value, 10, 32)
if err != nil {
return 0, fmt.Errorf("failed to parse value: %v", err)
return 0, false, fmt.Errorf("failed to parse %s value: value=%s, err=%v", MsgIndexAttributeKey, attr.Value, err)
}
return uint32(intValue), nil
return uint32(intValue), true, nil
}
}
return 0, fmt.Errorf("failed to find attribute of key %q", MsgIndexAttributeKey)
return 0, false, nil
}

func parseMsgEventLog(ev abcitypes.Event) (core.MsgEventLog, error) {
Expand Down
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ func (c *Config) CreateConfig() error {
return err
}
return nil
} else if err != nil {
return err
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion core/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func createConnectionStep(src, dst *ProvableChain) (*RelayMsgs, error) {
if !(srcConn.Connection.State == conntypes.UNINITIALIZED && dstConn.Connection.State == conntypes.UNINITIALIZED) {
// Query client state from each chain's client
srcCsRes, dstCsRes, err = QueryClientStatePair(sh.GetQueryContext(src.ChainID()), sh.GetQueryContext(dst.ChainID()), src, dst, true)
if err != nil && (srcCsRes == nil || dstCsRes == nil) {
if err != nil {
return nil, err
}
if err := src.Codec().UnpackAny(srcCsRes.ClientState, &srcCS); err != nil {
Expand Down
184 changes: 0 additions & 184 deletions core/path.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
package core

import (
"context"
"crypto/rand"
"fmt"
"math/big"
"strings"

"golang.org/x/sync/errgroup"
"gopkg.in/yaml.v2"

clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"
chantypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported"
)

const (
check = "✔"
xIcon = "✘"
)

// Paths represent connection paths between chains
Expand Down Expand Up @@ -107,24 +94,6 @@ type Path struct {
Strategy *StrategyCfg `yaml:"strategy" json:"strategy"`
}

// GenSrcClientID generates the specififed identifier
func (p *Path) GenSrcClientID() { p.Src.ClientID = RandLowerCaseLetterString(10) }

// GenDstClientID generates the specififed identifier
func (p *Path) GenDstClientID() { p.Dst.ClientID = RandLowerCaseLetterString(10) }

// GenSrcConnID generates the specififed identifier
func (p *Path) GenSrcConnID() { p.Src.ConnectionID = RandLowerCaseLetterString(10) }

// GenDstConnID generates the specififed identifier
func (p *Path) GenDstConnID() { p.Dst.ConnectionID = RandLowerCaseLetterString(10) }

// GenSrcChanID generates the specififed identifier
func (p *Path) GenSrcChanID() { p.Src.ChannelID = RandLowerCaseLetterString(10) }

// GenDstChanID generates the specififed identifier
func (p *Path) GenDstChanID() { p.Dst.ChannelID = RandLowerCaseLetterString(10) }

// Ordered returns true if the path is ordered and false if otherwise
func (p *Path) Ordered() bool {
return p.Src.GetOrder() == chantypes.ORDERED
Expand Down Expand Up @@ -165,156 +134,3 @@ func (p *Path) End(chainID string) *PathEnd {
func (p *Path) String() string {
return fmt.Sprintf("[ ] %s ->\n %s", p.Src.String(), p.Dst.String())
}

// GenPath generates a path with random client, connection and channel identifiers
// given chainIDs and portIDs
func GenPath(srcChainID, dstChainID, srcPortID, dstPortID, order string, version string) *Path {
return &Path{
Src: &PathEnd{
ChainID: srcChainID,
ClientID: RandLowerCaseLetterString(10),
ConnectionID: RandLowerCaseLetterString(10),
ChannelID: RandLowerCaseLetterString(10),
PortID: srcPortID,
Order: order,
Version: version,
},
Dst: &PathEnd{
ChainID: dstChainID,
ClientID: RandLowerCaseLetterString(10),
ConnectionID: RandLowerCaseLetterString(10),
ChannelID: RandLowerCaseLetterString(10),
PortID: dstPortID,
Order: order,
Version: version,
},
Strategy: &StrategyCfg{
Type: "naive",
},
}
}

// PathStatus holds the status of the primatives in the path
type PathStatus struct {
Chains bool `yaml:"chains" json:"chains"`
Clients bool `yaml:"clients" json:"clients"`
Connection bool `yaml:"connection" json:"connection"`
Channel bool `yaml:"channel" json:"channel"`
}

// PathWithStatus is used for showing the status of the path
type PathWithStatus struct {
Path *Path `yaml:"path" json:"chains"`
Status PathStatus `yaml:"status" json:"status"`
}

// QueryPathStatus returns an instance of the path struct with some attached data about
// the current status of the path
func (p *Path) QueryPathStatus(src, dst *ProvableChain) *PathWithStatus {
var (
err error
eg errgroup.Group
srch, dsth ibcexported.Height
srcCs, dstCs *clienttypes.QueryClientStateResponse
srcConn, dstConn *conntypes.QueryConnectionResponse
srcChan, dstChan *chantypes.QueryChannelResponse

out = &PathWithStatus{Path: p, Status: PathStatus{false, false, false, false}}
)
eg.Go(func() error {
srch, err = src.LatestHeight()
return err
})
eg.Go(func() error {
dsth, err = dst.LatestHeight()
return err
})
if eg.Wait(); err != nil {
return out
}
out.Status.Chains = true

ctx := context.TODO()

eg.Go(func() error {
srcCs, err = src.QueryClientState(NewQueryContext(ctx, srch))
return err
})
eg.Go(func() error {
dstCs, err = dst.QueryClientState(NewQueryContext(ctx, dsth))
return err
})
if err = eg.Wait(); err != nil || srcCs == nil || dstCs == nil {
return out
}
out.Status.Clients = true

eg.Go(func() error {
srcConn, err = src.QueryConnection(NewQueryContext(ctx, srch))
return err
})
eg.Go(func() error {
dstConn, err = dst.QueryConnection(NewQueryContext(ctx, dsth))
return err
})
if err = eg.Wait(); err != nil || srcConn.Connection.State != conntypes.OPEN || dstConn.Connection.State != conntypes.OPEN {
return out
}
out.Status.Connection = true

eg.Go(func() error {
srcChan, err = src.QueryChannel(NewQueryContext(ctx, srch))
return err
})
eg.Go(func() error {
dstChan, err = dst.QueryChannel(NewQueryContext(ctx, dsth))
return err
})
if err = eg.Wait(); err != nil || srcChan.Channel.State != chantypes.OPEN || dstChan.Channel.State != chantypes.OPEN {
return out
}
out.Status.Channel = true
return out
}

// PrintString prints a string representations of the path status
func (ps *PathWithStatus) PrintString(name string) string {
pth := ps.Path
return fmt.Sprintf(`Path "%s" strategy(%s):
SRC(%s)
ClientID: %s
ConnectionID: %s
ChannelID: %s
PortID: %s
DST(%s)
ClientID: %s
ConnectionID: %s
ChannelID: %s
PortID: %s
STATUS:
Chains: %s
Clients: %s
Connection: %s
Channel: %s`, name, pth.Strategy.Type, pth.Src.ChainID,
pth.Src.ClientID, pth.Src.ConnectionID, pth.Src.ChannelID, pth.Src.PortID,
pth.Dst.ChainID, pth.Dst.ClientID, pth.Dst.ConnectionID, pth.Dst.ChannelID, pth.Dst.PortID,
checkmark(ps.Status.Chains), checkmark(ps.Status.Clients), checkmark(ps.Status.Connection), checkmark(ps.Status.Channel))
}

func checkmark(status bool) string {
if status {
return check
}
return xIcon
}

// RandLowerCaseLetterString returns a lowercase letter string of given length
func RandLowerCaseLetterString(length int) string {
chars := []rune("abcdefghijklmnopqrstuvwxyz")
var b strings.Builder
for i := 0; i < length; i++ {
i, _ := rand.Int(rand.Reader, big.NewInt(int64(len(chars))))
b.WriteRune(chars[i.Int64()])
}
return b.String()
}
4 changes: 2 additions & 2 deletions proto/buf.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ deps:
- remote: buf.build
owner: cosmos
repository: gogo-proto
commit: 5e5b9fdd01804356895f8f79a6f1ddc1
digest: shake256:0b85da49e2e5f9ebc4806eae058e2f56096ff3b1c59d1fb7c190413dd15f45dd456f0b69ced9059341c80795d2b6c943de15b120a9e0308b499e43e4b5fc2952
commit: 88ef6483f90f478fb938c37dde52ece3
digest: shake256:89c45df2aa11e0cff97b0d695436713db3d993d76792e9f8dc1ae90e6ab9a9bec55503d48ceedd6b86069ab07d3041b32001b2bfe0227fa725dd515ff381e5ba

0 comments on commit 4f3349d

Please sign in to comment.