github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/02-client/client/utils/utils.go (about) 1 package utils 2 3 import ( 4 "context" 5 6 clictx "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context" 7 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 8 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types" 9 commitmenttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/23-commitment/types" 10 host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host" 11 ibcclient "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/client" 12 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported" 13 ibctmtypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/light-clients/07-tendermint/types" 14 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 15 ) 16 17 // QueryClientState returns a client state. If prove is true, it performs an ABCI store query 18 // in order to retrieve the merkle proof. Otherwise, it uses the gRPC query client. 19 func QueryClientState( 20 clientCtx clictx.CLIContext, clientID string, prove bool, 21 ) (*types.QueryClientStateResponse, error) { 22 if prove { 23 return QueryClientStateABCI(clientCtx, clientID) 24 } 25 26 queryClient := types.NewQueryClient(clientCtx) 27 req := &types.QueryClientStateRequest{ 28 ClientId: clientID, 29 } 30 31 return queryClient.ClientState(context.Background(), req) 32 } 33 34 // QueryClientStateABCI queries the store to get the light client state and a merkle proof. 35 func QueryClientStateABCI( 36 clientCtx clictx.CLIContext, clientID string, 37 ) (*types.QueryClientStateResponse, error) { 38 key := host.FullClientStateKey(clientID) 39 40 value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key) 41 if err != nil { 42 return nil, err 43 } 44 45 // check if client exists 46 if len(value) == 0 { 47 return nil, sdkerrors.Wrap(types.ErrClientNotFound, clientID) 48 } 49 50 cdc := clientCtx.CodecProy 51 52 clientState, err := types.UnmarshalClientState(cdc, value) 53 if err != nil { 54 return nil, err 55 } 56 57 anyClientState, err := types.PackClientState(clientState) 58 if err != nil { 59 return nil, err 60 } 61 62 clientStateRes := types.NewQueryClientStateResponse(anyClientState, proofBz, proofHeight) 63 return clientStateRes, nil 64 } 65 66 // QueryConsensusState returns a consensus state. If prove is true, it performs an ABCI store 67 // query in order to retrieve the merkle proof. Otherwise, it uses the gRPC query client. 68 func QueryConsensusState( 69 clientCtx clictx.CLIContext, clientID string, height exported.Height, prove, latestHeight bool, 70 ) (*types.QueryConsensusStateResponse, error) { 71 if prove { 72 return QueryConsensusStateABCI(clientCtx, clientID, height) 73 } 74 75 queryClient := types.NewQueryClient(clientCtx) 76 req := &types.QueryConsensusStateRequest{ 77 ClientId: clientID, 78 RevisionNumber: height.GetRevisionNumber(), 79 RevisionHeight: height.GetRevisionHeight(), 80 LatestHeight: latestHeight, 81 } 82 83 return queryClient.ConsensusState(context.Background(), req) 84 } 85 86 // QueryConsensusStateABCI queries the store to get the consensus state of a light client and a 87 // merkle proof of its existence or non-existence. 88 func QueryConsensusStateABCI( 89 clientCtx clictx.CLIContext, clientID string, height exported.Height, 90 ) (*types.QueryConsensusStateResponse, error) { 91 key := host.FullConsensusStateKey(clientID, height) 92 value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key) 93 if err != nil { 94 return nil, err 95 } 96 97 // check if consensus state exists 98 if len(value) == 0 { 99 return nil, sdkerrors.Wrap(types.ErrConsensusStateNotFound, clientID) 100 } 101 102 cdc := clientCtx.CodecProy 103 104 cs, err := types.UnmarshalConsensusState(cdc, value) 105 if err != nil { 106 return nil, err 107 } 108 109 anyConsensusState, err := types.PackConsensusState(cs) 110 if err != nil { 111 return nil, err 112 } 113 114 return types.NewQueryConsensusStateResponse(anyConsensusState, proofBz, proofHeight), nil 115 } 116 117 // QueryTendermintHeader takes a client context and returns the appropriate 118 // tendermint header 119 func QueryTendermintHeader(clientCtx clictx.CLIContext) (ibctmtypes.Header, int64, error) { 120 node, err := clientCtx.GetNode() 121 if err != nil { 122 return ibctmtypes.Header{}, 0, err 123 } 124 125 info, err := node.ABCIInfo() 126 if err != nil { 127 return ibctmtypes.Header{}, 0, err 128 } 129 130 var height int64 131 if clientCtx.Height != 0 { 132 height = clientCtx.Height 133 } else { 134 height = info.Response.LastBlockHeight 135 } 136 137 commit, err := node.Commit(&height) 138 if err != nil { 139 return ibctmtypes.Header{}, 0, err 140 } 141 142 page := 1 143 count := 10_000 144 145 validators, err := node.Validators(&height, page, count) 146 if err != nil { 147 return ibctmtypes.Header{}, 0, err 148 } 149 150 protoCommit := commit.SignedHeader.ToProto() 151 protoValset, err := tmtypes.NewValidatorSet(validators.Validators).ToProto() 152 if err != nil { 153 return ibctmtypes.Header{}, 0, err 154 } 155 156 header := ibctmtypes.Header{ 157 SignedHeader: protoCommit, 158 ValidatorSet: protoValset, 159 } 160 161 return header, height, nil 162 } 163 164 // QueryNodeConsensusState takes a client context and returns the appropriate 165 // tendermint consensus state 166 func QueryNodeConsensusState(clientCtx clictx.CLIContext) (*ibctmtypes.ConsensusState, int64, error) { 167 node, err := clientCtx.GetNode() 168 if err != nil { 169 return &ibctmtypes.ConsensusState{}, 0, err 170 } 171 172 info, err := node.ABCIInfo() 173 if err != nil { 174 return &ibctmtypes.ConsensusState{}, 0, err 175 } 176 177 var height int64 178 if clientCtx.Height != 0 { 179 height = clientCtx.Height 180 } else { 181 height = info.Response.LastBlockHeight 182 } 183 184 commit, err := node.Commit(&height) 185 if err != nil { 186 return &ibctmtypes.ConsensusState{}, 0, err 187 } 188 189 page := 1 190 count := 10_000 191 192 nextHeight := height + 1 193 nextVals, err := node.Validators(&nextHeight, page, count) 194 if err != nil { 195 return &ibctmtypes.ConsensusState{}, 0, err 196 } 197 198 state := &ibctmtypes.ConsensusState{ 199 Timestamp: commit.Time, 200 Root: commitmenttypes.NewMerkleRoot(commit.AppHash), 201 NextValidatorsHash: tmtypes.NewValidatorSet(nextVals.Validators).Hash(height), 202 } 203 204 return state, height, nil 205 } 206 207 // QuerySelfConsensusState takes a client context and returns the appropriate 208 // tendermint consensus state 209 func QuerySelfConsensusState(clientCtx clictx.CLIContext) (*ibctmtypes.ConsensusState, int64, error) { 210 node, err := clientCtx.GetNode() 211 if err != nil { 212 return &ibctmtypes.ConsensusState{}, 0, err 213 } 214 215 info, err := node.ABCIInfo() 216 if err != nil { 217 return &ibctmtypes.ConsensusState{}, 0, err 218 } 219 220 var height int64 221 if clientCtx.Height != 0 { 222 height = clientCtx.Height 223 } else { 224 height = info.Response.LastBlockHeight 225 } 226 227 commit, err := node.Commit(&height) 228 if err != nil { 229 return &ibctmtypes.ConsensusState{}, 0, err 230 } 231 232 page := 1 233 count := 10_000 234 235 nextHeight := height + 1 236 nextVals, err := node.Validators(&nextHeight, page, count) 237 if err != nil { 238 return &ibctmtypes.ConsensusState{}, 0, err 239 } 240 241 state := &ibctmtypes.ConsensusState{ 242 Timestamp: commit.Time, 243 Root: commitmenttypes.NewMerkleRoot(commit.AppHash), 244 NextValidatorsHash: tmtypes.NewValidatorSet(nextVals.Validators).Hash(height), 245 } 246 247 return state, height, nil 248 }