Skip to content

Commit

Permalink
fix: add relative timeout support for localhost clients using the tra…
Browse files Browse the repository at this point in the history
…nsfer CLI client (cosmos#3587) (cosmos#3690)

* updating incorrect error return in 04-channel SendPacket

* support localhost transfers using relative timeouts via the CLI client

* Update modules/apps/transfer/client/cli/tx.go

Co-authored-by: colin axnér <[email protected]>

* optimise client consensus state query as per review suggestion, rm error adaptation for another PR

---------

Co-authored-by: colin axnér <[email protected]>
(cherry picked from commit df2841d)

Co-authored-by: Damian Nolan <[email protected]>
  • Loading branch information
mergify[bot] and damiannolan authored May 30, 2023
1 parent 4519f10 commit 8586338
Showing 1 changed file with 37 additions and 7 deletions.
44 changes: 37 additions & 7 deletions modules/apps/transfer/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import (
"github.com/spf13/cobra"

"github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
clientutils "github.com/cosmos/ibc-go/v7/modules/core/02-client/client/utils"
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
channelutils "github.com/cosmos/ibc-go/v7/modules/core/04-channel/client/utils"
"github.com/cosmos/ibc-go/v7/modules/core/exported"
)

const (
Expand Down Expand Up @@ -83,26 +85,54 @@ corresponding to the counterparty channel. Any timeout set to 0 is disabled.`),
}

// if the timeouts are not absolute, retrieve latest block height and block timestamp
// for the consensus state connected to the destination port/channel
// for the consensus state connected to the destination port/channel.
// localhost clients must rely solely on local clock time in order to use relative timestamps.
if !absoluteTimeouts {
consensusState, height, _, err := channelutils.QueryLatestConsensusState(clientCtx, srcPort, srcChannel)
clientRes, err := channelutils.QueryChannelClientState(clientCtx, srcPort, srcChannel, false)
if err != nil {
return err
}

var clientState exported.ClientState
if err := clientCtx.InterfaceRegistry.UnpackAny(clientRes.IdentifiedClientState.ClientState, &clientState); err != nil {
return err
}

clientHeight, ok := clientState.GetLatestHeight().(clienttypes.Height)
if !ok {
return fmt.Errorf("invalid height type. expected type: %T, got: %T", clienttypes.Height{}, clientState.GetLatestHeight())
}

var consensusState exported.ConsensusState
if clientState.ClientType() != exported.Localhost {
consensusStateRes, err := clientutils.QueryConsensusState(clientCtx, clientRes.IdentifiedClientState.ClientId, clientHeight, false, true)
if err != nil {
return err
}

if err := clientCtx.InterfaceRegistry.UnpackAny(consensusStateRes.ConsensusState, &consensusState); err != nil {
return err
}
}

if !timeoutHeight.IsZero() {
absoluteHeight := height
absoluteHeight := clientHeight
absoluteHeight.RevisionNumber += timeoutHeight.RevisionNumber
absoluteHeight.RevisionHeight += timeoutHeight.RevisionHeight
timeoutHeight = absoluteHeight
}

// use local clock time as reference time if it is later than the
// consensus state timestamp of the counterparty chain, otherwise
// still use consensus state timestamp as reference.
// for localhost clients local clock time is always used.
if timeoutTimestamp != 0 {
// use local clock time as reference time if it is later than the
// consensus state timestamp of the counter party chain, otherwise
// still use consensus state timestamp as reference
var consensusStateTimestamp uint64
if consensusState != nil {
consensusStateTimestamp = consensusState.GetTimestamp()
}

now := time.Now().UnixNano()
consensusStateTimestamp := consensusState.GetTimestamp()
if now > 0 {
now := uint64(now)
if now > consensusStateTimestamp {
Expand Down

0 comments on commit 8586338

Please sign in to comment.