github.com/okex/exchain@v1.8.0/libs/ibc-go/modules/core/03-connection/client/utils/utils.go (about) 1 package utils 2 3 import ( 4 "context" 5 "fmt" 6 clictx "github.com/okex/exchain/libs/cosmos-sdk/client/context" 7 "github.com/okex/exchain/libs/cosmos-sdk/codec" 8 sdkerrors "github.com/okex/exchain/libs/cosmos-sdk/types/errors" 9 "github.com/okex/exchain/libs/ibc-go/modules/core/02-client/client/utils" 10 clienttypes "github.com/okex/exchain/libs/ibc-go/modules/core/02-client/types" 11 "github.com/okex/exchain/libs/ibc-go/modules/core/03-connection/types" 12 commitmenttypes "github.com/okex/exchain/libs/ibc-go/modules/core/23-commitment/types" 13 host "github.com/okex/exchain/libs/ibc-go/modules/core/24-host" 14 ibcclient "github.com/okex/exchain/libs/ibc-go/modules/core/client" 15 "github.com/okex/exchain/libs/ibc-go/modules/core/exported" 16 "io/ioutil" 17 18 "github.com/pkg/errors" 19 ) 20 21 // QueryConnection returns a connection end. 22 // If prove is true, it performs an ABCI store query in order to retrieve the merkle proof. Otherwise, 23 // it uses the gRPC query client. 24 func QueryConnection( 25 clientCtx clictx.CLIContext, connectionID string, prove bool, 26 ) (*types.QueryConnectionResponse, error) { 27 if prove { 28 return queryConnectionABCI(clientCtx, connectionID) 29 } 30 queryClient := types.NewQueryClient(clientCtx) 31 req := &types.QueryConnectionRequest{ 32 ConnectionId: connectionID, 33 } 34 35 return queryClient.Connection(context.Background(), req) 36 } 37 38 func queryConnectionABCI(clientCtx clictx.CLIContext, connectionID string) (*types.QueryConnectionResponse, error) { 39 key := host.ConnectionKey(connectionID) 40 41 value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key) 42 if err != nil { 43 return nil, err 44 } 45 46 // check if connection exists 47 if len(value) == 0 { 48 return nil, sdkerrors.Wrap(types.ErrConnectionNotFound, connectionID) 49 } 50 51 cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) 52 53 var connection types.ConnectionEnd 54 if err := cdc.UnmarshalBinaryBare(value, &connection); err != nil { 55 return nil, err 56 } 57 58 return types.NewQueryConnectionResponse(connection, proofBz, proofHeight), nil 59 } 60 61 // QueryClientConnections queries the connection paths registered for a particular client. 62 // If prove is true, it performs an ABCI store query in order to retrieve the merkle proof. Otherwise, 63 // it uses the gRPC query client. 64 func QueryClientConnections( 65 clientCtx clictx.CLIContext, clientID string, prove bool, 66 ) (*types.QueryClientConnectionsResponse, error) { 67 if prove { 68 return queryClientConnectionsABCI(clientCtx, clientID) 69 } 70 71 queryClient := types.NewQueryClient(clientCtx) 72 req := &types.QueryClientConnectionsRequest{ 73 ClientId: clientID, 74 } 75 76 return queryClient.ClientConnections(context.Background(), req) 77 } 78 79 func queryClientConnectionsABCI(clientCtx clictx.CLIContext, clientID string) (*types.QueryClientConnectionsResponse, error) { 80 key := host.ClientConnectionsKey(clientID) 81 82 value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key) 83 if err != nil { 84 return nil, err 85 } 86 87 // check if connection paths exist 88 if len(value) == 0 { 89 return nil, sdkerrors.Wrap(types.ErrClientConnectionPathsNotFound, clientID) 90 } 91 92 var paths []string 93 if err := clientCtx.CodecProy.GetCdc().UnmarshalBinaryBare(value, &paths); err != nil { 94 return nil, err 95 } 96 97 return types.NewQueryClientConnectionsResponse(paths, proofBz, proofHeight), nil 98 } 99 100 // QueryConnectionClientState returns the ClientState of a connection end. If 101 // prove is true, it performs an ABCI store query in order to retrieve the 102 // merkle proof. Otherwise, it uses the gRPC query client. 103 func QueryConnectionClientState( 104 clientCtx clictx.CLIContext, connectionID string, prove bool, 105 ) (*types.QueryConnectionClientStateResponse, error) { 106 107 queryClient := types.NewQueryClient(clientCtx) 108 req := &types.QueryConnectionClientStateRequest{ 109 ConnectionId: connectionID, 110 } 111 112 res, err := queryClient.ConnectionClientState(context.Background(), req) 113 if err != nil { 114 return nil, err 115 } 116 117 if prove { 118 clientStateRes, err := utils.QueryClientStateABCI(clientCtx, res.IdentifiedClientState.ClientId) 119 if err != nil { 120 return nil, err 121 } 122 123 // use client state returned from ABCI query in case query height differs 124 identifiedClientState := clienttypes.IdentifiedClientState{ 125 ClientId: res.IdentifiedClientState.ClientId, 126 ClientState: clientStateRes.ClientState, 127 } 128 129 res = types.NewQueryConnectionClientStateResponse(identifiedClientState, clientStateRes.Proof, clientStateRes.ProofHeight) 130 } 131 132 return res, nil 133 } 134 135 // QueryConnectionConsensusState returns the ConsensusState of a connection end. If 136 // prove is true, it performs an ABCI store query in order to retrieve the 137 // merkle proof. Otherwise, it uses the gRPC query client. 138 func QueryConnectionConsensusState( 139 clientCtx clictx.CLIContext, connectionID string, height clienttypes.Height, prove bool, 140 ) (*types.QueryConnectionConsensusStateResponse, error) { 141 142 queryClient := types.NewQueryClient(clientCtx) 143 req := &types.QueryConnectionConsensusStateRequest{ 144 ConnectionId: connectionID, 145 RevisionNumber: height.RevisionNumber, 146 RevisionHeight: height.RevisionHeight, 147 } 148 149 res, err := queryClient.ConnectionConsensusState(context.Background(), req) 150 if err != nil { 151 return nil, err 152 } 153 154 if prove { 155 consensusStateRes, err := utils.QueryConsensusStateABCI(clientCtx, res.ClientId, height) 156 if err != nil { 157 return nil, err 158 } 159 160 res = types.NewQueryConnectionConsensusStateResponse(res.ClientId, consensusStateRes.ConsensusState, height, consensusStateRes.Proof, consensusStateRes.ProofHeight) 161 } 162 163 return res, nil 164 } 165 166 // ParseClientState unmarshals a cmd input argument from a JSON string to a client state 167 // If the input is not a JSON, it looks for a path to the JSON file 168 func ParseClientState(cdc *codec.CodecProxy, arg string) (exported.ClientState, error) { 169 var clientState exported.ClientState 170 if err := cdc.GetCdc().UnmarshalJSON([]byte(arg), &clientState); err != nil { 171 // check for file path if JSON input is not provided 172 contents, err := ioutil.ReadFile(arg) 173 if err != nil { 174 return nil, errors.New("either JSON input nor path to .json file were provided") 175 } 176 if err := cdc.GetCdc().UnmarshalJSON(contents, &clientState); err != nil { 177 return nil, errors.Wrap(err, "error unmarshalling client state") 178 } 179 } 180 return clientState, nil 181 } 182 183 // ParsePrefix unmarshals an cmd input argument from a JSON string to a commitment 184 // Prefix. If the input is not a JSON, it looks for a path to the JSON file. 185 func ParsePrefix(cdc *codec.CodecProxy, arg string) (commitmenttypes.MerklePrefix, error) { 186 var prefix commitmenttypes.MerklePrefix 187 if err := cdc.GetCdc().UnmarshalJSON([]byte(arg), &prefix); err != nil { 188 // check for file path if JSON input is not provided 189 contents, err := ioutil.ReadFile(arg) 190 if err != nil { 191 return commitmenttypes.MerklePrefix{}, errors.New("neither JSON input nor path to .json file were provided") 192 } 193 if err := cdc.GetCdc().UnmarshalJSON(contents, &prefix); err != nil { 194 return commitmenttypes.MerklePrefix{}, errors.Wrap(err, "error unmarshalling commitment prefix") 195 } 196 } 197 return prefix, nil 198 } 199 200 // ParseProof unmarshals a cmd input argument from a JSON string to a commitment 201 // Proof. If the input is not a JSON, it looks for a path to the JSON file. It 202 // then marshals the commitment proof into a proto encoded byte array. 203 func ParseProof(cdc *codec.CodecProxy, arg string) ([]byte, error) { 204 var merkleProof commitmenttypes.MerkleProof 205 if err := cdc.GetCdc().UnmarshalJSON([]byte(arg), &merkleProof); err != nil { 206 // check for file path if JSON input is not provided 207 contents, err := ioutil.ReadFile(arg) 208 if err != nil { 209 return nil, errors.New("neither JSON input nor path to .json file were provided") 210 } 211 if err := cdc.GetCdc().UnmarshalJSON(contents, &merkleProof); err != nil { 212 return nil, fmt.Errorf("error unmarshalling commitment proof: %w", err) 213 } 214 } 215 216 return cdc.GetCdc().MarshalJSON(&merkleProof) 217 }