From f201839e530206fc6664f59b96d3f80ea026b26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Fri, 19 Feb 2021 11:58:46 +0100 Subject: [PATCH 01/14] bump sdk version to v0.41.3 (#430) * bump sdk version * bump SDK to v0.41.3 --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 849af2c59..69560ed8c 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/avast/retry-go v2.6.0+incompatible github.com/cenkalti/backoff/v3 v3.2.2 // indirect github.com/containerd/continuity v0.0.0-20200928162600-f2cc35102c2a // indirect - github.com/cosmos/cosmos-sdk v0.41.1 + github.com/cosmos/cosmos-sdk v0.41.3 github.com/cosmos/go-bip39 v1.0.0 github.com/gogo/protobuf v1.3.3 github.com/google/go-cmp v0.5.4 // indirect @@ -26,7 +26,7 @@ require ( github.com/spf13/viper v1.7.1 github.com/stretchr/objx v0.3.0 // indirect github.com/stretchr/testify v1.7.0 - github.com/tendermint/tendermint v0.34.4 + github.com/tendermint/tendermint v0.34.7 github.com/tendermint/tm-db v0.6.4 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect diff --git a/go.sum b/go.sum index e1bedb654..5b3959e54 100644 --- a/go.sum +++ b/go.sum @@ -121,8 +121,8 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cosmos/cosmos-sdk v0.41.1 h1:QatVRc8EaEObHtOFDNYHoF6di/jvSFVkXBK3I3SQ+/4= -github.com/cosmos/cosmos-sdk v0.41.1/go.mod h1:mCaJm2k+fqY7+qwvwd7WDHZZFG3avW4+I6c4lizAkIY= +github.com/cosmos/cosmos-sdk v0.41.3 h1:FQusz1vO0iyri5RBke2aMdx7aqj5Ma2/5c/4W9+u7ko= +github.com/cosmos/cosmos-sdk v0.41.3/go.mod h1:yKN705My5fGGT93DrdoeZ96GPFLCVZrzDBciGf8/Ldo= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= @@ -632,8 +632,8 @@ github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4= github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg= github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ= -github.com/tendermint/tendermint v0.34.4 h1:E7qkvFGx27d8ugVLiAY2iWP6DL5cep3l/mpTaWKHyBA= -github.com/tendermint/tendermint v0.34.4/go.mod h1:JVuu3V1ZexOaZG8VJMRl8lnfrGw6hEB2TVnoUwKRbss= +github.com/tendermint/tendermint v0.34.7 h1:lvBJFNqpDuEzKfLZKtUXOL5dMOpqHonHlO6LCujyl6E= +github.com/tendermint/tendermint v0.34.7/go.mod h1:JVuu3V1ZexOaZG8VJMRl8lnfrGw6hEB2TVnoUwKRbss= github.com/tendermint/tm-db v0.6.2 h1:DOn8jwCdjJblrCFJbtonEIPD1IuJWpbRUUdR8GWE4RM= github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI= github.com/tendermint/tm-db v0.6.3 h1:ZkhQcKnB8/2jr5EaZwGndN4owkPsGezW2fSisS9zGbg= From a42748ccbcdfa7bf32056846468fd60affda1f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20Axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Wed, 24 Feb 2021 11:39:04 +0100 Subject: [PATCH 02/14] inital work for refactoring state based relaying --- relayer/msgs.go | 63 +++++++++++++++++++++++++++++++++++++++ relayer/naive-strategy.go | 17 +++++------ 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/relayer/msgs.go b/relayer/msgs.go index cd2c61274..05742dd71 100644 --- a/relayer/msgs.go +++ b/relayer/msgs.go @@ -1,6 +1,9 @@ package relayer import ( + "fmt" + + retry "github.com/avast/retry-go" sdk "github.com/cosmos/cosmos-sdk/types" transfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" @@ -320,3 +323,63 @@ func (c *Chain) MsgTransfer(dst *PathEnd, amount sdk.Coin, dstAddr string, timeoutTimestamp, ) } + +// MsgRelayAcknowledgement +func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPacketAck) (msgs []sdk.Msg, err error) { + + // TODO: try commenting out retries to reduce complexity + // retry getting commit response until it succeeds + if err = retry.Do(func() error { + // NOTE: the proof height uses - 1 due to tendermint's delayed execution model + ackRes, err := counterparty.QueryPacketAcknowledgement(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) + if err != nil { + return err + } + + if ackRes.Proof == nil || ackRes.Acknowledgement == nil { + return fmt.Errorf("ack packet acknowledgement query seq(%d) is nil", packet.seq) + } + + return nil + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + // clear messages + msgs = []sdk.Msg{} + + // OnRetry we want to update the light clients and then debug log + updateMsg, err := c.UpdateClient(counterparty) + if err != nil { + return + } + + msgs = append(msgs, updateMsg) + + if counterparty.debug { + counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet acknowledgement: %s", + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) + } + + })); err != nil { + counterparty.Error(err) + return + } + + version := clienttypes.ParseChainID(counterparty.ChainID) + msg := chantypes.NewMsgAcknowledgement( + chantypes.NewPacket( + packet.packetData, + packet.seq, + c.PathEnd.PortID, + c.PathEnd.ChannelID, + counterparty.PathEnd.PortID, + counterparty.PathEnd.ChannelID, + clienttypes.NewHeight(version, packet.timeout), + packet.timeoutStamp, + ), + packet.ack, + packet.dstComRes.Proof, + packet.dstComRes.ProofHeight, + c.MustGetAddress(), + ) + + return append(msgs, msg), nil +} diff --git a/relayer/naive-strategy.go b/relayer/naive-strategy.go index 59372d5bb..8c660e741 100644 --- a/relayer/naive-strategy.go +++ b/relayer/naive-strategy.go @@ -420,16 +420,12 @@ func (nrs *NaiveStrategy) RelayAcknowledgements(src, dst *Chain, sp *RelaySequen // add messages for sequences on src for _, seq := range sp.Src { // SRC wrote ack, so we query packet and send to DST - pkt, err := acknowledgementFromSequence(src, dst, seq) + msgs, err := acknowledgementFromSequence(src, dst, seq) if err != nil { return err } - msg, err := pkt.Msg(dst, src) - if err != nil { - return err - } - msgs.Dst = append(msgs.Dst, msg) + msgs.Dst = append(msgs.Dst, msgs) } // add messages for sequences on dst @@ -630,7 +626,8 @@ func relayPacketFromSequence(src, dst *Chain, seq uint64) (relayPacket, error) { return nil, fmt.Errorf("should have errored before here") } -func acknowledgementFromSequence(src, dst *Chain, seq uint64) (relayPacket, error) { +// source is the sending chain, destination is the receiving chain +func acknowledgementFromSequence(src, dst *Chain, seq uint64) ([]sdk.Msg, error) { txs, err := src.QueryTxs(src.MustGetLatestLightHeight(), 1, 1000, ackPacketQuery(src.PathEnd.ChannelID, int(seq))) switch { case err != nil: @@ -655,10 +652,12 @@ func acknowledgementFromSequence(src, dst *Chain, seq uint64) (relayPacket, erro if seq != pkt.Seq() { return nil, fmt.Errorf("wrong sequence: expected(%d) got(%d)", seq, pkt.Seq()) } - if err = pkt.FetchCommitResponse(dst, src); err != nil { + + msgs, err := src.MsgRelayAcknowledgement(dst, pkt) + if err != nil { return nil, err } - return pkt, nil + return msgs, nil } // relayPacketsFromResultTx looks through the events in a *ctypes.ResultTx From f53b7d088f24c716e523df90d44c9ce3583145f2 Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Fri, 26 Feb 2021 17:13:56 +0530 Subject: [PATCH 03/14] Modify relayPacketFromSequence --- relayer/msgs.go | 148 +++++++++++++++++++++++++++++++++++--- relayer/naive-strategy.go | 98 +++++++++++-------------- 2 files changed, 180 insertions(+), 66 deletions(-) diff --git a/relayer/msgs.go b/relayer/msgs.go index 05742dd71..c10af13ab 100644 --- a/relayer/msgs.go +++ b/relayer/msgs.go @@ -324,14 +324,142 @@ func (c *Chain) MsgTransfer(dst *PathEnd, amount sdk.Coin, dstAddr string, ) } +// MsgRelayTimeout +func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (msgs []sdk.Msg, err error) { + var recvRes *chantypes.QueryPacketReceiptResponse + // TODO: try commenting out retries to reduce complexity + // retry getting commit response until it succeeds + if err = retry.Do(func() error { + // NOTE: Timeouts currently only work with ORDERED channels for nwo + // NOTE: the proof height uses - 1 due to tendermint's delayed execution model + recvRes, err = counterparty.QueryPacketReceipt(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) + if err != nil { + return err + } + + if recvRes.Proof == nil { + return fmt.Errorf("timeout packet receipt proof seq(%d) is nil", packet.seq) + } + + return nil + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + // clear messages + msgs = []sdk.Msg{} + + // OnRetry we want to update the light clients and then debug log + updateMsg, err := c.UpdateClient(counterparty) + if err != nil { + return + } + + msgs = append(msgs, updateMsg) + + if counterparty.debug { + counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet receipt: %s", + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) + } + + })); err != nil { + counterparty.Error(err) + return + } + + if recvRes == nil { + return nil, fmt.Errorf("timeout packet [%s]seq{%d} has no associated proofs", c.ChainID, packet.seq) + } + + version := clienttypes.ParseChainID(counterparty.ChainID) + msg := chantypes.NewMsgTimeout( + chantypes.NewPacket( + packet.packetData, + packet.seq, + c.PathEnd.PortID, + c.PathEnd.ChannelID, + counterparty.PathEnd.PortID, + counterparty.PathEnd.ChannelID, + clienttypes.NewHeight(version, packet.timeout), + packet.timeoutStamp, + ), + packet.seq, + recvRes.Proof, + recvRes.ProofHeight, + c.MustGetAddress(), + ) + + return append(msgs, msg), nil +} + +// MsgRelayRecvPacket +func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPacket) (msgs []sdk.Msg, err error) { + var comRes *chantypes.QueryPacketCommitmentResponse + // TODO: try commenting out retries to reduce complexity + // retry getting commit response until it succeeds + if err = retry.Do(func() error { + // NOTE: the proof height uses - 1 due to tendermint's delayed execution model + comRes, err = counterparty.QueryPacketCommitment(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) + if err != nil { + return err + } + + if comRes.Proof == nil || comRes.Commitment == nil { + return fmt.Errorf("recv packet commitment query seq(%d) is nil", packet.seq) + } + + return nil + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + // clear messages + msgs = []sdk.Msg{} + + // OnRetry we want to update the light clients and then debug log + updateMsg, err := c.UpdateClient(counterparty) + if err != nil { + return + } + + msgs = append(msgs, updateMsg) + + if counterparty.debug { + counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet commitment: %s", + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) + } + + })); err != nil { + counterparty.Error(err) + return + } + + if comRes == nil { + return nil, fmt.Errorf("receive packet [%s]seq{%d} has no associated proofs", c.ChainID, packet.seq) + } + + version := clienttypes.ParseChainID(counterparty.ChainID) + msg := chantypes.NewMsgRecvPacket( + chantypes.NewPacket( + packet.packetData, + packet.seq, + counterparty.PathEnd.PortID, + counterparty.PathEnd.ChannelID, + c.PathEnd.PortID, + c.PathEnd.ChannelID, + clienttypes.NewHeight(version, packet.timeout), + packet.timeoutStamp, + ), + comRes.Proof, + comRes.ProofHeight, + c.MustGetAddress(), + ) + + return append(msgs, msg), nil +} + // MsgRelayAcknowledgement func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPacketAck) (msgs []sdk.Msg, err error) { - + var ackRes *chantypes.QueryPacketAcknowledgementResponse // TODO: try commenting out retries to reduce complexity // retry getting commit response until it succeeds if err = retry.Do(func() error { // NOTE: the proof height uses - 1 due to tendermint's delayed execution model - ackRes, err := counterparty.QueryPacketAcknowledgement(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) + ackRes, err = counterparty.QueryPacketAcknowledgement(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) if err != nil { return err } @@ -363,22 +491,26 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac return } - version := clienttypes.ParseChainID(counterparty.ChainID) + if ackRes == nil { + return nil, fmt.Errorf("ack packet [%s]seq{%d} has no associated proofs", counterparty.ChainID, packet.seq) + } + + version := clienttypes.ParseChainID(c.ChainID) msg := chantypes.NewMsgAcknowledgement( chantypes.NewPacket( packet.packetData, packet.seq, - c.PathEnd.PortID, - c.PathEnd.ChannelID, counterparty.PathEnd.PortID, counterparty.PathEnd.ChannelID, + c.PathEnd.PortID, + c.PathEnd.ChannelID, clienttypes.NewHeight(version, packet.timeout), packet.timeoutStamp, ), packet.ack, - packet.dstComRes.Proof, - packet.dstComRes.ProofHeight, - c.MustGetAddress(), + ackRes.Proof, + ackRes.ProofHeight, + counterparty.MustGetAddress(), ) return append(msgs, msg), nil diff --git a/relayer/naive-strategy.go b/relayer/naive-strategy.go index 8c660e741..eadcba3de 100644 --- a/relayer/naive-strategy.go +++ b/relayer/naive-strategy.go @@ -420,27 +420,23 @@ func (nrs *NaiveStrategy) RelayAcknowledgements(src, dst *Chain, sp *RelaySequen // add messages for sequences on src for _, seq := range sp.Src { // SRC wrote ack, so we query packet and send to DST - msgs, err := acknowledgementFromSequence(src, dst, seq) + relayAckMsgs, err := acknowledgementFromSequence(src, dst, seq) if err != nil { return err } - msgs.Dst = append(msgs.Dst, msgs) + msgs.Dst = append(msgs.Dst, relayAckMsgs...) } // add messages for sequences on dst for _, seq := range sp.Dst { // DST wrote ack, so we query packet and send to SRC - pkt, err := acknowledgementFromSequence(dst, src, seq) + relayAckMsgs, err := acknowledgementFromSequence(dst, src, seq) if err != nil { return err } - msg, err := pkt.Msg(src, dst) - if err != nil { - return err - } - msgs.Src = append(msgs.Src, msg) + msgs.Src = append(msgs.Src, relayAckMsgs...) } if !msgs.Ready() { @@ -488,56 +484,38 @@ func (nrs *NaiveStrategy) RelayPackets(src, dst *Chain, sp *RelaySequences) erro // add messages for sequences on src for _, seq := range sp.Src { // Query src for the sequence number to get type of packet - pkt, err := relayPacketFromSequence(src, dst, seq) + recvMsgs, timeoutMsgs, err := relayPacketFromSequence(src, dst, seq) if err != nil { return err } // depending on the type of message to be relayed, we need to // send to different chains - switch pkt.(type) { - case *relayMsgRecvPacket: - msg, err := pkt.Msg(dst, src) - if err != nil { - return err - } - msgs.Dst = append(msgs.Dst, msg) - case *relayMsgTimeout: - msg, err := pkt.Msg(src, dst) - if err != nil { - return err - } - msgs.Src = append(msgs.Src, msg) - default: - return fmt.Errorf("%T packet types not supported", pkt) + if recvMsgs != nil { + msgs.Dst = append(msgs.Dst, recvMsgs...) + } + + if timeoutMsgs != nil { + msgs.Src = append(msgs.Src, timeoutMsgs...) } } // add messages for sequences on dst for _, seq := range sp.Dst { // Query dst for the sequence number to get type of packet - pkt, err := relayPacketFromSequence(dst, src, seq) + recvMsgs, timeoutMsgs, err := relayPacketFromSequence(dst, src, seq) if err != nil { return err } // depending on the type of message to be relayed, we need to // send to different chains - switch pkt.(type) { - case *relayMsgRecvPacket: - msg, err := pkt.Msg(src, dst) - if err != nil { - return err - } - msgs.Src = append(msgs.Src, msg) - case *relayMsgTimeout: - msg, err := pkt.Msg(dst, src) - if err != nil { - return err - } - msgs.Dst = append(msgs.Dst, msg) - default: - return fmt.Errorf("%T packet types not supported", pkt) + if recvMsgs != nil { + msgs.Src = append(msgs.Src, recvMsgs...) + } + + if timeoutMsgs != nil { + msgs.Dst = append(msgs.Dst, timeoutMsgs...) } } @@ -579,51 +557,55 @@ func (nrs *NaiveStrategy) RelayPackets(src, dst *Chain, sp *RelaySequences) erro return nil } -// relayPacketFromSequence returns a sdk.Msg to relay a packet with a given seq on src -func relayPacketFromSequence(src, dst *Chain, seq uint64) (relayPacket, error) { +// relayPacketFromSequence relays a packet with a given seq on src and returns recvPacket msgs, timeoutPacketmsgs and error +func relayPacketFromSequence(src, dst *Chain, seq uint64) ([]sdk.Msg, []sdk.Msg, error) { txs, err := src.QueryTxs(src.MustGetLatestLightHeight(), 1, 1000, rcvPacketQuery(src.PathEnd.ChannelID, int(seq))) switch { case err != nil: - return nil, err + return nil, nil, err case len(txs) == 0: - return nil, fmt.Errorf("no transactions returned with query") + return nil, nil, fmt.Errorf("no transactions returned with query") case len(txs) > 1: - return nil, fmt.Errorf("more than one transaction returned with query") + return nil, nil, fmt.Errorf("more than one transaction returned with query") } rcvPackets, timeoutPackets, err := relayPacketsFromResultTx(src, dst, txs[0]) switch { case err != nil: - return nil, err + return nil, nil, err case len(rcvPackets) == 0 && len(timeoutPackets) == 0: - return nil, fmt.Errorf("no relay msgs created from query response") + return nil, nil, fmt.Errorf("no relay msgs created from query response") case len(rcvPackets)+len(timeoutPackets) > 1: - return nil, fmt.Errorf("more than one relay msg found in tx query") + return nil, nil, fmt.Errorf("more than one relay msg found in tx query") } if len(rcvPackets) == 1 { pkt := rcvPackets[0] if seq != pkt.Seq() { - return nil, fmt.Errorf("wrong sequence: expected(%d) got(%d)", seq, pkt.Seq()) + return nil, nil, fmt.Errorf("wrong sequence: expected(%d) got(%d)", seq, pkt.Seq()) } - if err = pkt.FetchCommitResponse(dst, src); err != nil { - return nil, err + + msgs, err := dst.MsgRelayRecvPacket(src, pkt.(*relayMsgRecvPacket)) + if err != nil { + return nil, nil, err } - return pkt, nil + return msgs, nil, nil } if len(timeoutPackets) == 1 { pkt := timeoutPackets[0] if seq != pkt.Seq() { - return nil, fmt.Errorf("wrong sequence: expected(%d) got(%d)", seq, pkt.Seq()) + return nil, nil, fmt.Errorf("wrong sequence: expected(%d) got(%d)", seq, pkt.Seq()) } - if err = pkt.FetchCommitResponse(src, dst); err != nil { - return nil, err + + msgs, err := src.MsgRelayTimeout(dst, pkt.(*relayMsgTimeout)) + if err != nil { + return nil, nil, err } - return pkt, nil + return nil, msgs, nil } - return nil, fmt.Errorf("should have errored before here") + return nil, nil, fmt.Errorf("should have errored before here") } // source is the sending chain, destination is the receiving chain @@ -653,7 +635,7 @@ func acknowledgementFromSequence(src, dst *Chain, seq uint64) ([]sdk.Msg, error) return nil, fmt.Errorf("wrong sequence: expected(%d) got(%d)", seq, pkt.Seq()) } - msgs, err := src.MsgRelayAcknowledgement(dst, pkt) + msgs, err := dst.MsgRelayAcknowledgement(src, pkt) if err != nil { return nil, err } From 47b80d19a08be601eb17b7426298d3a760b8f15d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Fri, 26 Feb 2021 17:06:41 +0100 Subject: [PATCH 04/14] update tendermint client to not prune light blocks (#437) --- relayer/tm-light-client.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/relayer/tm-light-client.go b/relayer/tm-light-client.go index f4bcd7375..b7bec3443 100644 --- a/relayer/tm-light-client.go +++ b/relayer/tm-light-client.go @@ -128,7 +128,9 @@ func (c *Chain) LightClientWithoutTrust(db dbm.DB) (*light.Client, error) { // NOTE: This requires adding them to the chain config []lightp.Provider{prov}, dbs.New(db, ""), - logger) + logger, + light.PruningSize(0), + ) } // LightClientWithTrust takes a header from the chain and attempts to add that header to the light @@ -144,7 +146,9 @@ func (c *Chain) LightClientWithTrust(db dbm.DB, to light.TrustOptions) (*light.C // NOTE: This requires adding them to the chain config []lightp.Provider{prov}, dbs.New(db, ""), - logger) + logger, + light.PruningSize(0), + ) } // LightClient initializes the light client for a given chain from the trusted store in the database From 201dd0a6ad957ba9fa8e74cf714c85b7444dfac1 Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Mon, 1 Mar 2021 11:52:33 +0530 Subject: [PATCH 05/14] Address comments and fix lint issues --- relayer/msgs.go | 16 ++++++++-------- relayer/naive-strategy.go | 5 +++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/relayer/msgs.go b/relayer/msgs.go index c10af13ab..5de1123fe 100644 --- a/relayer/msgs.go +++ b/relayer/msgs.go @@ -329,7 +329,7 @@ func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (m var recvRes *chantypes.QueryPacketReceiptResponse // TODO: try commenting out retries to reduce complexity // retry getting commit response until it succeeds - if err = retry.Do(func() error { + if err = retry.Do(func() (err error) { // NOTE: Timeouts currently only work with ORDERED channels for nwo // NOTE: the proof height uses - 1 due to tendermint's delayed execution model recvRes, err = counterparty.QueryPacketReceipt(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) @@ -394,7 +394,7 @@ func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPack var comRes *chantypes.QueryPacketCommitmentResponse // TODO: try commenting out retries to reduce complexity // retry getting commit response until it succeeds - if err = retry.Do(func() error { + if err = retry.Do(func() (err error) { // NOTE: the proof height uses - 1 due to tendermint's delayed execution model comRes, err = counterparty.QueryPacketCommitment(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) if err != nil { @@ -432,7 +432,7 @@ func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPack return nil, fmt.Errorf("receive packet [%s]seq{%d} has no associated proofs", c.ChainID, packet.seq) } - version := clienttypes.ParseChainID(counterparty.ChainID) + version := clienttypes.ParseChainID(c.ChainID) msg := chantypes.NewMsgRecvPacket( chantypes.NewPacket( packet.packetData, @@ -457,7 +457,7 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac var ackRes *chantypes.QueryPacketAcknowledgementResponse // TODO: try commenting out retries to reduce complexity // retry getting commit response until it succeeds - if err = retry.Do(func() error { + if err = retry.Do(func() (err error) { // NOTE: the proof height uses - 1 due to tendermint's delayed execution model ackRes, err = counterparty.QueryPacketAcknowledgement(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) if err != nil { @@ -495,22 +495,22 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac return nil, fmt.Errorf("ack packet [%s]seq{%d} has no associated proofs", counterparty.ChainID, packet.seq) } - version := clienttypes.ParseChainID(c.ChainID) + version := clienttypes.ParseChainID(counterparty.ChainID) msg := chantypes.NewMsgAcknowledgement( chantypes.NewPacket( packet.packetData, packet.seq, - counterparty.PathEnd.PortID, - counterparty.PathEnd.ChannelID, c.PathEnd.PortID, c.PathEnd.ChannelID, + counterparty.PathEnd.PortID, + counterparty.PathEnd.ChannelID, clienttypes.NewHeight(version, packet.timeout), packet.timeoutStamp, ), packet.ack, ackRes.Proof, ackRes.ProofHeight, - counterparty.MustGetAddress(), + c.MustGetAddress(), ) return append(msgs, msg), nil diff --git a/relayer/naive-strategy.go b/relayer/naive-strategy.go index eadcba3de..b33106154 100644 --- a/relayer/naive-strategy.go +++ b/relayer/naive-strategy.go @@ -557,7 +557,8 @@ func (nrs *NaiveStrategy) RelayPackets(src, dst *Chain, sp *RelaySequences) erro return nil } -// relayPacketFromSequence relays a packet with a given seq on src and returns recvPacket msgs, timeoutPacketmsgs and error +// relayPacketFromSequence relays a packet with a given seq on src +// and returns recvPacket msgs, timeoutPacketmsgs and error func relayPacketFromSequence(src, dst *Chain, seq uint64) ([]sdk.Msg, []sdk.Msg, error) { txs, err := src.QueryTxs(src.MustGetLatestLightHeight(), 1, 1000, rcvPacketQuery(src.PathEnd.ChannelID, int(seq))) switch { @@ -635,7 +636,7 @@ func acknowledgementFromSequence(src, dst *Chain, seq uint64) ([]sdk.Msg, error) return nil, fmt.Errorf("wrong sequence: expected(%d) got(%d)", seq, pkt.Seq()) } - msgs, err := dst.MsgRelayAcknowledgement(src, pkt) + msgs, err := src.MsgRelayAcknowledgement(dst, pkt) if err != nil { return nil, err } From 30ed9215a10c4d61d112a239c8512f28f569e4ae Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Mon, 1 Mar 2021 12:07:45 +0530 Subject: [PATCH 06/14] Fix lint issues --- relayer/msgs.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/relayer/msgs.go b/relayer/msgs.go index 5de1123fe..dda62b8b8 100644 --- a/relayer/msgs.go +++ b/relayer/msgs.go @@ -342,13 +342,13 @@ func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (m } return nil - }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, onRtyErr error) { // clear messages msgs = []sdk.Msg{} // OnRetry we want to update the light clients and then debug log - updateMsg, err := c.UpdateClient(counterparty) - if err != nil { + updateMsg, onRtyErr := c.UpdateClient(counterparty) + if onRtyErr != nil { return } @@ -356,7 +356,7 @@ func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (m if counterparty.debug { counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet receipt: %s", - counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, onRtyErr)) } })); err != nil { @@ -406,13 +406,13 @@ func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPack } return nil - }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, onRtyErr error) { // clear messages msgs = []sdk.Msg{} // OnRetry we want to update the light clients and then debug log - updateMsg, err := c.UpdateClient(counterparty) - if err != nil { + updateMsg, onRtyErr := c.UpdateClient(counterparty) + if onRtyErr != nil { return } @@ -420,7 +420,7 @@ func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPack if counterparty.debug { counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet commitment: %s", - counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, onRtyErr)) } })); err != nil { @@ -469,13 +469,13 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac } return nil - }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, onRtyErr error) { // clear messages msgs = []sdk.Msg{} // OnRetry we want to update the light clients and then debug log - updateMsg, err := c.UpdateClient(counterparty) - if err != nil { + updateMsg, onRtyErr := c.UpdateClient(counterparty) + if onRtyErr != nil { return } @@ -483,7 +483,7 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac if counterparty.debug { counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet acknowledgement: %s", - counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, onRtyErr)) } })); err != nil { From 7fc9d48019ed7a172da278e6eecdd6f6750bd1e5 Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Mon, 1 Mar 2021 12:26:56 +0530 Subject: [PATCH 07/14] Remove onRtyErr (lint issue) --- relayer/msgs.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/relayer/msgs.go b/relayer/msgs.go index dda62b8b8..9070a4151 100644 --- a/relayer/msgs.go +++ b/relayer/msgs.go @@ -342,13 +342,13 @@ func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (m } return nil - }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, onRtyErr error) { + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, _ error) { // clear messages msgs = []sdk.Msg{} // OnRetry we want to update the light clients and then debug log - updateMsg, onRtyErr := c.UpdateClient(counterparty) - if onRtyErr != nil { + updateMsg, err := c.UpdateClient(counterparty) + if err != nil { return } @@ -356,7 +356,7 @@ func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (m if counterparty.debug { counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet receipt: %s", - counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, onRtyErr)) + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) } })); err != nil { @@ -406,13 +406,13 @@ func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPack } return nil - }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, onRtyErr error) { + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, _ error) { // clear messages msgs = []sdk.Msg{} // OnRetry we want to update the light clients and then debug log - updateMsg, onRtyErr := c.UpdateClient(counterparty) - if onRtyErr != nil { + updateMsg, err := c.UpdateClient(counterparty) + if err != nil { return } @@ -420,7 +420,7 @@ func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPack if counterparty.debug { counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet commitment: %s", - counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, onRtyErr)) + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) } })); err != nil { @@ -469,13 +469,13 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac } return nil - }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, onRtyErr error) { + }, rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, _ error) { // clear messages msgs = []sdk.Msg{} // OnRetry we want to update the light clients and then debug log - updateMsg, onRtyErr := c.UpdateClient(counterparty) - if onRtyErr != nil { + updateMsg, err := c.UpdateClient(counterparty) + if err != nil { return } @@ -483,7 +483,7 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac if counterparty.debug { counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet acknowledgement: %s", - counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, onRtyErr)) + counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) } })); err != nil { From 8008821ff0adb2d5344b9ef15f3fdd057bb26dfd Mon Sep 17 00:00:00 2001 From: Afanti Date: Mon, 1 Mar 2021 20:47:19 +0800 Subject: [PATCH 08/14] typo fix (#438) --- relayer/chain.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/relayer/chain.go b/relayer/chain.go index 3c1bc1173..469b9ca8e 100644 --- a/relayer/chain.go +++ b/relayer/chain.go @@ -67,7 +67,7 @@ type Chain struct { timeout time.Duration debug bool - // stores facuet addresses that have been used reciently + // stores faucet addresses that have been used reciently faucetAddrs map[string]time.Time } @@ -412,7 +412,7 @@ func lightDir(home string) string { return path.Join(home, "light") } -// GetAddress returns the sdk.AccAddress associated with the configred key +// GetAddress returns the sdk.AccAddress associated with the configured key func (c *Chain) GetAddress() (sdk.AccAddress, error) { defer c.UseSDKContext()() if c.address != nil { From a242db1aed18c8439a19ba6b8ca4395409da78de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Mon, 1 Mar 2021 17:49:02 +0100 Subject: [PATCH 09/14] disable tm pruning (#441) --- relayer/tm-light-client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/relayer/tm-light-client.go b/relayer/tm-light-client.go index b7bec3443..d118af4bd 100644 --- a/relayer/tm-light-client.go +++ b/relayer/tm-light-client.go @@ -164,6 +164,7 @@ func (c *Chain) LightClient(db dbm.DB) (*light.Client, error) { []lightp.Provider{prov}, dbs.New(db, ""), logger, + light.PruningSize(0), ) } From d007627a41474800f975fa720cdc77ecef12ac95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 2 Mar 2021 15:36:17 +0100 Subject: [PATCH 10/14] update release naming (#442) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cf20b678c..07ae8f29f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: "Release Relayer" +name: "(WARNING: ALPHA SOFTWARE)" on: push: From 3eb03944d01cc8ce6743add8d3529ea579b7c4fe Mon Sep 17 00:00:00 2001 From: Akhil Kumar P <36399231+akhilkumarpilli@users.noreply.github.com> Date: Wed, 3 Mar 2021 17:13:38 +0530 Subject: [PATCH 11/14] Implement swagger docs and fix path validation (#434) * Add swagger setup * Add some routes docs and swagger ui * Add few more route docs * Add swagger docs for remaining routes * Fix golint issues * Fix unused lint issues * check chain-id in AddChain --- Makefile | 7 + cmd/api.go | 6 +- cmd/chains.go | 11 +- cmd/config.go | 12 +- cmd/doc.go | 616 ++++++++ cmd/keys.go | 2 +- cmd/paths.go | 36 +- docs/rest-server.md | 8 +- docs/swagger-ui/favicon-16x16.png | Bin 0 -> 445 bytes docs/swagger-ui/favicon-32x32.png | Bin 0 -> 1141 bytes docs/swagger-ui/index.html | 60 + docs/swagger-ui/oauth2-redirect.html | 67 + docs/swagger-ui/swagger.yaml | 2156 ++++++++++++++++++++++++++ 13 files changed, 2939 insertions(+), 42 deletions(-) create mode 100644 cmd/doc.go create mode 100644 docs/swagger-ui/favicon-16x16.png create mode 100644 docs/swagger-ui/favicon-32x32.png create mode 100644 docs/swagger-ui/index.html create mode 100644 docs/swagger-ui/oauth2-redirect.html create mode 100644 docs/swagger-ui/swagger.yaml diff --git a/Makefile b/Makefile index c81641dea..e2fe1cfd0 100644 --- a/Makefile +++ b/Makefile @@ -98,3 +98,10 @@ build-wasmd: delete-chains: @echo "Removing the ./chain-code/ directory..." @rm -rf ./chain-code + +check-swagger: + which swagger || (GO111MODULE=off go get -u github.com/go-swagger/go-swagger/cmd/swagger) + +update-swagger-docs: check-swagger + swagger generate spec -o ./docs/swagger-ui/swagger.yaml + diff --git a/cmd/api.go b/cmd/api.go index 51bb53d87..05e8adf39 100644 --- a/cmd/api.go +++ b/cmd/api.go @@ -168,11 +168,15 @@ func getAPICmd() *cobra.Command { // Data for this should be stored in the ServicesManager struct r.HandleFunc("/listen/{path}/{strategy}/{name}", PostRelayerListenHandler(sm)).Methods("POST") + fs := http.FileServer(http.Dir("./docs/swagger-ui")) + r.PathPrefix("/").Handler(fs) + + fmt.Println("listening on", config.Global.APIListenPort) + if err := http.ListenAndServe(config.Global.APIListenPort, r); err != nil { return err } - fmt.Println("listening on", config.Global.APIListenPort) return nil }, } diff --git a/cmd/chains.go b/cmd/chains.go index b0df260ec..cde97f333 100644 --- a/cmd/chains.go +++ b/cmd/chains.go @@ -546,8 +546,10 @@ type addChainRequest struct { GasAdjustment string `json:"gas-adjustment"` GasPrices string `json:"gas-prices"` TrustingPeriod string `json:"trusting-period"` - FilePath string `json:"file"` - URL string `json:"url"` + // required: false + FilePath string `json:"file"` + // required: false + URL string `json:"url"` } // PostChainHandler handles the route @@ -678,6 +680,11 @@ func PutChainHandler(w http.ResponseWriter, r *http.Request) { // DeleteChainHandler handles the route func DeleteChainHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) + _, err := config.Chains.Get(vars["name"]) + if err != nil { + helpers.WriteErrorResponse(http.StatusBadRequest, err, w) + return + } if err := overWriteConfig(config.DeleteChain(vars["name"])); err != nil { helpers.WriteErrorResponse(http.StatusInternalServerError, err, w) return diff --git a/cmd/config.go b/cmd/config.go index f95c5120e..2b1f9ed48 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -363,6 +363,9 @@ func newDefaultGlobalConfig() GlobalConfig { // AddChain adds an additional chain to the config func (c *Config) AddChain(chain *relayer.Chain) (err error) { + if chain.ChainID == "" { + return fmt.Errorf("chain ID cannot be empty") + } chn, err := c.Chains.Get(chain.ChainID) if chn == nil || err == nil { return fmt.Errorf("chain with ID %s already exists in config", chain.ChainID) @@ -564,15 +567,16 @@ func (c *Config) ValidatePathEnd(pe *relayer.PathEnd) error { return err } + chain, err := c.Chains.Get(pe.ChainID) + if err != nil { + return err + } + // if the identifiers are empty, don't do any validation if pe.ClientID == "" && pe.ConnectionID == "" && pe.ChannelID == "" { return nil } - chain, err := c.Chains.Get(pe.ChainID) - if err != nil { - return err - } // NOTE: this is just to do validation, the path // is not written to the config file if err = chain.SetPath(pe); err != nil { diff --git a/cmd/doc.go b/cmd/doc.go new file mode 100644 index 000000000..4709b7cad --- /dev/null +++ b/cmd/doc.go @@ -0,0 +1,616 @@ +// Package cmd Relayer Rest Server. +// +// A REST interface for state queries. +// +// Schemes: http +// Basepath: / +// Version: 1.0.0 +// Host: localhost:5183 +// +// Consumes: +// - application/json +// +// Produces: +// - application/json +// +// +// swagger:meta +// nolint +package cmd + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + transfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" + conntypes "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types" + chantypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" + tmclient "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" + "github.com/cosmos/relayer/helpers" + "github.com/cosmos/relayer/relayer" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + ctypes "github.com/tendermint/tendermint/rpc/core/types" +) + +// swagger:response errorResponse +type errResWrapper struct { + // in:body + Error struct { + Err string `json:"err" yaml:"err"` + } +} + +// swagger:route GET /version Version version +// Get version. +// responses: +// 200: versionResponse + +// swagger:response versionResponse +type versionResWrapper struct { + // in:body + VersionInfo versionInfo +} + +// swagger:route GET /config Config config +// Get config. +// responses: +// 200: configResponse + +// swagger:response configResponse +type configResWrapper struct { + // Returns config of relayer + // in:body + Config *Config +} + +// swagger:parameters getChain addChain updateChain deleteChain getChainStatus +// swagger:parameters getPath addPath deletePath getPathStatus +// swagger:parameters getKey addKey deleteKey restoreKey +type nameParamsWrapper struct { + // in:path + Name string `json:"name" yaml:"name"` +} + +// swagger:parameters getKeys getKey addKey deleteKey restoreKey +// swagger:parameters getLightHeader getLightHeight initLight updateLight deleteLight +// swagger:parameters queryAccount queryBalance queryHeader queryNodeState queryValSet +// swagger:parameters queryTxs queryTx queryClient queryClients queryConn queryConns +// swagger:parameters queryClientConns queryChan queryChans queryConnChans queryIBCDenoms +type chainIDParamsWrapper struct { + // in:path + ChainID string `json:"chain-id" yaml:"chain-id"` +} + +// swagger:parameters getLightHeader queryHeader queryValSet queryClient queryConn queryClientConns queryChan +type heightParamsWrapper struct { + // in:query + Height int `json:"height" yaml:"height"` +} + +// swagger:parameters queryTxs queryClients queryConns queryChans queryConnChans +type paginationParamsWrapper struct { + // in:query + Offset uint `json:"offset" yaml:"offset"` + // in:query + Limit uint `json:"limit" yaml:"limit"` +} + +// swagger:response stringSuccessResponse +type stringResWrapper struct { + // in:body + Res string `json:"res" yaml:"res"` +} + +// swagger:route GET /chains Chains getChains +// Get chains list. +// responses: +// 200: getChainsResponse + +// swagger:response getChainsResponse +type getChainsResWrapper struct { + // Returns chains list. + // in:body + Chains relayer.Chains +} + +// swagger:route GET /chains/{name} Chains getChain +// Get single chain details. +// responses: +// 200: body:getChainResponse Returns chain details +// 400: errorResponse + +// swagger:response getChainResponse +type getChainResWrapper struct { + // in:body + Chain *relayer.Chain +} + +// swagger:route POST /chains/{name} Chains addChain +// Add a chain. +// +// file and url parameters in body are optional and can't use both at once. +// responses: +// 201: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters addChain +type addChainParamsWrapper struct { + // required:true + // in:body + Body addChainRequest `json:"body" yaml:"body"` +} + +// swagger:route PUT /chains/{name} Chains updateChain +// Update chain config values. +// responses: +// 200: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters updateChain +type updateChainParamsWrapper struct { + // required:true + // in:body + Body editChainRequest `json:"body" yaml:"body"` +} + +// swagger:route DELETE /chains/{name} Chains deleteChain +// Delete Chain. +// responses: +// 200: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 500: errorResponse + +// swagger:route GET /chains/{name}/status Chains getChainStatus +// Get status of a chain. +// responses: +// 200: chainStatusRes +// 400: errorResponse + +// swagger:response chainStatusRes +type chainStatusResWrapper struct { + // in:body + Status chainStatusResponse +} + +// swagger:route GET /paths Paths getPaths +// Get paths list. +// responses: +// 200: getPathsResponse + +// swagger:response getPathsResponse +type getPathsResWrapper struct { + // Returns paths list. + // in:body + Paths relayer.Paths +} + +// swagger:route GET /paths/{name} Paths getPath +// Get single path details. +// responses: +// 200: getPathResponse +// 400: errorResponse + +// swagger:response getPathResponse +type getPathResWrapper struct { + // in:body + Path *relayer.Path +} + +// swagger:route POST /paths/{name} Paths addPath +// Add a path. +// +// file parameter in body is optional and if given, it will considered first. +// +// responses: +// 201: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters addPath +type addPathParamsWrapper struct { + // required:true + // in:body + Body postPathRequest `json:"body" yaml:"body"` +} + +// swagger:route DELETE /paths/{name} Paths deletePath +// Delete Path. +// responses: +// 200: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 500: errorResponse + +// swagger:route GET /paths/{name}/status Paths getPathStatus +// Get status of a path. +// responses: +// 200: pathStatusRes +// 400: errorResponse +// 500: errorResponse + +// swagger:response pathStatusRes +type pathStatusResWrapper struct { + // in:body + Status *relayer.PathWithStatus +} + +// swagger:route GET /keys/{chain-id} Keys getKeys +// Get keys list of a chain. +// responses: +// 200: getKeysResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response getKeysResponse +type getKeysResWrapper struct { + // in:body + Keys []keyResponse +} + +// swagger:route GET /keys/{chain-id}/{name} Keys getKey +// Get details of a key in a chain. +// responses: +// 200: getKeyResponse +// 400: errorResponse +// 404: errorResponse +// 500: errorResponse + +// swagger:response getKeyResponse +type getKeyResWrapper struct { + // in:body + Key keyResponse +} + +// swagger:route POST /keys/{chain-id}/{name} Keys addKey +// Add a key in a chain. +// +// coin-type is a query parameter (optional) +// +// responses: +// 201: keyCreatedResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters addKey restoreKey +type addKeyParamsWrapper struct { + // required:false + // in:query + CoinType int `json:"coin-type" yaml:"coin-type"` +} + +// swagger:response keyCreatedResponse +type keyCreatedResWrapper struct { + // in:body + KeyOutput helpers.KeyOutput +} + +// swagger:route POST /keys/{chain-id}/{name}/restore Keys restoreKey +// Restore a key using mnemonic. +// +// coin-type is a query parameter (optional) +// +// responses: +// 200: keyCreatedResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters restoreKey +type restoreKeyParamsWrapper struct { + // required:true + // in:body + Body restoreKeyRequest `json:"body" yaml:"body"` +} + +// swagger:route DELETE /keys/{chain-id}/{name} Keys deleteKey +// Delete key in a chain. +// responses: +// 200: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 404: errorResponse +// 500: errorResponse + +// swagger:route GET /light/{chain-id}/header Light getLightHeader +// Get light header of a chain. +// responses: +// 200: headerResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response headerResponse +type headerResWrapper struct { + // in:body + Header *tmclient.Header +} + +// swagger:route GET /light/{chain-id}/height Light getLightHeight +// Get light height of a chain. +// responses: +// 200: body:getLightHeightResponse Returns light height +// 400: errorResponse +// 500: errorResponse + +// swagger:response getLightHeightResponse +type getLightHeightResWrapper struct { + // in:body + Height int64 `json:"height" yaml:"height"` +} + +// swagger:route POST /light/{chain-id} Light initLight +// Init light header for a chain. +// +// force is optional and if given, it will be considered first, +// height and hash can be used instead of force and need to send both values. +// responses: +// 201: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters initLight +type initLightParamsWrapper struct { + // required:true + // in:body + Body postLightRequest `json:"body" yaml:"body"` +} + +// swagger:route PUT /light/{chain-id} Light updateLight +// Update light header of a chain. +// responses: +// 200: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 500: errorResponse + +// swagger:route DELETE /light/{chain-id} Light deleteLight +// Delete light header of a chain. +// responses: +// 200: body:stringSuccessResponse Returns success string +// 400: errorResponse +// 500: errorResponse + +// swagger:route GET /query/{chain-id}/account/{address} Query queryAccount +// Query account of a chain. +// responses: +// 200: body:queryAccountResponse Output format might change if address queried is Module Account +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters queryAccount queryBalance +type addressParamsWrapper struct { + // in:path + Address string `json:"address" yaml:"address"` +} + +// swagger:response queryAccountResponse +type queryAccountResWrapper struct { + // in:body + Res struct { + Account *authtypes.BaseAccount `json:"account" yaml:"account"` + } +} + +// swagger:route GET /query/{chain-id}/balance/{address} Query queryBalance +// Query balance of a chain. +// responses: +// 200: queryBalanceResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters queryBalance +type queryBalanceParamsWrapper struct { + // in:query + IBCDenoms bool `json:"ibc-denoms" yaml:"ibc-denoms"` +} + +// swagger:response queryBalanceResponse +type queryBalanceResWrapper struct { + // in:body + Balance sdk.Coins +} + +// swagger:route GET /query/{chain-id}/header Query queryHeader +// Query header of a chain. +// responses: +// 200: headerResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:route GET /query/{chain-id}/node-state Query queryNodeState +// Query node state of a chain. +// responses: +// 200: nodeStateResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response nodeStateResponse +type nodeStateResWrapper struct { + // in:body + ConsensusState *tmclient.ConsensusState +} + +// swagger:route GET /query/{chain-id}/valset Query queryValSet +// Query node state of a chain. +// responses: +// 200: valSetResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response valSetResponse +type valSetResWrapper struct { + // in:body + ValSet *tmproto.ValidatorSet +} + +// swagger:route POST /query/{chain-id}/txs Query queryTxs +// Query Txs using events. +// responses: +// 200: txsResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters queryTxs +type queryTxsParamsWrapper struct { + // in:body + Body txsRequest `json:"body" yaml:"body"` +} + +// swagger:response txsResponse +type txsResWrapper struct { + // in:body + Txs []*ctypes.ResultTx +} + +// swagger:route GET /query/{chain-id}/tx/{hash} Query queryTx +// Query Tx details by hash. +// responses: +// 200: txResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters queryTx +type queryTxParamsWrapper struct { + // in:path + Hash string `json:"hash" yaml:"hash"` +} + +// swagger:response txResponse +type txResWrapper struct { + // in:body + Txs *ctypes.ResultTx +} + +// swagger:route GET /query/{chain-id}/clients/{client-id} Query queryClient +// Query client by clientID. +// responses: +// 200: queryClientResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters queryClient +type clientParamsWrapper struct { + // in:path + ClientID string `json:"client-id" yaml:"client-id"` +} + +// swagger:response queryClientResponse +type queryClientResWrapper struct { + // in:body + Client *clienttypes.QueryClientStateResponse +} + +// swagger:route GET /query/{chain-id}/clients Query queryClients +// Query clients of a chain. +// responses: +// 200: queryClientsResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response queryClientsResponse +type queryClientsResWrapper struct { + // in:body + Clients *clienttypes.QueryClientStatesResponse +} + +// swagger:route GET /query/{chain-id}/connections/{conn-id} Query queryConn +// Query connection by connectionID. +// responses: +// 200: queryConnResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters queryConn queryConnChans +type connectionParamsWrapper struct { + // in:path + ConnectionID string `json:"conn-id" yaml:"conn-id"` +} + +// swagger:response queryConnResponse +type queryConnResWrapper struct { + // in:body + Connection *conntypes.QueryConnectionResponse +} + +// swagger:route GET /query/{chain-id}/connections Query queryConns +// Query connections of a chain. +// responses: +// 200: queryConnsResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response queryConnsResponse +type queryConnsResWrapper struct { + // in:body + Connections *conntypes.QueryConnectionsResponse +} + +// swagger:route GET /query/{chain-id}/connections/client/{client-id} Query queryClientConns +// Query connections of a client in a chain. +// responses: +// 200: queryClientConnsResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response queryClientConnsResponse +type queryClientConnsResWrapper struct { + // in:body + Connections *conntypes.QueryClientConnectionsResponse +} + +// swagger:route GET /query/{chain-id}/channels/{chan-id}/{port-id} Query queryChan +// Query channel by channelID and portID. +// responses: +// 200: queryChanResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:parameters queryChan +type channelParamsWrapper struct { + // in:path + ChannelID string `json:"chan-id" yaml:"chan-id"` + // in:path + PortID string `json:"port-id" yaml:"port-id"` +} + +// swagger:response queryChanResponse +type queryChanResWrapper struct { + // in:body + Channel *chantypes.QueryChannelResponse +} + +// swagger:route GET /query/{chain-id}/channels Query queryChans +// Query channels of a chain. +// responses: +// 200: queryChansResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response queryChansResponse +type queryChansResWrapper struct { + // in:body + Channels *chantypes.QueryChannelsResponse +} + +// swagger:route GET /query/{chain-id}/channels/connection/{conn-id} Query queryConnChans +// Query channels of a connection in a chain. +// responses: +// 200: queryConnChansResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response queryConnChansResponse +type queryConnChansResWrapper struct { + // in:body + Channels *chantypes.QueryConnectionChannelsResponse +} + +// swagger:route GET /query/{chain-id}/ibc-denoms Query queryIBCDenoms +// Query ibc-denoms of a chain. +// responses: +// 200: queryIBCDenomsResponse +// 400: errorResponse +// 500: errorResponse + +// swagger:response queryIBCDenomsResponse +type queryIBCDenomsResWrapper struct { + // in:body + IBCDenoms *transfertypes.QueryDenomTracesResponse +} diff --git a/cmd/keys.go b/cmd/keys.go index aaf36a507..7e03d4e6e 100644 --- a/cmd/keys.go +++ b/cmd/keys.go @@ -426,7 +426,7 @@ func RestoreKeyHandler(w http.ResponseWriter, r *http.Request) { keyName := vars["name"] if chain.KeyExists(keyName) { - helpers.WriteErrorResponse(http.StatusNotFound, errKeyExists(keyName), w) + helpers.WriteErrorResponse(http.StatusBadRequest, errKeyExists(keyName), w) return } diff --git a/cmd/paths.go b/cmd/paths.go index c0fa61595..2b55490dd 100644 --- a/cmd/paths.go +++ b/cmd/paths.go @@ -706,11 +706,9 @@ func GetPathStatusHandler(w http.ResponseWriter, r *http.Request) { } type postPathRequest struct { - FilePath string `json:"file"` - SrcChainID string `json:"src-chain-id"` - DstChainID string `json:"dst-chain-id"` - Src relayer.PathEnd `json:"src"` - Dst relayer.PathEnd `json:"dst"` + FilePath string `json:"file"` + Src relayer.PathEnd `json:"src"` + Dst relayer.PathEnd `json:"dst"` } // PostPathHandler handles the route @@ -719,28 +717,9 @@ func PostPathHandler(w http.ResponseWriter, r *http.Request) { pathName := vars["name"] var request postPathRequest - if err := json.NewDecoder(r.Body).Decode(&request); err != nil { - helpers.WriteErrorResponse(http.StatusBadRequest, err, w) - return - } - - if request.SrcChainID == "" { - helpers.WriteErrorResponse(http.StatusBadRequest, fmt.Errorf("src-chain-id is required"), w) - return - } - - if request.DstChainID == "" { - helpers.WriteErrorResponse(http.StatusBadRequest, fmt.Errorf("dst-chain-id is required"), w) - return - } - - _, err := config.Chains.Gets(request.SrcChainID, request.DstChainID) + err := json.NewDecoder(r.Body).Decode(&request) if err != nil { - helpers.WriteErrorResponse( - http.StatusBadRequest, - fmt.Errorf("chains need to be configured before paths to them can be added: %w", err), - w, - ) + helpers.WriteErrorResponse(http.StatusBadRequest, err, w) return } @@ -773,8 +752,9 @@ func addPathByRequest(req postPathRequest, pathName string) (*Config, error) { } ) - path.Src.ChainID = req.SrcChainID - path.Dst.ChainID = req.DstChainID + if err := config.ValidatePath(path); err != nil { + return nil, err + } if err := config.Paths.Add(pathName, path); err != nil { return nil, err diff --git a/docs/rest-server.md b/docs/rest-server.md index cdb3ac958..c23f0f381 100644 --- a/docs/rest-server.md +++ b/docs/rest-server.md @@ -45,12 +45,10 @@ $ curl -d '{"key":"testkey3","rpc-addr":"http://localhost:26657","account-prefix "chain ibc-2 added successfully" # Add new path to relay over -$ curl -d '{"src-chain-id":"ibc-0","dst-chain-id":"ibc-1","src":{"client-id":"","connection-id":"","channel-id":"","port-id":"transfer","order":"unordered","version":"ics20-1"},"dst":{"client-id":"","connection-id":"","channel-id":"","port-id":"transfer","order":"unordered","version":"ics20-1"}}' -H 'Content-Type: application/json' http://localhost:5183/paths/demo-path +$ curl -d '{"src":{"chain-id":"ibc-0","client-id":"","connection-id":"","channel-id":"","port-id":"transfer","order":"unordered","version":"ics20-1"},"dst":{"chain-id":"ibc-1","client-id":"","connection-id":"","channel-id":"","port-id":"transfer","order":"unordered","version":"ics20-1"}}' -H 'Content-Type: application/json' http://localhost:5183/paths/demo-path # Here we are creating path by sending data in format { - src-chain-id string - dst-chain-id string src PathEnd dst PathEnd } @@ -58,11 +56,9 @@ $ curl -d '{"src-chain-id":"ibc-0","dst-chain-id":"ibc-1","src":{"client-id":"", # We can also create path by sending file path instead of src and dst data in below format { file string - src-chain-id string - dst-chain-id string } -$ curl -d '{"file":"/root/go/src/github.com/cosmos/relayer/configs/akash/demo.json","src-chain-id":"ibc-0","dst-chain-id":"ibc-1"}' -H 'Content-Type: application/json' http://localhost:5183/paths/demo2 +$ curl -d '{"file":"/root/go/src/github.com/cosmos/relayer/configs/akash/demo.json"}' -H 'Content-Type: application/json' http://localhost:5183/paths/demo2 "path demo2 added successfully" diff --git a/docs/swagger-ui/favicon-16x16.png b/docs/swagger-ui/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0f7e13b0d9903d27a9129950b1dad362361504e4 GIT binary patch literal 445 zcmV;u0Yd(XP)rNm2=6wQ7&2F}_`h_PI>(9Fx!5<0%l6W{u0OQ#*rglqx3__&vD?|#%fhn*Mn&YY1i+JQHqPvZ34FR@_E%P@x zzTL;Bw#nJXWY}D7^bC>-bx{t|^|R6Oci&MKvov8Op~S=}R=h^p-=vZ0uqG@LE6tP7 n92{cY$^db6>&z__iT?Z#Z8BG|DVcT0DjiaEd>Z!7_`J}8! zKk_$1lGm$vJOY&DjT-(&VGn0;R`iN9=1aOuG`H}BlY>&R3KbGER zB2$7euhH;y1C_LTQex%L6khZpkjFn!ajOUK)f3JLz+I;CE@(N)T)CM4AWjfl-(04= zrsMQ)#NG6nr^Y7!6LA;iHXh?UOFE%hhy>7dl=;I$J>g0BH_r|_4ctEsXx z2sDIQnwa*rcK=*3XUC$D{I@}DTNs@GCb7dB2%%nV%jR){xktt;Ah09op7x@l5D6B2 z0uBdt0YmcN!o?lMpu9Io(1&B1s{TUu*a>2&>Iycx__fbDRM8PYtLt+#G*xSt(cn}K zt!~W2{`9r)xkh^xodLS&FbYw`x$t&Vhl?)#f&k-lZIs<`$gTj{^#^HewuJz(WnUZZ z{Ty_aE;^93bhc-^^k6ZM!^e~$q5!Zz`XPta{a@651gPzaFx$&%IHL6hx$mSeAa#n6 zLkyc-M zs$qhBZhCNE^aIEV)H_~^IeqSRnvo!21Qc`Z;S9!IqXl4K(RUImejotzuG65LVuGS# zcqp@OA8~ln^4c^VihUew)IOX^E9KMtvSvnZ| zC@rl{f(B*PA26aFR`|X!!I(7x_|kq{rlqwhCia+CfNbOg_yYt0bDCc4g#h#`3jpCd zNAhr%4#Ye{i>ni$fzY%r0IS%l3HHZ4tTjOi=JW-t_iG~)oC!2C!52Cc|TAPaH zJ}l%m9yPmA-4#lJea@uf$a`(1;={rL2f*8;7%icbF}e^_`X#ndU=SI0nIn8hXPXHS zSN4rbF}jl0HWx(_`q`-SRa9jP8Ab!}sThNkQ634k=qXBVM4`o{M>qrLJD ze*%D)S;wpxG$d%FcDf-6%zMqWA+gw!C1~T5+|ys$G3Ksm&x59Lyd?0l+LWSk6hc4~ z+yC>|4f;X3#cq3!)>#Mvb-^co7LMrzqWeKB$21I>tJgaGFwu6eB%&j?@d*8GAx~In zI1p-lXVKtcvY7;$TX~wjYw|QhB%q!npQES%F~%Aqz~pJB%rNu!xAj;>xZt75!VHju zfFy%B-`3;Qf<{h94~I62zcHv}D5pS-QCN`M8K1>jN9mpbrFk=5no8j!00000NkvXX Hu0mjfOavUK literal 0 HcmV?d00001 diff --git a/docs/swagger-ui/index.html b/docs/swagger-ui/index.html new file mode 100644 index 000000000..b2ee4dff3 --- /dev/null +++ b/docs/swagger-ui/index.html @@ -0,0 +1,60 @@ + + + + + + Swagger UI + + + + + + + +
+ + + + + + diff --git a/docs/swagger-ui/oauth2-redirect.html b/docs/swagger-ui/oauth2-redirect.html new file mode 100644 index 000000000..fb68399d2 --- /dev/null +++ b/docs/swagger-ui/oauth2-redirect.html @@ -0,0 +1,67 @@ + + + + + + diff --git a/docs/swagger-ui/swagger.yaml b/docs/swagger-ui/swagger.yaml new file mode 100644 index 000000000..548e041a1 --- /dev/null +++ b/docs/swagger-ui/swagger.yaml @@ -0,0 +1,2156 @@ +basePath: / +consumes: +- application/json +definitions: + Any: + properties: + type_url: + description: nolint + type: string + x-go-name: TypeUrl + value: + description: Must be a valid serialized protocol buffer of the above specified + type. + items: + format: uint8 + type: integer + type: array + x-go-name: Value + type: object + x-go-package: github.com/cosmos/cosmos-sdk/codec/types + BaseAccount: + description: |- + BaseAccount defines a base account type. It contains all the necessary fields + for basic account functionality. Any custom account type should extend this + type for additional functionality (e.g. vesting). + properties: + account_number: + format: uint64 + type: integer + x-go-name: AccountNumber + address: + type: string + x-go-name: Address + public_key: + $ref: '#/definitions/Any' + sequence: + format: uint64 + type: integer + x-go-name: Sequence + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/auth/types + BlockID: + description: BlockID + properties: + hash: + items: + format: uint8 + type: integer + type: array + x-go-name: Hash + part_set_header: + $ref: '#/definitions/PartSetHeader' + type: object + x-go-package: github.com/tendermint/tendermint/proto/tendermint/types + BlockIDFlag: + description: BlockIdFlag indicates which BlcokID the signature is for + format: int32 + type: integer + x-go-package: github.com/tendermint/tendermint/proto/tendermint/types + Chain: + description: Chain represents the necessary data for connecting to and indentifying + a chain and its counterparites + properties: + account-prefix: + type: string + x-go-name: AccountPrefix + chain-id: + type: string + x-go-name: ChainID + gas-adjustment: + format: double + type: number + x-go-name: GasAdjustment + gas-prices: + type: string + x-go-name: GasPrices + key: + type: string + x-go-name: Key + rpc-addr: + type: string + x-go-name: RPCAddr + trusting-period: + type: string + x-go-name: TrustingPeriod + type: object + x-go-package: github.com/cosmos/relayer/relayer + Chains: + description: Chains is a collection of Chain + items: + $ref: '#/definitions/Chain' + type: array + x-go-package: github.com/cosmos/relayer/relayer + Channel: + description: |- + Channel defines pipeline for exactly-once packet delivery between specific + modules on separate blockchains, which has at least one end capable of + sending packets and one end capable of receiving packets. + properties: + connection_hops: + description: |- + list of connection identifiers, in order, along which packets sent on + this channel will travel + items: + type: string + type: array + x-go-name: ConnectionHops + counterparty: + $ref: '#/definitions/Counterparty' + ordering: + $ref: '#/definitions/Order' + state: + $ref: '#/definitions/State' + version: + description: opaque channel version, which is agreed upon during the handshake + type: string + x-go-name: Version + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types + Coin: + description: |- + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. + properties: + amount: + $ref: '#/definitions/Int' + denom: + type: string + x-go-name: Denom + title: Coin defines a token with a denomination and an amount. + type: object + x-go-package: github.com/cosmos/cosmos-sdk/types + Coins: + description: Coins is a set of Coin, one per currency + items: + $ref: '#/definitions/Coin' + type: array + x-go-package: github.com/cosmos/cosmos-sdk/types + Commit: + properties: + block_id: + $ref: '#/definitions/BlockID' + height: + format: int64 + type: integer + x-go-name: Height + round: + format: int32 + type: integer + x-go-name: Round + signatures: + items: + $ref: '#/definitions/CommitSig' + type: array + x-go-name: Signatures + title: Commit contains the evidence that a block was committed by a set of validators. + type: object + x-go-package: github.com/tendermint/tendermint/proto/tendermint/types + CommitSig: + properties: + block_id_flag: + $ref: '#/definitions/BlockIDFlag' + signature: + items: + format: uint8 + type: integer + type: array + x-go-name: Signature + timestamp: + format: date-time + type: string + x-go-name: Timestamp + validator_address: + items: + format: uint8 + type: integer + type: array + x-go-name: ValidatorAddress + title: CommitSig is a part of the Vote included in a Commit. + type: object + x-go-package: github.com/tendermint/tendermint/proto/tendermint/types + Config: + description: Config represents the config file for the relayer + properties: + chains: + $ref: '#/definitions/Chains' + global: + $ref: '#/definitions/GlobalConfig' + paths: + $ref: '#/definitions/Paths' + type: object + x-go-package: github.com/cosmos/relayer/cmd + ConnectionEnd: + description: |- + ConnectionEnd defines a stateful object on a chain connected to another + separate one. + NOTE: there must only be 2 defined ConnectionEnds to establish + a connection between two chains. + properties: + client_id: + description: client associated with this connection. + type: string + x-go-name: ClientId + counterparty: + $ref: '#/definitions/Counterparty' + delay_period: + description: |- + delay period that must pass before a consensus state can be used for packet-verification + NOTE: delay period logic is only implemented by some clients. + format: uint64 + type: integer + x-go-name: DelayPeriod + state: + $ref: '#/definitions/State' + versions: + description: |- + IBC version which can be utilised to determine encodings or protocols for + channels or packets utilising this connection. + items: + $ref: '#/definitions/Version' + type: array + x-go-name: Versions + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types + ConsensusState: + properties: + next_validators_hash: + $ref: '#/definitions/HexBytes' + root: + $ref: '#/definitions/MerkleRoot' + timestamp: + description: |- + timestamp that corresponds to the block height in which the ConsensusState + was stored. + format: date-time + type: string + x-go-name: Timestamp + title: ConsensusState defines the consensus state from Tendermint. + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types + Counterparty: + description: Counterparty defines a channel end counterparty + properties: + channel_id: + description: channel end on the counterparty chain + type: string + x-go-name: ChannelId + port_id: + description: port on the counterparty chain which owns the other end of the + channel. + type: string + x-go-name: PortId + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types + DenomTrace: + description: |- + DenomTrace contains the base denomination for ICS20 fungible tokens and the + source tracing information path. + properties: + base_denom: + description: base denomination of the relayed fungible token. + type: string + x-go-name: BaseDenom + path: + description: |- + path defines the chain of port/channel identifiers used for tracing the + source of the fungible token. + type: string + x-go-name: Path + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types + Event: + description: |- + Event allows application developers to attach additional information to + ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx. + Later, transactions may be queried using these events. + properties: + attributes: + items: + $ref: '#/definitions/EventAttribute' + type: array + x-go-name: Attributes + type: + type: string + x-go-name: Type + type: object + x-go-package: github.com/tendermint/tendermint/abci/types + EventAttribute: + properties: + index: + type: boolean + x-go-name: Index + key: + items: + format: uint8 + type: integer + type: array + x-go-name: Key + value: + items: + format: uint8 + type: integer + type: array + x-go-name: Value + title: EventAttribute is a single key-value pair, associated with an event. + type: object + x-go-package: github.com/tendermint/tendermint/abci/types + GlobalConfig: + description: GlobalConfig describes any global relayer settings + properties: + api-listen-addr: + type: string + x-go-name: APIListenPort + light-cache-size: + format: int64 + type: integer + x-go-name: LightCacheSize + timeout: + type: string + x-go-name: Timeout + type: object + x-go-package: github.com/cosmos/relayer/cmd + Header: + description: |- + It encapsulates all the information necessary to update from a trusted + Tendermint ConsensusState. The inclusion of TrustedHeight and + TrustedValidators allows this update to process correctly, so long as the + ConsensusState for the TrustedHeight exists, this removes race conditions + among relayers The SignedHeader and ValidatorSet are the new untrusted update + fields for the client. The TrustedHeight is the height of a stored + ConsensusState on the client that will be used to verify the new untrusted + header. The Trusted ConsensusState must be within the unbonding period of + current time in order to correctly verify, and the TrustedValidators must + hash to TrustedConsensusState.NextValidatorsHash since that is the last + trusted validator set at the TrustedHeight. + properties: + commit: + $ref: '#/definitions/Commit' + header: + $ref: '#/definitions/Header' + trusted_height: + $ref: '#/definitions/Height' + trusted_validators: + $ref: '#/definitions/ValidatorSet' + validator_set: + $ref: '#/definitions/ValidatorSet' + title: Header defines the Tendermint client consensus Header. + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types + Height: + description: |- + Normally the RevisionHeight is incremented at each height while keeping RevisionNumber + the same. However some consensus algorithms may choose to reset the + height in certain conditions e.g. hard forks, state-machine breaking changes + In these cases, the RevisionNumber is incremented so that height continues to + be monitonically increasing even as the RevisionHeight gets reset + properties: + revision_height: + description: the height within the given revision + format: uint64 + type: integer + x-go-name: RevisionHeight + revision_number: + description: the revision that the client is currently on + format: uint64 + type: integer + x-go-name: RevisionNumber + title: |- + Height is a monotonically increasing data type + that can be compared against another Height for the purposes of updating and + freezing clients + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types + HexBytes: + items: + format: uint8 + type: integer + title: The main purpose of HexBytes is to enable HEX-encoding for json/encoding. + type: array + x-go-package: github.com/tendermint/tendermint/libs/bytes + IdentifiedChannel: + description: |- + IdentifiedChannel defines a channel with additional port and channel + identifier fields. + properties: + channel_id: + description: channel identifier + type: string + x-go-name: ChannelId + connection_hops: + description: |- + list of connection identifiers, in order, along which packets sent on + this channel will travel + items: + type: string + type: array + x-go-name: ConnectionHops + counterparty: + $ref: '#/definitions/Counterparty' + ordering: + $ref: '#/definitions/Order' + port_id: + description: port identifier + type: string + x-go-name: PortId + state: + $ref: '#/definitions/State' + version: + description: opaque channel version, which is agreed upon during the handshake + type: string + x-go-name: Version + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types + IdentifiedClientState: + description: |- + IdentifiedClientState defines a client state with an additional client + identifier field. + properties: + client_id: + description: client identifier + type: string + x-go-name: ClientId + client_state: + $ref: '#/definitions/Any' + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types + IdentifiedClientStates: + description: IdentifiedClientStates defines a slice of ClientConsensusStates that + supports the sort interface + items: + $ref: '#/definitions/IdentifiedClientState' + type: array + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types + IdentifiedConnection: + description: |- + IdentifiedConnection defines a connection with additional connection + identifier field. + properties: + client_id: + description: client associated with this connection. + type: string + x-go-name: ClientId + counterparty: + $ref: '#/definitions/Counterparty' + delay_period: + description: delay period associated with this connection. + format: uint64 + type: integer + x-go-name: DelayPeriod + id: + description: connection identifier. + type: string + x-go-name: Id + state: + $ref: '#/definitions/State' + versions: + description: |- + IBC version which can be utilised to determine encodings or protocols for + channels or packets utilising this connection + items: + $ref: '#/definitions/Version' + type: array + x-go-name: Versions + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types + Int: + description: |- + Int wraps integer with 256 bit range bound + Checks overflow, underflow and division by zero + Exists in range from -(2^maxBitLen-1) to 2^maxBitLen-1 + type: object + x-go-package: github.com/cosmos/cosmos-sdk/types + KeyOutput: + description: KeyOutput contains mnemonic and address of key + properties: + address: + type: string + x-go-name: Address + mnemonic: + type: string + x-go-name: Mnemonic + type: object + x-go-package: github.com/cosmos/relayer/helpers + MerklePrefix: + description: |- + The constructed key from the Path and the key will be append(Path.KeyPath, + append(Path.KeyPrefix, key...)) + properties: + key_prefix: + items: + format: uint8 + type: integer + type: array + x-go-name: KeyPrefix + title: MerklePrefix is merkle path prefixed to the key. + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types + MerkleRoot: + description: In the Cosmos SDK, the AppHash of a block header becomes the root. + properties: + hash: + items: + format: uint8 + type: integer + type: array + x-go-name: Hash + title: MerkleRoot defines a merkle root hash. + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types + Order: + description: Order defines if a channel is ORDERED or UNORDERED + format: int32 + type: integer + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types + PageResponse: + description: |- + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + properties: + next_key: + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + items: + format: uint8 + type: integer + type: array + x-go-name: NextKey + total: + description: |- + total is total number of results available if PageRequest.count_total + was set, its value is undefined otherwise + format: uint64 + type: integer + x-go-name: Total + title: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. + type: object + x-go-package: github.com/cosmos/cosmos-sdk/types/query + PartSetHeader: + description: PartsetHeader + properties: + hash: + items: + format: uint8 + type: integer + type: array + x-go-name: Hash + total: + format: uint32 + type: integer + x-go-name: Total + type: object + x-go-package: github.com/tendermint/tendermint/proto/tendermint/types + Path: + description: |- + Path represents a pair of chains and the identifiers needed to + relay over them + properties: + dst: + $ref: '#/definitions/PathEnd' + src: + $ref: '#/definitions/PathEnd' + strategy: + $ref: '#/definitions/StrategyCfg' + type: object + x-go-package: github.com/cosmos/relayer/relayer + PathEnd: + description: |- + PathEnd represents the local connection identifers for a relay path + The path is set on the chain before performing operations + properties: + chain-id: + type: string + x-go-name: ChainID + channel-id: + type: string + x-go-name: ChannelID + client-id: + type: string + x-go-name: ClientID + connection-id: + type: string + x-go-name: ConnectionID + order: + type: string + x-go-name: Order + port-id: + type: string + x-go-name: PortID + version: + type: string + x-go-name: Version + type: object + x-go-package: github.com/cosmos/relayer/relayer + PathStatus: + description: PathStatus holds the status of the primitives in the path + properties: + chains: + type: boolean + x-go-name: Chains + channel: + type: boolean + x-go-name: Channel + clients: + type: boolean + x-go-name: Clients + connection: + type: boolean + x-go-name: Connection + type: object + x-go-package: github.com/cosmos/relayer/relayer + PathWithStatus: + description: PathWithStatus is used for showing the status of the path + properties: + chains: + $ref: '#/definitions/Path' + status: + $ref: '#/definitions/PathStatus' + type: object + x-go-package: github.com/cosmos/relayer/relayer + Paths: + additionalProperties: + $ref: '#/definitions/Path' + description: Paths represent connection paths between chains + type: object + x-go-package: github.com/cosmos/relayer/relayer + Proof: + description: |- + NOTE: The convention for proofs is to include leaf hashes but to + exclude the root hash. + This convention is implemented across IAVL range proofs as well. + Keep this consistent unless there's a very good reason to change + everything. This also affects the generalized proof system as + well. + properties: + aunts: + items: + items: + format: uint8 + type: integer + type: array + type: array + x-go-name: Aunts + index: + format: int64 + type: integer + x-go-name: Index + leaf_hash: + items: + format: uint8 + type: integer + type: array + x-go-name: LeafHash + total: + format: int64 + type: integer + x-go-name: Total + title: Proof represents a Merkle proof. + type: object + x-go-package: github.com/tendermint/tendermint/crypto/merkle + PublicKey: + description: PublicKey defines the keys available for use with Tendermint Validators + properties: + Sum: + $ref: '#/definitions/isPublicKey_Sum' + type: object + x-go-package: github.com/tendermint/tendermint/proto/tendermint/crypto + QueryChannelResponse: + description: |- + Besides the Channel end, it includes a proof and the height from which the + proof was retrieved. + properties: + channel: + $ref: '#/definitions/Channel' + proof: + description: merkle proof of existence + items: + format: uint8 + type: integer + type: array + x-go-name: Proof + proof_height: + $ref: '#/definitions/Height' + title: QueryChannelResponse is the response type for the Query/Channel RPC method. + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types + QueryChannelsResponse: + properties: + channels: + description: list of stored channels of the chain. + items: + $ref: '#/definitions/IdentifiedChannel' + type: array + x-go-name: Channels + height: + $ref: '#/definitions/Height' + pagination: + $ref: '#/definitions/PageResponse' + title: QueryChannelsResponse is the response type for the Query/Channels RPC method. + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types + QueryClientConnectionsResponse: + description: |- + QueryClientConnectionsResponse is the response type for the + Query/ClientConnections RPC method + properties: + connection_paths: + description: slice of all the connection paths associated with a client. + items: + type: string + type: array + x-go-name: ConnectionPaths + proof: + description: merkle proof of existence + items: + format: uint8 + type: integer + type: array + x-go-name: Proof + proof_height: + $ref: '#/definitions/Height' + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types + QueryClientStateResponse: + description: |- + QueryClientStateResponse is the response type for the Query/ClientState RPC + method. Besides the client state, it includes a proof and the height from + which the proof was retrieved. + properties: + client_state: + $ref: '#/definitions/Any' + proof: + description: merkle proof of existence + items: + format: uint8 + type: integer + type: array + x-go-name: Proof + proof_height: + $ref: '#/definitions/Height' + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types + QueryClientStatesResponse: + description: |- + QueryClientStatesResponse is the response type for the Query/ClientStates RPC + method. + properties: + client_states: + $ref: '#/definitions/IdentifiedClientStates' + pagination: + $ref: '#/definitions/PageResponse' + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types + QueryConnectionChannelsResponse: + description: |- + QueryConnectionChannelsResponse is the Response type for the + Query/QueryConnectionChannels RPC method + properties: + channels: + description: list of channels associated with a connection. + items: + $ref: '#/definitions/IdentifiedChannel' + type: array + x-go-name: Channels + height: + $ref: '#/definitions/Height' + pagination: + $ref: '#/definitions/PageResponse' + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types + QueryConnectionResponse: + description: |- + QueryConnectionResponse is the response type for the Query/Connection RPC + method. Besides the connection end, it includes a proof and the height from + which the proof was retrieved. + properties: + connection: + $ref: '#/definitions/ConnectionEnd' + proof: + description: merkle proof of existence + items: + format: uint8 + type: integer + type: array + x-go-name: Proof + proof_height: + $ref: '#/definitions/Height' + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types + QueryConnectionsResponse: + description: |- + QueryConnectionsResponse is the response type for the Query/Connections RPC + method. + properties: + connections: + description: list of stored connections of the chain. + items: + $ref: '#/definitions/IdentifiedConnection' + type: array + x-go-name: Connections + height: + $ref: '#/definitions/Height' + pagination: + $ref: '#/definitions/PageResponse' + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types + QueryDenomTracesResponse: + description: |- + QueryConnectionsResponse is the response type for the Query/DenomTraces RPC + method. + properties: + denom_traces: + $ref: '#/definitions/Traces' + pagination: + $ref: '#/definitions/PageResponse' + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types + ResponseDeliverTx: + properties: + code: + format: uint32 + type: integer + x-go-name: Code + codespace: + type: string + x-go-name: Codespace + data: + items: + format: uint8 + type: integer + type: array + x-go-name: Data + events: + items: + $ref: '#/definitions/Event' + type: array + x-go-name: Events + gas_used: + format: int64 + type: integer + x-go-name: GasUsed + gas_wanted: + format: int64 + type: integer + x-go-name: GasWanted + info: + type: string + x-go-name: Info + log: + type: string + x-go-name: Log + type: object + x-go-package: github.com/tendermint/tendermint/abci/types + ResultTx: + description: Result of querying for a tx + properties: + hash: + $ref: '#/definitions/HexBytes' + height: + format: int64 + type: integer + x-go-name: Height + index: + format: uint32 + type: integer + x-go-name: Index + proof: + $ref: '#/definitions/TxProof' + tx: + $ref: '#/definitions/Tx' + tx_result: + $ref: '#/definitions/ResponseDeliverTx' + type: object + x-go-package: github.com/tendermint/tendermint/rpc/core/types + State: + description: CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + format: int32 + title: 'State defines if a channel is in one of the following states:' + type: integer + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types + StrategyCfg: + description: StrategyCfg defines which relaying strategy to take for a given path + properties: + type: + type: string + x-go-name: Type + type: object + x-go-package: github.com/cosmos/relayer/relayer + Traces: + items: + $ref: '#/definitions/DenomTrace' + title: Traces defines a wrapper type for a slice of DenomTrace. + type: array + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types + Tx: + description: |- + NOTE: Tx has no types at this level, so when wire encoded it's just length-prefixed. + Might we want types here ? + items: + format: uint8 + type: integer + title: Tx is an arbitrary byte array. + type: array + x-go-package: github.com/tendermint/tendermint/types + TxProof: + properties: + data: + $ref: '#/definitions/Tx' + proof: + $ref: '#/definitions/Proof' + root_hash: + $ref: '#/definitions/HexBytes' + title: TxProof represents a Merkle proof of the presence of a transaction in the + Merkle tree. + type: object + x-go-package: github.com/tendermint/tendermint/types + Validator: + properties: + address: + items: + format: uint8 + type: integer + type: array + x-go-name: Address + proposer_priority: + format: int64 + type: integer + x-go-name: ProposerPriority + pub_key: + $ref: '#/definitions/PublicKey' + voting_power: + format: int64 + type: integer + x-go-name: VotingPower + type: object + x-go-package: github.com/tendermint/tendermint/proto/tendermint/types + ValidatorSet: + properties: + proposer: + $ref: '#/definitions/Validator' + total_voting_power: + format: int64 + type: integer + x-go-name: TotalVotingPower + validators: + items: + $ref: '#/definitions/Validator' + type: array + x-go-name: Validators + type: object + x-go-package: github.com/tendermint/tendermint/proto/tendermint/types + Version: + description: |- + Version defines the versioning scheme used to negotiate the IBC verison in + the connection handshake. + properties: + features: + description: list of features compatible with the specified identifier + items: + type: string + type: array + x-go-name: Features + identifier: + description: unique version identifier + type: string + x-go-name: Identifier + type: object + x-go-package: github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types + addChainRequest: + properties: + account-prefix: + type: string + x-go-name: AccountPrefix + file: + type: string + x-go-name: FilePath + gas-adjustment: + type: string + x-go-name: GasAdjustment + gas-prices: + type: string + x-go-name: GasPrices + key: + type: string + x-go-name: Key + rpc-addr: + type: string + x-go-name: RPCAddr + trusting-period: + type: string + x-go-name: TrustingPeriod + url: + type: string + x-go-name: URL + type: object + x-go-package: github.com/cosmos/relayer/cmd + chainStatusResponse: + properties: + balance: + type: boolean + x-go-name: Balance + key: + type: boolean + x-go-name: Key + light: + type: boolean + x-go-name: Light + path: + type: boolean + x-go-name: Path + type: object + x-go-package: github.com/cosmos/relayer/cmd + editChainRequest: + properties: + key: + type: string + x-go-name: Key + value: + type: string + x-go-name: Value + type: object + x-go-package: github.com/cosmos/relayer/cmd + isPublicKey_Sum: + properties: + Size: + format: int64 + type: integer + type: object + x-go-package: github.com/tendermint/tendermint/proto/tendermint/crypto + keyResponse: + properties: + address: + type: string + x-go-name: Address + name: + type: string + x-go-name: Name + type: object + x-go-package: github.com/cosmos/relayer/cmd + postLightRequest: + properties: + force: + type: boolean + x-go-name: Force + hash: + type: string + x-go-name: Hash + height: + format: int64 + type: integer + x-go-name: Height + type: object + x-go-package: github.com/cosmos/relayer/cmd + postPathRequest: + properties: + dst: + $ref: '#/definitions/PathEnd' + file: + type: string + x-go-name: FilePath + src: + $ref: '#/definitions/PathEnd' + type: object + x-go-package: github.com/cosmos/relayer/cmd + restoreKeyRequest: + properties: + mnemonic: + type: string + x-go-name: Mnemonic + type: object + x-go-package: github.com/cosmos/relayer/cmd + txsRequest: + properties: + events: + items: + type: string + type: array + x-go-name: Events + type: object + x-go-package: github.com/cosmos/relayer/cmd + versionInfo: + properties: + commit: + type: string + x-go-name: Commit + cosmos-sdk: + type: string + x-go-name: CosmosSDK + go: + type: string + x-go-name: Go + version: + type: string + x-go-name: Version + type: object + x-go-package: github.com/cosmos/relayer/cmd +host: localhost:5183 +info: + description: A REST interface for state queries. + title: Relayer Rest Server. + version: 1.0.0 +paths: + /chains: + get: + operationId: getChains + responses: + "200": + $ref: '#/responses/getChainsResponse' + summary: Get chains list. + tags: + - Chains + /chains/{name}: + delete: + operationId: deleteChain + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + responses: + "200": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Delete Chain. + tags: + - Chains + get: + operationId: getChain + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + responses: + "200": + description: Returns chain details + schema: + $ref: '#/definitions/getChainResponse' + "400": + $ref: '#/responses/errorResponse' + summary: Get single chain details. + tags: + - Chains + post: + description: file and url parameters in body are optional and can't use both + at once. + operationId: addChain + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + - in: body + name: body + required: true + schema: + $ref: '#/definitions/addChainRequest' + x-go-name: Body + responses: + "201": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Add a chain. + tags: + - Chains + put: + operationId: updateChain + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + - in: body + name: body + required: true + schema: + $ref: '#/definitions/editChainRequest' + x-go-name: Body + responses: + "200": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Update chain config values. + tags: + - Chains + /chains/{name}/status: + get: + operationId: getChainStatus + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + responses: + "200": + $ref: '#/responses/chainStatusRes' + "400": + $ref: '#/responses/errorResponse' + summary: Get status of a chain. + tags: + - Chains + /config: + get: + operationId: config + responses: + "200": + $ref: '#/responses/configResponse' + summary: Get config. + tags: + - Config + /keys/{chain-id}: + get: + operationId: getKeys + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + responses: + "200": + $ref: '#/responses/getKeysResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Get keys list of a chain. + tags: + - Keys + /keys/{chain-id}/{name}: + delete: + operationId: deleteKey + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + responses: + "200": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "404": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Delete key in a chain. + tags: + - Keys + get: + operationId: getKey + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + responses: + "200": + $ref: '#/responses/getKeyResponse' + "400": + $ref: '#/responses/errorResponse' + "404": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Get details of a key in a chain. + tags: + - Keys + post: + description: coin-type is a query parameter (optional) + operationId: addKey + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: coin-type + type: integer + x-go-name: CoinType + responses: + "201": + $ref: '#/responses/keyCreatedResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Add a key in a chain. + tags: + - Keys + /keys/{chain-id}/{name}/restore: + post: + description: coin-type is a query parameter (optional) + operationId: restoreKey + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: coin-type + type: integer + x-go-name: CoinType + - in: body + name: body + required: true + schema: + $ref: '#/definitions/restoreKeyRequest' + x-go-name: Body + responses: + "200": + $ref: '#/responses/keyCreatedResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Restore a key using mnemonic. + tags: + - Keys + /light/{chain-id}: + delete: + operationId: deleteLight + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + responses: + "200": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Delete light header of a chain. + tags: + - Light + post: + description: |- + force is optional and if given, it will be considered first, + height and hash can be used instead of force and need to send both values. + operationId: initLight + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - in: body + name: body + required: true + schema: + $ref: '#/definitions/postLightRequest' + x-go-name: Body + responses: + "201": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Init light header for a chain. + tags: + - Light + put: + operationId: updateLight + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + responses: + "200": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Update light header of a chain. + tags: + - Light + /light/{chain-id}/header: + get: + operationId: getLightHeader + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: height + type: integer + x-go-name: Height + responses: + "200": + $ref: '#/responses/headerResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Get light header of a chain. + tags: + - Light + /light/{chain-id}/height: + get: + operationId: getLightHeight + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + responses: + "200": + description: Returns light height + schema: + $ref: '#/definitions/getLightHeightResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Get light height of a chain. + tags: + - Light + /paths: + get: + operationId: getPaths + responses: + "200": + $ref: '#/responses/getPathsResponse' + summary: Get paths list. + tags: + - Paths + /paths/{name}: + delete: + operationId: deletePath + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + responses: + "200": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Delete Path. + tags: + - Paths + get: + operationId: getPath + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + responses: + "200": + $ref: '#/responses/getPathResponse' + "400": + $ref: '#/responses/errorResponse' + summary: Get single path details. + tags: + - Paths + post: + description: file parameter in body is optional and if given, it will considered + first. + operationId: addPath + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + - in: body + name: body + required: true + schema: + $ref: '#/definitions/postPathRequest' + x-go-name: Body + responses: + "201": + description: Returns success string + schema: + $ref: '#/definitions/stringSuccessResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Add a path. + tags: + - Paths + /paths/{name}/status: + get: + operationId: getPathStatus + parameters: + - in: path + name: name + required: true + type: string + x-go-name: Name + responses: + "200": + $ref: '#/responses/pathStatusRes' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Get status of a path. + tags: + - Paths + /query/{chain-id}/account/{address}: + get: + operationId: queryAccount + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - in: path + name: address + required: true + type: string + x-go-name: Address + responses: + "200": + description: Output format might change if address queried is Module Account + schema: + $ref: '#/definitions/queryAccountResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query account of a chain. + tags: + - Query + /query/{chain-id}/balance/{address}: + get: + operationId: queryBalance + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - in: path + name: address + required: true + type: string + x-go-name: Address + - in: query + name: ibc-denoms + type: boolean + x-go-name: IBCDenoms + responses: + "200": + $ref: '#/responses/queryBalanceResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query balance of a chain. + tags: + - Query + /query/{chain-id}/channels: + get: + operationId: queryChans + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: uint64 + in: query + name: offset + type: integer + x-go-name: Offset + - format: uint64 + in: query + name: limit + type: integer + x-go-name: Limit + responses: + "200": + $ref: '#/responses/queryChansResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query channels of a chain. + tags: + - Query + /query/{chain-id}/channels/{chan-id}/{port-id}: + get: + operationId: queryChan + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: height + type: integer + x-go-name: Height + - in: path + name: chan-id + required: true + type: string + x-go-name: ChannelID + - in: path + name: port-id + required: true + type: string + x-go-name: PortID + responses: + "200": + $ref: '#/responses/queryChanResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query channel by channelID and portID. + tags: + - Query + /query/{chain-id}/channels/connection/{conn-id}: + get: + operationId: queryConnChans + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: uint64 + in: query + name: offset + type: integer + x-go-name: Offset + - format: uint64 + in: query + name: limit + type: integer + x-go-name: Limit + - in: path + name: conn-id + required: true + type: string + x-go-name: ConnectionID + responses: + "200": + $ref: '#/responses/queryConnChansResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query channels of a connection in a chain. + tags: + - Query + /query/{chain-id}/clients: + get: + operationId: queryClients + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: uint64 + in: query + name: offset + type: integer + x-go-name: Offset + - format: uint64 + in: query + name: limit + type: integer + x-go-name: Limit + responses: + "200": + $ref: '#/responses/queryClientsResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query clients of a chain. + tags: + - Query + /query/{chain-id}/clients/{client-id}: + get: + operationId: queryClient + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: height + type: integer + x-go-name: Height + - in: path + name: client-id + required: true + type: string + x-go-name: ClientID + responses: + "200": + $ref: '#/responses/queryClientResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query client by clientID. + tags: + - Query + /query/{chain-id}/connections: + get: + operationId: queryConns + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: uint64 + in: query + name: offset + type: integer + x-go-name: Offset + - format: uint64 + in: query + name: limit + type: integer + x-go-name: Limit + responses: + "200": + $ref: '#/responses/queryConnsResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query connections of a chain. + tags: + - Query + /query/{chain-id}/connections/{conn-id}: + get: + operationId: queryConn + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: height + type: integer + x-go-name: Height + - in: path + name: conn-id + required: true + type: string + x-go-name: ConnectionID + responses: + "200": + $ref: '#/responses/queryConnResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query connection by connectionID. + tags: + - Query + /query/{chain-id}/connections/client/{client-id}: + get: + operationId: queryClientConns + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: height + type: integer + x-go-name: Height + responses: + "200": + $ref: '#/responses/queryClientConnsResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query connections of a client in a chain. + tags: + - Query + /query/{chain-id}/header: + get: + operationId: queryHeader + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: height + type: integer + x-go-name: Height + responses: + "200": + $ref: '#/responses/headerResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query header of a chain. + tags: + - Query + /query/{chain-id}/ibc-denoms: + get: + operationId: queryIBCDenoms + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + responses: + "200": + $ref: '#/responses/queryIBCDenomsResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query ibc-denoms of a chain. + tags: + - Query + /query/{chain-id}/node-state: + get: + operationId: queryNodeState + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + responses: + "200": + $ref: '#/responses/nodeStateResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query node state of a chain. + tags: + - Query + /query/{chain-id}/tx/{hash}: + get: + operationId: queryTx + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - in: path + name: hash + required: true + type: string + x-go-name: Hash + responses: + "200": + $ref: '#/responses/txResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query Tx details by hash. + tags: + - Query + /query/{chain-id}/txs: + post: + operationId: queryTxs + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: uint64 + in: query + name: offset + type: integer + x-go-name: Offset + - format: uint64 + in: query + name: limit + type: integer + x-go-name: Limit + - in: body + name: body + schema: + $ref: '#/definitions/txsRequest' + x-go-name: Body + responses: + "200": + $ref: '#/responses/txsResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query Txs using events. + tags: + - Query + /query/{chain-id}/valset: + get: + operationId: queryValSet + parameters: + - in: path + name: chain-id + required: true + type: string + x-go-name: ChainID + - format: int64 + in: query + name: height + type: integer + x-go-name: Height + responses: + "200": + $ref: '#/responses/valSetResponse' + "400": + $ref: '#/responses/errorResponse' + "500": + $ref: '#/responses/errorResponse' + summary: Query node state of a chain. + tags: + - Query + /version: + get: + operationId: version + responses: + "200": + $ref: '#/responses/versionResponse' + summary: Get version. + tags: + - Version +produces: +- application/json +responses: + chainStatusRes: + description: "" + schema: + $ref: '#/definitions/chainStatusResponse' + configResponse: + description: "" + schema: + $ref: '#/definitions/Config' + errorResponse: + description: "" + schema: + properties: + err: + type: string + x-go-name: Err + type: object + getChainResponse: + description: "" + schema: + $ref: '#/definitions/Chain' + getChainsResponse: + description: "" + schema: + $ref: '#/definitions/Chains' + getKeyResponse: + description: "" + schema: + $ref: '#/definitions/keyResponse' + getKeysResponse: + description: "" + schema: + items: + $ref: '#/definitions/keyResponse' + type: array + getLightHeightResponse: + description: "" + getPathResponse: + description: "" + schema: + $ref: '#/definitions/Path' + getPathsResponse: + description: "" + schema: + $ref: '#/definitions/Paths' + headerResponse: + description: "" + schema: + $ref: '#/definitions/Header' + keyCreatedResponse: + description: "" + schema: + $ref: '#/definitions/KeyOutput' + nodeStateResponse: + description: "" + schema: + $ref: '#/definitions/ConsensusState' + pathStatusRes: + description: "" + schema: + $ref: '#/definitions/PathWithStatus' + queryAccountResponse: + description: "" + schema: + properties: + account: + $ref: '#/definitions/BaseAccount' + type: object + queryBalanceResponse: + description: "" + schema: + $ref: '#/definitions/Coins' + queryChanResponse: + description: "" + schema: + $ref: '#/definitions/QueryChannelResponse' + queryChansResponse: + description: "" + schema: + $ref: '#/definitions/QueryChannelsResponse' + queryClientConnsResponse: + description: "" + schema: + $ref: '#/definitions/QueryClientConnectionsResponse' + queryClientResponse: + description: "" + schema: + $ref: '#/definitions/QueryClientStateResponse' + queryClientsResponse: + description: "" + schema: + $ref: '#/definitions/QueryClientStatesResponse' + queryConnChansResponse: + description: "" + schema: + $ref: '#/definitions/QueryConnectionChannelsResponse' + queryConnResponse: + description: "" + schema: + $ref: '#/definitions/QueryConnectionResponse' + queryConnsResponse: + description: "" + schema: + $ref: '#/definitions/QueryConnectionsResponse' + queryIBCDenomsResponse: + description: "" + schema: + $ref: '#/definitions/QueryDenomTracesResponse' + stringSuccessResponse: + description: "" + txResponse: + description: "" + schema: + $ref: '#/definitions/ResultTx' + txsResponse: + description: "" + schema: + items: + $ref: '#/definitions/ResultTx' + type: array + valSetResponse: + description: "" + schema: + $ref: '#/definitions/ValidatorSet' + versionResponse: + description: "" + schema: + $ref: '#/definitions/versionInfo' +schemes: +- http +swagger: "2.0" From 6dcc55baa2e00975a3daf655b9879d2d98916339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Mon, 8 Mar 2021 16:12:07 +0100 Subject: [PATCH 12/14] add a light client database lock (#447) Add a lock to prevent multiple processes from attempting to access the light client database at the same time. This typically resulted in unnecessary errors or even panics --- relayer/tm-light-client.go | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/relayer/tm-light-client.go b/relayer/tm-light-client.go index d118af4bd..86eceee9c 100644 --- a/relayer/tm-light-client.go +++ b/relayer/tm-light-client.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "path/filepath" + "sync" "time" retry "github.com/avast/retry-go" @@ -23,11 +24,17 @@ import ( "golang.org/x/sync/errgroup" ) -// NOTE: currently we are discarding the very noisy light client logs -// it would be nice if we could add a setting the chain or otherwise -// that allowed users to enable light client logging. (maybe as a hidden prop -// on the Chain struct that users could pass in the config??) -var logger = light.Logger(log.NewTMLogger(log.NewSyncWriter(ioutil.Discard))) +var ( + // NOTE: currently we are discarding the very noisy light client logs + // it would be nice if we could add a setting the chain or otherwise + // that allowed users to enable light client logging. (maybe as a hidden prop + // on the Chain struct that users could pass in the config??) + logger = light.Logger(log.NewTMLogger(log.NewSyncWriter(ioutil.Discard))) + + // a lock to prevent two processes from trying to access the light client + // database at the same time resulting in errors and panics. + lightDBMutex sync.Mutex +) func lightError(err error) error { return fmt.Errorf("light client: %w", err) } @@ -171,18 +178,19 @@ func (c *Chain) LightClient(db dbm.DB) (*light.Client, error) { // NewLightDB returns a new instance of the lightclient database connection // CONTRACT: must close the database connection when done with it (defer df()) func (c *Chain) NewLightDB() (db *dbm.GoLevelDB, df func(), err error) { - if err := retry.Do(func() error { - db, err = dbm.NewGoLevelDB(c.ChainID, lightDir(c.HomePath)) - if err != nil { - return fmt.Errorf("can't open light client database: %w", err) - } - return nil - }, rtyAtt, rtyDel, rtyErr); err != nil { - return nil, nil, err + // a lock is used to prevent error messages or panics from two processes + // trying to simultanenously use the light client + lightDBMutex.Lock() + + db, err = dbm.NewGoLevelDB(c.ChainID, lightDir(c.HomePath)) + if err != nil { + lightDBMutex.Unlock() + return nil, nil, fmt.Errorf("can't open light client database: %w", err) } df = func() { err := db.Close() + lightDBMutex.Unlock() if err != nil { panic(err) } From cf49cb43d3e3571c87d4b9d1aaa872ed74b220ef Mon Sep 17 00:00:00 2001 From: Mark | Microtick <409166+mark-microtick@users.noreply.github.com> Date: Mon, 8 Mar 2021 08:52:13 -0700 Subject: [PATCH 13/14] Close database connection even if second error triggers (#449) Co-authored-by: Mark --- relayer/tm-light-client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relayer/tm-light-client.go b/relayer/tm-light-client.go index 86eceee9c..ac0f8660e 100644 --- a/relayer/tm-light-client.go +++ b/relayer/tm-light-client.go @@ -316,11 +316,11 @@ func (c *Chain) ForceInitLight() error { if err != nil { return err } + defer df() _, err = c.LightClientWithoutTrust(db) if err != nil { return err } - df() return nil } From cd69b8d9c5e5b4b4ec41ff1c51f632ff57001c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20Axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 9 Mar 2021 15:54:35 +0100 Subject: [PATCH 14/14] address comments --- relayer/msgs.go | 100 ++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 51 deletions(-) diff --git a/relayer/msgs.go b/relayer/msgs.go index 9070a4151..a6a7297bd 100644 --- a/relayer/msgs.go +++ b/relayer/msgs.go @@ -324,21 +324,19 @@ func (c *Chain) MsgTransfer(dst *PathEnd, amount sdk.Coin, dstAddr string, ) } -// MsgRelayTimeout -func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (msgs []sdk.Msg, err error) { - var recvRes *chantypes.QueryPacketReceiptResponse - // TODO: try commenting out retries to reduce complexity - // retry getting commit response until it succeeds +// MsgRelayRecvPacket constructs the MsgRecvPacket which is to be sent to the receiving chain. +// The counterparty represents the sending chain where the packet commitment would be stored. +func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPacket) (msgs []sdk.Msg, err error) { + var comRes *chantypes.QueryPacketCommitmentResponse if err = retry.Do(func() (err error) { - // NOTE: Timeouts currently only work with ORDERED channels for nwo // NOTE: the proof height uses - 1 due to tendermint's delayed execution model - recvRes, err = counterparty.QueryPacketReceipt(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) + comRes, err = counterparty.QueryPacketCommitment(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) if err != nil { return err } - if recvRes.Proof == nil { - return fmt.Errorf("timeout packet receipt proof seq(%d) is nil", packet.seq) + if comRes.Proof == nil || comRes.Commitment == nil { + return fmt.Errorf("recv packet commitment query seq(%d) is nil", packet.seq) } return nil @@ -355,7 +353,7 @@ func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (m msgs = append(msgs, updateMsg) if counterparty.debug { - counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet receipt: %s", + counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet commitment: %s", counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) } @@ -364,45 +362,43 @@ func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (m return } - if recvRes == nil { - return nil, fmt.Errorf("timeout packet [%s]seq{%d} has no associated proofs", c.ChainID, packet.seq) + if comRes == nil { + return nil, fmt.Errorf("receive packet [%s]seq{%d} has no associated proofs", c.ChainID, packet.seq) } - version := clienttypes.ParseChainID(counterparty.ChainID) - msg := chantypes.NewMsgTimeout( + version := clienttypes.ParseChainID(c.ChainID) + msg := chantypes.NewMsgRecvPacket( chantypes.NewPacket( packet.packetData, packet.seq, - c.PathEnd.PortID, - c.PathEnd.ChannelID, counterparty.PathEnd.PortID, counterparty.PathEnd.ChannelID, + c.PathEnd.PortID, + c.PathEnd.ChannelID, clienttypes.NewHeight(version, packet.timeout), packet.timeoutStamp, ), - packet.seq, - recvRes.Proof, - recvRes.ProofHeight, + comRes.Proof, + comRes.ProofHeight, c.MustGetAddress(), ) return append(msgs, msg), nil } -// MsgRelayRecvPacket -func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPacket) (msgs []sdk.Msg, err error) { - var comRes *chantypes.QueryPacketCommitmentResponse - // TODO: try commenting out retries to reduce complexity - // retry getting commit response until it succeeds +// MsgRelayAcknowledgement constructs the MsgAcknowledgement which is to be sent to the sending chain. +// The counterparty represents the receiving chain where the acknowledgement would be stored. +func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPacketAck) (msgs []sdk.Msg, err error) { + var ackRes *chantypes.QueryPacketAcknowledgementResponse if err = retry.Do(func() (err error) { // NOTE: the proof height uses - 1 due to tendermint's delayed execution model - comRes, err = counterparty.QueryPacketCommitment(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) + ackRes, err = counterparty.QueryPacketAcknowledgement(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) if err != nil { return err } - if comRes.Proof == nil || comRes.Commitment == nil { - return fmt.Errorf("recv packet commitment query seq(%d) is nil", packet.seq) + if ackRes.Proof == nil || ackRes.Acknowledgement == nil { + return fmt.Errorf("ack packet acknowledgement query seq(%d) is nil", packet.seq) } return nil @@ -419,7 +415,7 @@ func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPack msgs = append(msgs, updateMsg) if counterparty.debug { - counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet commitment: %s", + counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet acknowledgement: %s", counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) } @@ -428,44 +424,46 @@ func (c *Chain) MsgRelayRecvPacket(counterparty *Chain, packet *relayMsgRecvPack return } - if comRes == nil { - return nil, fmt.Errorf("receive packet [%s]seq{%d} has no associated proofs", c.ChainID, packet.seq) + if ackRes == nil { + return nil, fmt.Errorf("ack packet [%s]seq{%d} has no associated proofs", counterparty.ChainID, packet.seq) } - version := clienttypes.ParseChainID(c.ChainID) - msg := chantypes.NewMsgRecvPacket( + version := clienttypes.ParseChainID(counterparty.ChainID) + msg := chantypes.NewMsgAcknowledgement( chantypes.NewPacket( packet.packetData, packet.seq, - counterparty.PathEnd.PortID, - counterparty.PathEnd.ChannelID, c.PathEnd.PortID, c.PathEnd.ChannelID, + counterparty.PathEnd.PortID, + counterparty.PathEnd.ChannelID, clienttypes.NewHeight(version, packet.timeout), packet.timeoutStamp, ), - comRes.Proof, - comRes.ProofHeight, + packet.ack, + ackRes.Proof, + ackRes.ProofHeight, c.MustGetAddress(), ) return append(msgs, msg), nil } -// MsgRelayAcknowledgement -func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPacketAck) (msgs []sdk.Msg, err error) { - var ackRes *chantypes.QueryPacketAcknowledgementResponse - // TODO: try commenting out retries to reduce complexity - // retry getting commit response until it succeeds +// MsgRelayTimeout constructs the MsgTimeout which is to be sent to the sending chain. +// The counterparty represents the receiving chain where the receipts would have been +// stored. +func (c *Chain) MsgRelayTimeout(counterparty *Chain, packet *relayMsgTimeout) (msgs []sdk.Msg, err error) { + var recvRes *chantypes.QueryPacketReceiptResponse if err = retry.Do(func() (err error) { + // NOTE: Timeouts currently only work with ORDERED channels for nwo // NOTE: the proof height uses - 1 due to tendermint's delayed execution model - ackRes, err = counterparty.QueryPacketAcknowledgement(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) + recvRes, err = counterparty.QueryPacketReceipt(int64(counterparty.MustGetLatestLightHeight())-1, packet.seq) if err != nil { return err } - if ackRes.Proof == nil || ackRes.Acknowledgement == nil { - return fmt.Errorf("ack packet acknowledgement query seq(%d) is nil", packet.seq) + if recvRes.Proof == nil { + return fmt.Errorf("timeout packet receipt proof seq(%d) is nil", packet.seq) } return nil @@ -482,7 +480,7 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac msgs = append(msgs, updateMsg) if counterparty.debug { - counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet acknowledgement: %s", + counterparty.Log(fmt.Sprintf("- [%s]@{%d} - try(%d/%d) query packet receipt: %s", counterparty.ChainID, counterparty.MustGetLatestLightHeight()-1, n+1, rtyAttNum, err)) } @@ -491,12 +489,12 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac return } - if ackRes == nil { - return nil, fmt.Errorf("ack packet [%s]seq{%d} has no associated proofs", counterparty.ChainID, packet.seq) + if recvRes == nil { + return nil, fmt.Errorf("timeout packet [%s]seq{%d} has no associated proofs", c.ChainID, packet.seq) } version := clienttypes.ParseChainID(counterparty.ChainID) - msg := chantypes.NewMsgAcknowledgement( + msg := chantypes.NewMsgTimeout( chantypes.NewPacket( packet.packetData, packet.seq, @@ -507,9 +505,9 @@ func (c *Chain) MsgRelayAcknowledgement(counterparty *Chain, packet *relayMsgPac clienttypes.NewHeight(version, packet.timeout), packet.timeoutStamp, ), - packet.ack, - ackRes.Proof, - ackRes.ProofHeight, + packet.seq, + recvRes.Proof, + recvRes.ProofHeight, c.MustGetAddress(), )