Skip to content

Commit

Permalink
feat(rpc): implementing staking reads and replacing sdk.Address (#1060)
Browse files Browse the repository at this point in the history
* feat: staking reads + linting errors

* feat: rewriting to not take delAddr as a parameter

* refactor(rpc): renaming local variables

* refactor(rpc): using AccAddress and ValAddress instead of the generic Address type
  • Loading branch information
distractedm1nd authored Sep 15, 2022
1 parent ba2d4c7 commit 1803ca0
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 62 deletions.
8 changes: 8 additions & 0 deletions service/rpc/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ func (h *Handler) RegisterEndpoints(rpc *Server) {
rpc.RegisterHandlerFunc(cancelUnbondingEndpoint, h.handleCancelUnbonding, http.MethodPost)
rpc.RegisterHandlerFunc(beginRedelegationEndpoint, h.handleRedelegation, http.MethodPost)

// staking queries
rpc.RegisterHandlerFunc(fmt.Sprintf("%s/{%s}", queryDelegationEndpoint, addrKey), h.handleQueryDelegation,
http.MethodGet)
rpc.RegisterHandlerFunc(fmt.Sprintf("%s/{%s}", queryUnbondingEndpoint, addrKey), h.handleQueryUnbonding,
http.MethodGet)
rpc.RegisterHandlerFunc(queryRedelegationsEndpoint, h.handleQueryRedelegations,
http.MethodPost)

// share endpoints
rpc.RegisterHandlerFunc(fmt.Sprintf("%s/{%s}/height/{%s}", namespacedSharesEndpoint, nIDKey, heightKey),
h.handleSharesByNamespaceRequest, http.MethodGet)
Expand Down
119 changes: 111 additions & 8 deletions service/rpc/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ import (
)

const (
balanceEndpoint = "/balance"
submitTxEndpoint = "/submit_tx"
submitPFDEndpoint = "/submit_pfd"
transferEndpoint = "/transfer"
delegationEndpoint = "/delegate"
undelegationEndpoint = "/begin_unbonding"
cancelUnbondingEndpoint = "/cancel_unbond"
beginRedelegationEndpoint = "/begin_redelegate"
balanceEndpoint = "/balance"
submitTxEndpoint = "/submit_tx"
submitPFDEndpoint = "/submit_pfd"
transferEndpoint = "/transfer"
delegationEndpoint = "/delegate"
undelegationEndpoint = "/begin_unbonding"
cancelUnbondingEndpoint = "/cancel_unbond"
beginRedelegationEndpoint = "/begin_redelegate"
queryDelegationEndpoint = "/query_delegation"
queryUnbondingEndpoint = "/query_unbonding"
queryRedelegationsEndpoint = "/query_redelegations"
)

var addrKey = "address"
Expand Down Expand Up @@ -75,6 +78,11 @@ type cancelUnbondRequest struct {
GasLimit uint64 `json:"gas_limit"`
}

type queryRedelegationsRequest struct {
From string `json:"from"`
To string `json:"to"`
}

func (h *Handler) handleBalanceRequest(w http.ResponseWriter, r *http.Request) {
var (
bal *state.Balance
Expand Down Expand Up @@ -348,3 +356,98 @@ func (h *Handler) handleRedelegation(w http.ResponseWriter, r *http.Request) {
log.Errorw("writing response", "endpoint", beginRedelegationEndpoint, "err", err)
}
}

func (h *Handler) handleQueryDelegation(w http.ResponseWriter, r *http.Request) {
// read and parse request
vars := mux.Vars(r)
addrStr, exists := vars[addrKey]
if !exists {
writeError(w, http.StatusBadRequest, queryDelegationEndpoint, errors.New("address not specified"))
return
}

// convert address to Address type
addr, err := types.ValAddressFromBech32(addrStr)
if err != nil {
writeError(w, http.StatusBadRequest, queryDelegationEndpoint, err)
return
}
delegation, err := h.state.QueryDelegation(r.Context(), addr)
if err != nil {
writeError(w, http.StatusInternalServerError, queryDelegationEndpoint, err)
return
}
resp, err := json.Marshal(delegation)
if err != nil {
writeError(w, http.StatusInternalServerError, queryDelegationEndpoint, err)
return
}
_, err = w.Write(resp)
if err != nil {
log.Errorw("writing response", "endpoint", queryDelegationEndpoint, "err", err)
}
}

func (h *Handler) handleQueryUnbonding(w http.ResponseWriter, r *http.Request) {
// read and parse request
vars := mux.Vars(r)
addrStr, exists := vars[addrKey]
if !exists {
writeError(w, http.StatusBadRequest, queryUnbondingEndpoint, errors.New("address not specified"))
return
}

// convert address to Address type
addr, err := types.ValAddressFromBech32(addrStr)
if err != nil {
writeError(w, http.StatusBadRequest, queryUnbondingEndpoint, err)
return
}
unbonding, err := h.state.QueryUnbonding(r.Context(), addr)
if err != nil {
writeError(w, http.StatusInternalServerError, queryUnbondingEndpoint, err)
return
}
resp, err := json.Marshal(unbonding)
if err != nil {
writeError(w, http.StatusInternalServerError, queryUnbondingEndpoint, err)
return
}
_, err = w.Write(resp)
if err != nil {
log.Errorw("writing response", "endpoint", queryUnbondingEndpoint, "err", err)
}
}

func (h *Handler) handleQueryRedelegations(w http.ResponseWriter, r *http.Request) {
var req queryRedelegationsRequest
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
writeError(w, http.StatusBadRequest, queryRedelegationsEndpoint, err)
return
}
srcValAddr, err := types.ValAddressFromBech32(req.From)
if err != nil {
writeError(w, http.StatusBadRequest, queryRedelegationsEndpoint, err)
return
}
dstValAddr, err := types.ValAddressFromBech32(req.To)
if err != nil {
writeError(w, http.StatusBadRequest, queryRedelegationsEndpoint, err)
return
}
unbonding, err := h.state.QueryRedelegations(r.Context(), srcValAddr, dstValAddr)
if err != nil {
writeError(w, http.StatusInternalServerError, queryRedelegationsEndpoint, err)
return
}
resp, err := json.Marshal(unbonding)
if err != nil {
writeError(w, http.StatusInternalServerError, queryRedelegationsEndpoint, err)
return
}
_, err = w.Write(resp)
if err != nil {
log.Errorw("writing response", "endpoint", queryRedelegationsEndpoint, "err", err)
}
}
97 changes: 60 additions & 37 deletions service/state/core_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ type CoreAccessor struct {
signer *apptypes.KeyringSigner
getter header.Getter

queryCli banktypes.QueryClient
rpcCli rpcclient.ABCIClient
queryCli banktypes.QueryClient
stakingCli stakingtypes.QueryClient
rpcCli rpcclient.ABCIClient

coreConn *grpc.ClientConn
coreIP string
Expand Down Expand Up @@ -74,6 +75,9 @@ func (ca *CoreAccessor) Start(ctx context.Context) error {
// create the query client
queryCli := banktypes.NewQueryClient(ca.coreConn)
ca.queryCli = queryCli
// create the staking query client
stakingCli := stakingtypes.NewQueryClient(ca.coreConn)
ca.stakingCli = stakingCli
// create ABCI query client
cli, err := http.New(fmt.Sprintf("http://%s:%s", ca.coreIP, ca.rpcPort), "/websocket")
if err != nil {
Expand Down Expand Up @@ -132,7 +136,7 @@ func (ca *CoreAccessor) Balance(ctx context.Context) (*Balance, error) {
return ca.BalanceForAddress(ctx, addr)
}

func (ca *CoreAccessor) BalanceForAddress(ctx context.Context, addr Address) (*Balance, error) {
func (ca *CoreAccessor) BalanceForAddress(ctx context.Context, addr AccAddress) (*Balance, error) {
head, err := ca.getter.Head(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -215,20 +219,16 @@ func (ca *CoreAccessor) SubmitTxWithBroadcastMode(

func (ca *CoreAccessor) Transfer(
ctx context.Context,
addr Address,
addr AccAddress,
amount Int,
gasLim uint64,
) (*TxResponse, error) {
to, ok := addr.(sdktypes.AccAddress)
if !ok {
return nil, fmt.Errorf("state: unsupported address type")
}
from, err := ca.signer.GetSignerInfo().GetAddress()
if err != nil {
return nil, err
}
coins := sdktypes.NewCoins(sdktypes.NewCoin(app.BondDenom, amount))
msg := banktypes.NewMsgSend(from, to, coins)
msg := banktypes.NewMsgSend(from, addr, coins)
signedTx, err := ca.constructSignedTx(ctx, msg, apptypes.SetGasLimit(gasLim))
if err != nil {
return nil, err
Expand All @@ -238,21 +238,17 @@ func (ca *CoreAccessor) Transfer(

func (ca *CoreAccessor) CancelUnbondingDelegation(
ctx context.Context,
valAddr Address,
valAddr ValAddress,
amount,
height Int,
gasLim uint64,
) (*TxResponse, error) {
validator, ok := valAddr.(sdktypes.ValAddress)
if !ok {
return nil, fmt.Errorf("state: unsupported address type")
}
from, err := ca.signer.GetSignerInfo().GetAddress()
if err != nil {
return nil, err
}
coins := sdktypes.NewCoin(app.BondDenom, amount)
msg := stakingtypes.NewMsgCancelUnbondingDelegation(from, validator, height.Int64(), coins)
msg := stakingtypes.NewMsgCancelUnbondingDelegation(from, valAddr, height.Int64(), coins)
signedTx, err := ca.constructSignedTx(ctx, msg, apptypes.SetGasLimit(gasLim))
if err != nil {
return nil, err
Expand All @@ -263,24 +259,16 @@ func (ca *CoreAccessor) CancelUnbondingDelegation(
func (ca *CoreAccessor) BeginRedelegate(
ctx context.Context,
srcValAddr,
dstValAddr Address,
dstValAddr ValAddress,
amount Int,
gasLim uint64,
) (*TxResponse, error) {
srcValidator, ok := srcValAddr.(sdktypes.ValAddress)
if !ok {
return nil, fmt.Errorf("state: unsupported address type")
}
dstValidator, ok := dstValAddr.(sdktypes.ValAddress)
if !ok {
return nil, fmt.Errorf("state: unsupported address type")
}
from, err := ca.signer.GetSignerInfo().GetAddress()
if err != nil {
return nil, err
}
coins := sdktypes.NewCoin(app.BondDenom, amount)
msg := stakingtypes.NewMsgBeginRedelegate(from, srcValidator, dstValidator, coins)
msg := stakingtypes.NewMsgBeginRedelegate(from, srcValAddr, dstValAddr, coins)
signedTx, err := ca.constructSignedTx(ctx, msg, apptypes.SetGasLimit(gasLim))
if err != nil {
return nil, err
Expand All @@ -290,20 +278,16 @@ func (ca *CoreAccessor) BeginRedelegate(

func (ca *CoreAccessor) Undelegate(
ctx context.Context,
delAddr Address,
delAddr ValAddress,
amount Int,
gasLim uint64,
) (*TxResponse, error) {
delegate, ok := delAddr.(sdktypes.ValAddress)
if !ok {
return nil, fmt.Errorf("state: unsupported address type")
}
from, err := ca.signer.GetSignerInfo().GetAddress()
if err != nil {
return nil, err
}
coins := sdktypes.NewCoin(app.BondDenom, amount)
msg := stakingtypes.NewMsgUndelegate(from, delegate, coins)
msg := stakingtypes.NewMsgUndelegate(from, delAddr, coins)
signedTx, err := ca.constructSignedTx(ctx, msg, apptypes.SetGasLimit(gasLim))
if err != nil {
return nil, err
Expand All @@ -313,23 +297,62 @@ func (ca *CoreAccessor) Undelegate(

func (ca *CoreAccessor) Delegate(
ctx context.Context,
delAddr Address,
delAddr ValAddress,
amount Int,
gasLim uint64,
) (*TxResponse, error) {
delegate, ok := delAddr.(sdktypes.ValAddress)
if !ok {
return nil, fmt.Errorf("state: unsupported address type")
}
from, err := ca.signer.GetSignerInfo().GetAddress()
if err != nil {
return nil, err
}
coins := sdktypes.NewCoin(app.BondDenom, amount)
msg := stakingtypes.NewMsgDelegate(from, delegate, coins)
msg := stakingtypes.NewMsgDelegate(from, delAddr, coins)
signedTx, err := ca.constructSignedTx(ctx, msg, apptypes.SetGasLimit(gasLim))
if err != nil {
return nil, err
}
return ca.SubmitTx(ctx, signedTx)
}

func (ca *CoreAccessor) QueryDelegation(
ctx context.Context,
valAddr ValAddress,
) (*stakingtypes.QueryDelegationResponse, error) {
delAddr, err := ca.signer.GetSignerInfo().GetAddress()
if err != nil {
return nil, err
}
return ca.stakingCli.Delegation(ctx, &stakingtypes.QueryDelegationRequest{
DelegatorAddr: delAddr.String(),
ValidatorAddr: valAddr.String(),
})
}

func (ca *CoreAccessor) QueryUnbonding(
ctx context.Context,
valAddr ValAddress,
) (*stakingtypes.QueryUnbondingDelegationResponse, error) {
delAddr, err := ca.signer.GetSignerInfo().GetAddress()
if err != nil {
return nil, err
}
return ca.stakingCli.UnbondingDelegation(ctx, &stakingtypes.QueryUnbondingDelegationRequest{
DelegatorAddr: delAddr.String(),
ValidatorAddr: valAddr.String(),
})
}
func (ca *CoreAccessor) QueryRedelegations(
ctx context.Context,
srcValAddr,
dstValAddr ValAddress,
) (*stakingtypes.QueryRedelegationsResponse, error) {
delAddr, err := ca.signer.GetSignerInfo().GetAddress()
if err != nil {
return nil, err
}
return ca.stakingCli.Redelegations(ctx, &stakingtypes.QueryRedelegationsRequest{
DelegatorAddr: delAddr.String(),
SrcValidatorAddr: srcValAddr.String(),
DstValidatorAddr: dstValAddr.String(),
})
}
Loading

0 comments on commit 1803ca0

Please sign in to comment.