github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/staking/client/rest/query.go (about) 1 package rest 2 3 import ( 4 "fmt" 5 "net/http" 6 "strconv" 7 "strings" 8 9 "github.com/gorilla/mux" 10 11 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context" 12 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 13 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/rest" 14 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types" 15 ) 16 17 func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { 18 // Get all delegations from a delegator 19 r.HandleFunc( 20 "/staking/delegators/{delegatorAddr}/delegations", 21 delegatorDelegationsHandlerFn(cliCtx), 22 ).Methods("GET") 23 24 // Get all unbonding delegations from a delegator 25 r.HandleFunc( 26 "/staking/delegators/{delegatorAddr}/unbonding_delegations", 27 delegatorUnbondingDelegationsHandlerFn(cliCtx), 28 ).Methods("GET") 29 30 // Get all staking txs (i.e msgs) from a delegator 31 r.HandleFunc( 32 "/staking/delegators/{delegatorAddr}/txs", 33 delegatorTxsHandlerFn(cliCtx), 34 ).Methods("GET") 35 36 // Query all validators that a delegator is bonded to 37 r.HandleFunc( 38 "/staking/delegators/{delegatorAddr}/validators", 39 delegatorValidatorsHandlerFn(cliCtx), 40 ).Methods("GET") 41 42 // Query a validator that a delegator is bonded to 43 r.HandleFunc( 44 "/staking/delegators/{delegatorAddr}/validators/{validatorAddr}", 45 delegatorValidatorHandlerFn(cliCtx), 46 ).Methods("GET") 47 48 // Query a delegation between a delegator and a validator 49 r.HandleFunc( 50 "/staking/delegators/{delegatorAddr}/delegations/{validatorAddr}", 51 delegationHandlerFn(cliCtx), 52 ).Methods("GET") 53 54 // Query all unbonding delegations between a delegator and a validator 55 r.HandleFunc( 56 "/staking/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}", 57 unbondingDelegationHandlerFn(cliCtx), 58 ).Methods("GET") 59 60 // Query redelegations (filters in query params) 61 r.HandleFunc( 62 "/staking/redelegations", 63 redelegationsHandlerFn(cliCtx), 64 ).Methods("GET") 65 66 // Get all validators 67 r.HandleFunc( 68 "/staking/validators", 69 validatorsHandlerFn(cliCtx), 70 ).Methods("GET") 71 72 // Get a single validator info 73 r.HandleFunc( 74 "/staking/validators/{validatorAddr}", 75 validatorHandlerFn(cliCtx), 76 ).Methods("GET") 77 78 // Get all delegations to a validator 79 r.HandleFunc( 80 "/staking/validators/{validatorAddr}/delegations", 81 validatorDelegationsHandlerFn(cliCtx), 82 ).Methods("GET") 83 84 // Get all unbonding delegations from a validator 85 r.HandleFunc( 86 "/staking/validators/{validatorAddr}/unbonding_delegations", 87 validatorUnbondingDelegationsHandlerFn(cliCtx), 88 ).Methods("GET") 89 90 // Get HistoricalInfo at a given height 91 r.HandleFunc( 92 "/staking/historical_info/{height}", 93 historicalInfoHandlerFn(cliCtx), 94 ).Methods("GET") 95 96 // Get the current state of the staking pool 97 r.HandleFunc( 98 "/staking/pool", 99 poolHandlerFn(cliCtx), 100 ).Methods("GET") 101 102 // Get the current staking parameter values 103 r.HandleFunc( 104 "/staking/parameters", 105 paramsHandlerFn(cliCtx), 106 ).Methods("GET") 107 108 } 109 110 // HTTP request handler to query a delegator delegations 111 func delegatorDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 112 return queryDelegator(cliCtx, fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryDelegatorDelegations)) 113 } 114 115 // HTTP request handler to query a delegator unbonding delegations 116 func delegatorUnbondingDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 117 return queryDelegator(cliCtx, "custom/staking/delegatorUnbondingDelegations") 118 } 119 120 // HTTP request handler to query all staking txs (msgs) from a delegator 121 func delegatorTxsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 122 return func(w http.ResponseWriter, r *http.Request) { 123 var typesQuerySlice []string 124 vars := mux.Vars(r) 125 delegatorAddr := vars["delegatorAddr"] 126 127 _, err := sdk.AccAddressFromBech32(delegatorAddr) 128 if err != nil { 129 rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) 130 return 131 } 132 133 cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) 134 if !ok { 135 return 136 } 137 138 typesQuery := r.URL.Query().Get("type") 139 trimmedQuery := strings.TrimSpace(typesQuery) 140 if len(trimmedQuery) != 0 { 141 typesQuerySlice = strings.Split(trimmedQuery, " ") 142 } 143 144 noQuery := len(typesQuerySlice) == 0 145 isBondTx := contains(typesQuerySlice, "bond") 146 isUnbondTx := contains(typesQuerySlice, "unbond") 147 isRedTx := contains(typesQuerySlice, "redelegate") 148 149 var ( 150 txs []*sdk.SearchTxsResult 151 actions []string 152 ) 153 154 switch { 155 case isBondTx: 156 actions = append(actions, types.MsgDelegate{}.Type()) 157 158 case isUnbondTx: 159 actions = append(actions, types.MsgUndelegate{}.Type()) 160 161 case isRedTx: 162 actions = append(actions, types.MsgBeginRedelegate{}.Type()) 163 164 case noQuery: 165 actions = append(actions, types.MsgDelegate{}.Type()) 166 actions = append(actions, types.MsgUndelegate{}.Type()) 167 actions = append(actions, types.MsgBeginRedelegate{}.Type()) 168 169 default: 170 w.WriteHeader(http.StatusNoContent) 171 return 172 } 173 174 for _, action := range actions { 175 foundTxs, errQuery := queryTxs(cliCtx, action, delegatorAddr) 176 if errQuery != nil { 177 rest.WriteErrorResponse(w, http.StatusInternalServerError, errQuery.Error()) 178 } 179 txs = append(txs, foundTxs) 180 } 181 182 res, err := cliCtx.Codec.MarshalJSON(txs) 183 if err != nil { 184 rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) 185 return 186 } 187 188 rest.PostProcessResponseBare(w, cliCtx, res) 189 } 190 } 191 192 // HTTP request handler to query an unbonding-delegation 193 func unbondingDelegationHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 194 return queryBonds(cliCtx, "custom/staking/unbondingDelegation") 195 } 196 197 // HTTP request handler to query redelegations 198 func redelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 199 return func(w http.ResponseWriter, r *http.Request) { 200 var params types.QueryRedelegationParams 201 202 cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) 203 if !ok { 204 return 205 } 206 207 bechDelegatorAddr := r.URL.Query().Get("delegator") 208 bechSrcValidatorAddr := r.URL.Query().Get("validator_from") 209 bechDstValidatorAddr := r.URL.Query().Get("validator_to") 210 211 if len(bechDelegatorAddr) != 0 { 212 delegatorAddr, err := sdk.AccAddressFromBech32(bechDelegatorAddr) 213 if err != nil { 214 rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) 215 return 216 } 217 params.DelegatorAddr = delegatorAddr 218 } 219 220 if len(bechSrcValidatorAddr) != 0 { 221 srcValidatorAddr, err := sdk.ValAddressFromBech32(bechSrcValidatorAddr) 222 if err != nil { 223 rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) 224 return 225 } 226 params.SrcValidatorAddr = srcValidatorAddr 227 } 228 229 if len(bechDstValidatorAddr) != 0 { 230 dstValidatorAddr, err := sdk.ValAddressFromBech32(bechDstValidatorAddr) 231 if err != nil { 232 rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) 233 return 234 } 235 params.DstValidatorAddr = dstValidatorAddr 236 } 237 238 bz, err := cliCtx.Codec.MarshalJSON(params) 239 if err != nil { 240 rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) 241 return 242 } 243 244 res, height, err := cliCtx.QueryWithData("custom/staking/redelegations", bz) 245 if err != nil { 246 rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) 247 return 248 } 249 250 cliCtx = cliCtx.WithHeight(height) 251 rest.PostProcessResponse(w, cliCtx, res) 252 } 253 } 254 255 // HTTP request handler to query a delegation 256 func delegationHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 257 return queryBonds(cliCtx, fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryDelegation)) 258 } 259 260 // HTTP request handler to query all delegator bonded validators 261 func delegatorValidatorsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 262 return queryDelegator(cliCtx, "custom/staking/delegatorValidators") 263 } 264 265 // HTTP request handler to get information from a currently bonded validator 266 func delegatorValidatorHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 267 return queryBonds(cliCtx, "custom/staking/delegatorValidator") 268 } 269 270 // HTTP request handler to query list of validators 271 func validatorsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 272 return func(w http.ResponseWriter, r *http.Request) { 273 _, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0) 274 if err != nil { 275 rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) 276 return 277 } 278 279 cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) 280 if !ok { 281 return 282 } 283 284 status := r.FormValue("status") 285 if status == "" { 286 status = sdk.BondStatusBonded 287 } 288 289 params := types.NewQueryValidatorsParams(page, limit, status) 290 bz, err := cliCtx.Codec.MarshalJSON(params) 291 if err != nil { 292 rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) 293 return 294 } 295 296 route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryValidators) 297 res, height, err := cliCtx.QueryWithData(route, bz) 298 if err != nil { 299 rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) 300 return 301 } 302 303 cliCtx = cliCtx.WithHeight(height) 304 rest.PostProcessResponse(w, cliCtx, res) 305 } 306 } 307 308 // HTTP request handler to query the validator information from a given validator address 309 func validatorHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 310 return queryValidator(cliCtx, "custom/staking/validator") 311 } 312 313 // HTTP request handler to query all unbonding delegations from a validator 314 func validatorDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 315 return queryValidator(cliCtx, fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryValidatorDelegations)) 316 } 317 318 // HTTP request handler to query all unbonding delegations from a validator 319 func validatorUnbondingDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 320 return queryValidator(cliCtx, "custom/staking/validatorUnbondingDelegations") 321 } 322 323 // HTTP request handler to query historical info at a given height 324 func historicalInfoHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 325 return func(w http.ResponseWriter, r *http.Request) { 326 vars := mux.Vars(r) 327 heightStr := vars["height"] 328 height, err := strconv.ParseInt(heightStr, 10, 64) 329 if err != nil || height < 0 { 330 rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("Must provide non-negative integer for height: %v", err)) 331 return 332 } 333 334 params := types.NewQueryHistoricalInfoParams(height) 335 bz, err := cliCtx.Codec.MarshalJSON(params) 336 if err != nil { 337 rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) 338 return 339 } 340 341 route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryHistoricalInfo) 342 res, height, err := cliCtx.QueryWithData(route, bz) 343 if err != nil { 344 rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) 345 return 346 } 347 348 cliCtx = cliCtx.WithHeight(height) 349 rest.PostProcessResponse(w, cliCtx, res) 350 } 351 } 352 353 // HTTP request handler to query the pool information 354 func poolHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 355 return func(w http.ResponseWriter, r *http.Request) { 356 cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) 357 if !ok { 358 return 359 } 360 361 res, height, err := cliCtx.QueryWithData("custom/staking/pool", nil) 362 if err != nil { 363 rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) 364 return 365 } 366 367 cliCtx = cliCtx.WithHeight(height) 368 rest.PostProcessResponse(w, cliCtx, res) 369 } 370 } 371 372 // HTTP request handler to query the staking params values 373 func paramsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { 374 return func(w http.ResponseWriter, r *http.Request) { 375 cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) 376 if !ok { 377 return 378 } 379 380 res, height, err := cliCtx.QueryWithData("custom/staking/parameters", nil) 381 if err != nil { 382 rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) 383 return 384 } 385 386 cliCtx = cliCtx.WithHeight(height) 387 rest.PostProcessResponse(w, cliCtx, res) 388 } 389 }