From 3549cc62df88d1e424acd3eaabff83d9fb9b7414 Mon Sep 17 00:00:00 2001 From: vimystic <122659254+vimystic@users.noreply.github.com> Date: Fri, 1 Sep 2023 14:49:22 -0600 Subject: [PATCH 1/4] output json for query cmd's blance & clients-expirations --- cmd/query.go | 14 +++++++++++++- relayer/query.go | 22 ++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/cmd/query.go b/cmd/query.go index 15ccd743a..1409e758f 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -257,7 +257,19 @@ $ %s query balance ibc-0 testkey`, return err } - fmt.Fprintf(cmd.OutOrStdout(), "address {%s} balance {%s} \n", addr, coins) + // Create a map to hold the data + data := map[string]string{ + "address": addr, + "balance": coins.String(), + } + + // Convert the map to a JSON string + jsonOutput, err := json.Marshal(data) + if err != nil { + return err + } + + fmt.Fprint(cmd.OutOrStdout(), string(jsonOutput)) return nil }, } diff --git a/relayer/query.go b/relayer/query.go index 08b2ec1b0..80897b35d 100644 --- a/relayer/query.go +++ b/relayer/query.go @@ -2,7 +2,9 @@ package relayer import ( "context" + "encoding/json" "fmt" + "strconv" "strings" "time" @@ -308,12 +310,28 @@ func SPrintClientExpiration(chain *Chain, expiration time.Time, clientInfo Clien status = "GOOD" } - return fmt.Sprintf(` + data := map[string]string{ + "client": fmt.Sprintf("%s (%s)", chain.ClientID(), chain.ChainID()), + "HEALTH": status, + "TIME": fmt.Sprintf("%s (%s)", expirationFormatted, remainingTime.Round(time.Second)), + "LAST UPDATE HEIGHT": strconv.FormatUint(clientInfo.LatestHeight.GetRevisionHeight(), 10), + "TRUSTING PERIOD": clientInfo.TrustingPeriod.String(), + } + + jsonOutput, err := json.Marshal(data) + + if err != nil { + return fmt.Sprintf(` client: %s (%s) HEALTH: %s TIME: %s (%s) LAST UPDATE HEIGHT: %d TRUSTING PERIOD: %s `, - chain.ClientID(), chain.ChainID(), status, expirationFormatted, remainingTime.Round(time.Second), clientInfo.LatestHeight.GetRevisionHeight(), clientInfo.TrustingPeriod.String()) + chain.ClientID(), chain.ChainID(), status, expirationFormatted, remainingTime.Round(time.Second), clientInfo.LatestHeight.GetRevisionHeight(), clientInfo.TrustingPeriod.String()) + + } else { + return string(jsonOutput) + } + } From 2132a339ff8dec86ed6af134a39ae4223a30f8cd Mon Sep 17 00:00:00 2001 From: vimystic <122659254+vimystic@users.noreply.github.com> Date: Sat, 2 Sep 2023 20:49:28 -0600 Subject: [PATCH 2/4] print proper json instead of bytes for headers command --- cmd/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/query.go b/cmd/query.go index 1409e758f..0c2411dbf 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -321,7 +321,7 @@ $ %s query header ibc-0 1400`, return err } - fmt.Fprintln(cmd.OutOrStdout(), s) + fmt.Fprintln(cmd.OutOrStdout(), string(s)) return nil }, } From 5c0c34cbf2b2402b23310c3645353ddbe85244b4 Mon Sep 17 00:00:00 2001 From: vimystic <122659254+vimystic@users.noreply.github.com> Date: Sun, 10 Sep 2023 16:07:13 -0600 Subject: [PATCH 3/4] Add output flag . Use legacy,json options --- cmd/flags.go | 9 ++++ cmd/query.go | 107 ++++++++++++++++++++++++++++-------------- relayer/query.go | 40 +++++++++++----- relayer/query_test.go | 14 ++++++ 4 files changed, 123 insertions(+), 47 deletions(-) diff --git a/cmd/flags.go b/cmd/flags.go index 82bab138a..e5e850b4e 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -54,6 +54,7 @@ const ( flagDstClientID = "dst-client-id" flagSrcConnID = "src-connection-id" flagDstConnID = "dst-connection-id" + flagOutput = "output" ) const ( @@ -381,3 +382,11 @@ func OverwriteConfigFlag(v *viper.Viper, cmd *cobra.Command) *cobra.Command { } return cmd } + +func addOutputFlag(v *viper.Viper, cmd *cobra.Command) *cobra.Command { + cmd.Flags().StringP(flagOutput, "o", "legacy", "Specify the console output format. Can be 'legacy' or 'json'.") + if err := v.BindPFlag(flagOutput, cmd.Flags().Lookup(flagOutput)); err != nil { + panic(err) + } + return cmd +} diff --git a/cmd/query.go b/cmd/query.go index 0c2411dbf..fe2337fc0 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -63,7 +63,7 @@ func feegrantQueryCmd(a *appState) *cobra.Command { cmd.AddCommand( feegrantBasicGrantsCmd(a), ) - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -99,7 +99,7 @@ $ %s q ibc-denoms ibc-0`, return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -127,7 +127,7 @@ $ %s q denom-trace osmosis 9BBA9A1C257E971E38C1422780CE6F0B0686F0A3085E2D61118D9 return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -161,7 +161,7 @@ $ %s q tx ibc-0 A5DF8D272F1C451CFF92BA6C41942C4D29B5CF180279439ED6AB038282F956BE return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -213,7 +213,9 @@ $ %s q txs ibc-0 "message.action=transfer"`, }, } - return paginationFlags(a.viper, cmd, "txs") + cmd = addOutputFlag(a.viper, cmd) + cmd = paginationFlags(a.viper, cmd, "txs") + return cmd } func queryBalanceCmd(a *appState) *cobra.Command { @@ -269,12 +271,22 @@ $ %s query balance ibc-0 testkey`, return err } - fmt.Fprint(cmd.OutOrStdout(), string(jsonOutput)) + output, _ := cmd.Flags().GetString(flagOutput) + switch output { + case "json": + fmt.Fprint(cmd.OutOrStdout(), string(jsonOutput)) + case "legacy": + fallthrough + default: + fmt.Fprintf(cmd.OutOrStdout(), "address {%s} balance {%s} \n", addr, coins) + } return nil }, } - return ibcDenomFlags(a.viper, cmd) + cmd = addOutputFlag(a.viper, cmd) + cmd = ibcDenomFlags(a.viper, cmd) + return cmd } func queryHeaderCmd(a *appState) *cobra.Command { @@ -321,11 +333,21 @@ $ %s query header ibc-0 1400`, return err } - fmt.Fprintln(cmd.OutOrStdout(), string(s)) + output, _ := cmd.Flags().GetString(flagOutput) + switch output { + case "json": + fmt.Fprintln(cmd.OutOrStdout(), string(s)) + case "legacy": + fallthrough + default: + fmt.Fprintln(cmd.OutOrStdout(), s) + } + return nil }, } + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -367,7 +389,7 @@ $ %s q node-state ibc-1`, return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -418,8 +440,9 @@ $ %s query client ibc-0 ibczeroclient --height 1205`, return nil }, } - - return heightFlag(a.viper, cmd) + cmd = addOutputFlag(a.viper, cmd) + cmd = heightFlag(a.viper, cmd) + return cmd } func queryClientsCmd(a *appState) *cobra.Command { @@ -463,8 +486,9 @@ $ %s query clients ibc-2 --offset 2 --limit 30`, return nil }, } - - return paginationFlags(a.viper, cmd, "client states") + cmd = addOutputFlag(a.viper, cmd) + cmd = paginationFlags(a.viper, cmd, "client states") + return cmd } func queryConnections(a *appState) *cobra.Command { @@ -510,7 +534,9 @@ $ %s q conns ibc-1`, }, } - return paginationFlags(a.viper, cmd, "connections on a network") + cmd = addOutputFlag(a.viper, cmd) + cmd = paginationFlags(a.viper, cmd, "connections on a network") + return cmd } func queryConnectionsUsingClient(a *appState) *cobra.Command { @@ -563,7 +589,9 @@ $ %s query client-connections ibc-0 ibczeroclient --height 1205`, }, } - return heightFlag(a.viper, cmd) + cmd = addOutputFlag(a.viper, cmd) + cmd = heightFlag(a.viper, cmd) + return cmd } func queryConnection(a *appState) *cobra.Command { @@ -607,7 +635,7 @@ $ %s q conn ibc-1 ibconeconn`, return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -656,7 +684,9 @@ $ %s query connection-channels ibc-2 ibcconnection2 --offset 2 --limit 30`, }, } - return paginationFlags(a.viper, cmd, "channels associated with a connection") + cmd = addOutputFlag(a.viper, cmd) + cmd = paginationFlags(a.viper, cmd, "channels associated with a connection") + return cmd } func queryChannel(a *appState) *cobra.Command { @@ -709,7 +739,9 @@ $ %s query channel ibc-2 ibctwochannel transfer --height 1205`, }, } - return heightFlag(a.viper, cmd) + cmd = addOutputFlag(a.viper, cmd) + cmd = heightFlag(a.viper, cmd) + return cmd } // chanExtendedInfo is an intermediate type for holding additional useful @@ -929,7 +961,9 @@ $ %s query channels ibc-0 ibc-2`, }, } - return paginationFlags(a.viper, cmd, "channels on a network") + cmd = addOutputFlag(a.viper, cmd) + cmd = paginationFlags(a.viper, cmd, "channels on a network") + return cmd } func queryPacketCommitment(a *appState) *cobra.Command { @@ -971,7 +1005,7 @@ $ %s q packet-commit ibc-1 ibconechannel transfer 31`, return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -1024,7 +1058,7 @@ $ %s query unrelayed-pkts demo-path channel-0`, return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -1076,7 +1110,7 @@ $ %s query unrelayed-acks demo-path channel-0`, return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } @@ -1117,24 +1151,27 @@ $ %s query clients-expiration demo-path`, return errDst } - // if only the src light client is found, just print info for source light client - if errSrc == nil && errDst != nil { - fmt.Fprintln(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[src], srcExpiration, srcClientInfo)) - return nil - } + output, _ := cmd.Flags().GetString(flagOutput) - // if only the dst light client is found, just print info for destination light client - if errDst == nil && errSrc != nil { - fmt.Fprintln(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[dst], dstExpiration, dstClientInfo)) - return nil - } + srcClientExpiration := relayer.SPrintClientExpiration(c[src], srcExpiration, srcClientInfo) + dstClientExpiration := relayer.SPrintClientExpiration(c[dst], dstExpiration, dstClientInfo) - fmt.Fprintln(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[src], srcExpiration, srcClientInfo)) - fmt.Fprintln(cmd.OutOrStdout(), relayer.SPrintClientExpiration(c[dst], dstExpiration, dstClientInfo)) + if output == "json" { + srcClientExpiration = relayer.SPrintClientExpirationJson(c[src], srcExpiration, srcClientInfo) + dstClientExpiration = relayer.SPrintClientExpirationJson(c[dst], dstExpiration, dstClientInfo) + } + if errSrc == nil && errDst == nil { + fmt.Fprintln(cmd.OutOrStdout(), srcClientExpiration) + fmt.Fprintln(cmd.OutOrStdout(), dstClientExpiration) + } else if errSrc == nil && errDst != nil { + fmt.Fprintln(cmd.OutOrStdout(), dstClientExpiration) + } else if errDst == nil && errSrc != nil { + fmt.Fprintln(cmd.OutOrStdout(), srcClientExpiration) + } return nil }, } - + cmd = addOutputFlag(a.viper, cmd) return cmd } diff --git a/relayer/query.go b/relayer/query.go index 80897b35d..fa59dba14 100644 --- a/relayer/query.go +++ b/relayer/query.go @@ -310,6 +310,32 @@ func SPrintClientExpiration(chain *Chain, expiration time.Time, clientInfo Clien status = "GOOD" } + legacyOutput := fmt.Sprintf(` + client: %s (%s) + HEALTH: %s + TIME: %s (%s) + LAST UPDATE HEIGHT: %d + TRUSTING PERIOD: %s + `, + chain.ClientID(), chain.ChainID(), status, expirationFormatted, remainingTime.Round(time.Second), clientInfo.LatestHeight.GetRevisionHeight(), clientInfo.TrustingPeriod.String()) + + return legacyOutput + +} + +// Returns clientExpiration data in JSON format. +func SPrintClientExpirationJson(chain *Chain, expiration time.Time, clientInfo ClientStateInfo) string { + now := time.Now() + remainingTime := expiration.Sub(now) + expirationFormatted := expiration.Format(time.RFC822) + + var status string + if remainingTime <= 0 { + status = "EXPIRED" + } else { + status = "GOOD" + } + data := map[string]string{ "client": fmt.Sprintf("%s (%s)", chain.ClientID(), chain.ChainID()), "HEALTH": status, @@ -319,19 +345,9 @@ func SPrintClientExpiration(chain *Chain, expiration time.Time, clientInfo Clien } jsonOutput, err := json.Marshal(data) - if err != nil { - return fmt.Sprintf(` - client: %s (%s) - HEALTH: %s - TIME: %s (%s) - LAST UPDATE HEIGHT: %d - TRUSTING PERIOD: %s - `, - chain.ClientID(), chain.ChainID(), status, expirationFormatted, remainingTime.Round(time.Second), clientInfo.LatestHeight.GetRevisionHeight(), clientInfo.TrustingPeriod.String()) - - } else { - return string(jsonOutput) + jsonOutput = []byte{} } + return string(jsonOutput) } diff --git a/relayer/query_test.go b/relayer/query_test.go index 39dc837b7..ea7e4b71d 100644 --- a/relayer/query_test.go +++ b/relayer/query_test.go @@ -31,8 +31,10 @@ func TestSPrintClientExpiration_PrintClientId(t *testing.T) { chain := mockChain("test-chain-id", "expected-client-id") clientStateInfo := mockClientStateInfo("test-chain-id", trustingPeriod, mockHeight) expiration := SPrintClientExpiration(chain, previousTime, *clientStateInfo) + expirationJson := SPrintClientExpirationJson(chain, previousTime, *clientStateInfo) require.Contains(t, expiration, "expected-client-id") + require.Contains(t, expirationJson, "expected-client-id") } func TestSPrintClientExpiration_PrintExpired_WhenTimeIsInPast(t *testing.T) { @@ -43,8 +45,10 @@ func TestSPrintClientExpiration_PrintExpired_WhenTimeIsInPast(t *testing.T) { chain := mockChain("test-chain-id", "test-client-id") clientStateInfo := mockClientStateInfo("test-chain-id", trustingPeriod, mockHeight) expiration := SPrintClientExpiration(chain, previousTime, *clientStateInfo) + expirationJson := SPrintClientExpirationJson(chain, previousTime, *clientStateInfo) require.Contains(t, expiration, "EXPIRED") + require.Contains(t, expirationJson, "EXPIRED") } func TestSPrintClientExpiration_PrintRFC822FormattedTime_WhenTimeIsInPast(t *testing.T) { @@ -55,8 +59,10 @@ func TestSPrintClientExpiration_PrintRFC822FormattedTime_WhenTimeIsInPast(t *tes chain := mockChain("expected-chain-id", "test-client-id") clientStateInfo := mockClientStateInfo("test-chain-id", trustingPeriod, mockHeight) expiration := SPrintClientExpiration(chain, pastTime, *clientStateInfo) + expirationJson := SPrintClientExpirationJson(chain, pastTime, *clientStateInfo) require.Contains(t, expiration, pastTime.Format(time.RFC822)) + require.Contains(t, expirationJson, pastTime.Format(time.RFC822)) } func TestSPrintClientExpiration_PrintGood_WhenTimeIsInFuture(t *testing.T) { @@ -67,8 +73,10 @@ func TestSPrintClientExpiration_PrintGood_WhenTimeIsInFuture(t *testing.T) { chain := mockChain("test-chain-id", "test-client-id") clientStateInfo := mockClientStateInfo("test-chain-id", trustingPeriod, mockHeight) expiration := SPrintClientExpiration(chain, previousTime, *clientStateInfo) + expirationJson := SPrintClientExpirationJson(chain, previousTime, *clientStateInfo) require.Contains(t, expiration, "GOOD") + require.Contains(t, expirationJson, "GOOD") } func TestSPrintClientExpiration_PrintRFC822FormattedTime_WhenTimeIsInFuture(t *testing.T) { @@ -79,8 +87,10 @@ func TestSPrintClientExpiration_PrintRFC822FormattedTime_WhenTimeIsInFuture(t *t chain := mockChain("test-chain-id", "test-client-id") clientStateInfo := mockClientStateInfo("test-chain-id", trustingPeriod, mockHeight) expiration := SPrintClientExpiration(chain, futureTime, *clientStateInfo) + expirationJson := SPrintClientExpirationJson(chain, futureTime, *clientStateInfo) require.Contains(t, expiration, futureTime.Format(time.RFC822)) + require.Contains(t, expirationJson, futureTime.Format(time.RFC822)) } func TestSPrintClientExpiration_PrintRemainingTime_WhenTimeIsInFuture(t *testing.T) { @@ -91,8 +101,10 @@ func TestSPrintClientExpiration_PrintRemainingTime_WhenTimeIsInFuture(t *testing chain := mockChain("test-chain-id", "test-client-id") clientStateInfo := mockClientStateInfo("test-chain-id", trustingPeriod, mockHeight) expiration := SPrintClientExpiration(chain, futureTime, *clientStateInfo) + expirationJson := SPrintClientExpirationJson(chain, futureTime, *clientStateInfo) require.Contains(t, expiration, "10h0m0s") + require.Contains(t, expirationJson, "10h0m0s") } func TestSPrintClientExpiration_TrustingPeriod(t *testing.T) { @@ -103,8 +115,10 @@ func TestSPrintClientExpiration_TrustingPeriod(t *testing.T) { chain := mockChain("expected-chain-id", "test-client-id") clientStateInfo := mockClientStateInfo("test-chain-id", trustingPeriod, mockHeight) expiration := SPrintClientExpiration(chain, previousTime, *clientStateInfo) + expirationJson := SPrintClientExpirationJson(chain, previousTime, *clientStateInfo) require.Contains(t, expiration, "1h0m0s") + require.Contains(t, expirationJson, "1h0m0s") } func TestSPrintClientExpiration_LastUpdateHeight(t *testing.T) { From 3f121143e00be0edf70dab1bf9c7581f2ed7c890 Mon Sep 17 00:00:00 2001 From: vimystic <122659254+vimystic@users.noreply.github.com> Date: Tue, 12 Sep 2023 17:23:35 -0600 Subject: [PATCH 4/4] Update according to reviews --- cmd/query.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/cmd/query.go b/cmd/query.go index fe2337fc0..2f3c2e3e9 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -15,6 +15,11 @@ import ( "github.com/spf13/cobra" ) +const ( + formatJson = "json" + formatLegacy = "legacy" +) + // queryCmd represents the chain command func queryCmd(a *appState) *cobra.Command { cmd := &cobra.Command{ @@ -273,9 +278,9 @@ $ %s query balance ibc-0 testkey`, output, _ := cmd.Flags().GetString(flagOutput) switch output { - case "json": + case formatJson: fmt.Fprint(cmd.OutOrStdout(), string(jsonOutput)) - case "legacy": + case formatLegacy: fallthrough default: fmt.Fprintf(cmd.OutOrStdout(), "address {%s} balance {%s} \n", addr, coins) @@ -335,9 +340,9 @@ $ %s query header ibc-0 1400`, output, _ := cmd.Flags().GetString(flagOutput) switch output { - case "json": + case formatJson: fmt.Fprintln(cmd.OutOrStdout(), string(s)) - case "legacy": + case formatLegacy: fallthrough default: fmt.Fprintln(cmd.OutOrStdout(), s) @@ -1156,18 +1161,17 @@ $ %s query clients-expiration demo-path`, srcClientExpiration := relayer.SPrintClientExpiration(c[src], srcExpiration, srcClientInfo) dstClientExpiration := relayer.SPrintClientExpiration(c[dst], dstExpiration, dstClientInfo) - if output == "json" { + if output == formatJson { srcClientExpiration = relayer.SPrintClientExpirationJson(c[src], srcExpiration, srcClientInfo) dstClientExpiration = relayer.SPrintClientExpirationJson(c[dst], dstExpiration, dstClientInfo) } - if errSrc == nil && errDst == nil { + if errSrc == nil { fmt.Fprintln(cmd.OutOrStdout(), srcClientExpiration) + } + + if errDst == nil { fmt.Fprintln(cmd.OutOrStdout(), dstClientExpiration) - } else if errSrc == nil && errDst != nil { - fmt.Fprintln(cmd.OutOrStdout(), dstClientExpiration) - } else if errDst == nil && errSrc != nil { - fmt.Fprintln(cmd.OutOrStdout(), srcClientExpiration) } return nil },