Skip to content

Commit

Permalink
feat: add new clients-expiration query returning time before expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
glebiller committed Oct 28, 2022
1 parent b06fceb commit 04612e1
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 3 deletions.
52 changes: 49 additions & 3 deletions cmd/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ package cmd
import (
"encoding/json"
"fmt"
"strconv"
"strings"

"github.com/cosmos/relayer/v2/relayer"
"github.com/spf13/cobra"
"strconv"
"strings"
)

// queryCmd represents the chain command
Expand All @@ -31,6 +30,7 @@ func queryCmd(a *appState) *cobra.Command {
lineBreakCommand(),
queryClientCmd(a),
queryClientsCmd(a),
queryClientsExpiration(a),
queryConnection(a),
queryConnections(a),
queryConnectionsUsingClient(a),
Expand Down Expand Up @@ -870,3 +870,49 @@ $ %s query unrelayed-acks demo-path channel-0`,

return cmd
}

func queryClientsExpiration(a *appState) *cobra.Command {
cmd := &cobra.Command{
Use: "clients-expiration path",
Short: "query for light clients expiration date",
Args: withUsage(cobra.ExactArgs(1)),
Example: strings.TrimSpace(fmt.Sprintf(`
$ %s query clients-expiration demo-path`,
appName,
)),
RunE: func(cmd *cobra.Command, args []string) error {
path, err := a.Config.Paths.Get(args[0])
if err != nil {
return err
}
src, dst := path.Src.ChainID, path.Dst.ChainID
c, err := a.Config.Chains.Gets(src, dst)
if err != nil {
return err
}

if err = c[src].SetPath(path.Src); err != nil {
return err
}
if err = c[dst].SetPath(path.Dst); err != nil {
return err
}

srcExpiration, err := relayer.QueryClientExpiration(cmd.Context(), c[src], c[dst])
if err != nil {
return err
}
dstExpiration, err := relayer.QueryClientExpiration(cmd.Context(), c[dst], c[src])
if err != nil {
return err
}

fmt.Fprintf(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[src], srcExpiration))
fmt.Fprintf(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[dst], dstExpiration))

return nil
},
}

return cmd
}
34 changes: 34 additions & 0 deletions relayer/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strings"
"time"

"github.com/avast/retry-go/v4"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
Expand Down Expand Up @@ -301,3 +302,36 @@ func QueryBalance(ctx context.Context, chain *Chain, address string, showDenoms
}
return out, nil
}

func QueryClientExpiration(ctx context.Context, from, to *Chain) (time.Time, error) {
latestHeight, err := from.ChainProvider.QueryLatestHeight(ctx)
if err != nil {
return time.Time{}, err
}

clientState, err := from.QueryTMClientState(ctx, latestHeight)
if err != nil {
return time.Time{}, err
}

trustingPeriod := clientState.TrustingPeriod
clientTime, err := to.ChainProvider.BlockTime(ctx, int64(clientState.GetLatestHeight().GetRevisionHeight()))
if err != nil {
return time.Time{}, err
}

return clientTime.Add(trustingPeriod), nil
}

func SPrintClientExpiration(chain *Chain, expiration time.Time) string {
now := time.Now()
remainingTime := expiration.Sub(now)
expirationFormatted := expiration.Format(time.RFC822)

if remainingTime < 0 {
return fmt.Sprintf("client %s (%s) is already expired (%s)\n",
chain.ClientID(), chain.ChainID(), expirationFormatted)
}
return fmt.Sprintf("client %s (%s) expires in %s (%s)\n",
chain.ClientID(), chain.ChainID(), remainingTime.Round(time.Second), expirationFormatted)
}
87 changes: 87 additions & 0 deletions relayer/query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package relayer

import (
"github.com/cosmos/relayer/v2/relayer/chains/cosmos"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestSPrintClientExpiration_PrintChainId(t *testing.T) {
previousTime := time.Now().Add(10 * time.Hour)

chain := mockChain("expected-chain-id", "test-client-id")
expiration := SPrintClientExpiration(chain, previousTime)

require.Contains(t, expiration, "expected-chain-id")
}

func TestSPrintClientExpiration_PrintClientId(t *testing.T) {
previousTime := time.Now().Add(10 * time.Hour)

chain := mockChain("test-chain-id", "expected-client-id")
expiration := SPrintClientExpiration(chain, previousTime)

require.Contains(t, expiration, "expected-client-id")
}

func TestSPrintClientExpiration_PrintIsAlreadyExpired_WhenTimeIsInPast(t *testing.T) {
previousTime := time.Now().Add(-10 * time.Hour)

chain := mockChain("test-chain-id", "test-client-id")
expiration := SPrintClientExpiration(chain, previousTime)

require.Contains(t, expiration, "is already expired")
}

func TestSPrintClientExpiration_PrintRFC822FormattedTime_WhenTimeIsInPast(t *testing.T) {
pastTime := time.Now().Add(-10 * time.Hour)

chain := mockChain("test-chain-id", "test-client-id")
expiration := SPrintClientExpiration(chain, pastTime)

require.Contains(t, expiration, pastTime.Format(time.RFC822))
}

func TestSPrintClientExpiration_PrintExpiresIn_WhenTimeIsInFuture(t *testing.T) {
previousTime := time.Now().Add(10 * time.Hour)

chain := mockChain("test-chain-id", "test-client-id")
expiration := SPrintClientExpiration(chain, previousTime)

require.Contains(t, expiration, "expires in")
}

func TestSPrintClientExpiration_PrintRFC822FormattedTime_WhenTimeIsInFuture(t *testing.T) {
futureTime := time.Now().Add(10 * time.Hour)

chain := mockChain("test-chain-id", "test-client-id")
expiration := SPrintClientExpiration(chain, futureTime)

require.Contains(t, expiration, futureTime.Format(time.RFC822))
}

func TestSPrintClientExpiration_PrintRemainingTime_WhenTimeIsInFuture(t *testing.T) {
futureTime := time.Now().Add(10 * time.Hour)

chain := mockChain("test-chain-id", "test-client-id")
expiration := SPrintClientExpiration(chain, futureTime)

require.Contains(t, expiration, "10h0m0s")
}

func mockChain(chainId string, clientId string) *Chain {
return &Chain{
Chainid: chainId,
ChainProvider: &cosmos.CosmosProvider{
PCfg: cosmos.CosmosProviderConfig{
ChainID: chainId,
},
},
PathEnd: &PathEnd{
ChainID: chainId,
ClientID: clientId,
},
}
}

0 comments on commit 04612e1

Please sign in to comment.