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  }