0g-chain/x/savings/keeper/grpc_query.go
2024-08-02 12:22:00 +08:00

143 lines
3.6 KiB
Go

package keeper
import (
"context"
"strings"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
errorsmod "cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/0glabs/0g-chain/x/savings/types"
)
type queryServer struct {
keeper Keeper
}
// NewQueryServerImpl creates a new server for handling gRPC queries.
func NewQueryServerImpl(k Keeper) types.QueryServer {
return &queryServer{keeper: k}
}
var _ types.QueryServer = queryServer{}
// Params implements the gRPC service handler for querying x/savings parameters.
func (s queryServer) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(c)
params := s.keeper.GetParams(sdkCtx)
return &types.QueryParamsResponse{Params: params}, nil
}
func (s queryServer) Deposits(ctx context.Context, req *types.QueryDepositsRequest) (*types.QueryDepositsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
hasDenom := len(req.Denom) > 0
hasOwner := len(req.Owner) > 0
var owner sdk.AccAddress
var err error
if hasOwner {
owner, err = sdk.AccAddressFromBech32(req.Owner)
if err != nil {
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidAddress, err.Error())
}
}
var deposits types.Deposits
switch {
case hasOwner && hasDenom:
deposit, found := s.keeper.GetDeposit(sdkCtx, owner)
if found {
for _, coin := range deposit.Amount {
if coin.Denom == req.Denom {
deposits = append(deposits, deposit)
}
}
}
case hasOwner:
deposit, found := s.keeper.GetDeposit(sdkCtx, owner)
if found {
deposits = append(deposits, deposit)
}
case hasDenom:
s.keeper.IterateDeposits(sdkCtx, func(deposit types.Deposit) (stop bool) {
if deposit.Amount.AmountOf(req.Denom).IsPositive() {
deposits = append(deposits, deposit)
}
return false
})
default:
s.keeper.IterateDeposits(sdkCtx, func(deposit types.Deposit) (stop bool) {
deposits = append(deposits, deposit)
return false
})
}
page, limit, err := query.ParsePagination(req.Pagination)
if err != nil {
return nil, err
}
start, end := client.Paginate(len(deposits), page, limit, 100)
if start < 0 || end < 0 {
deposits = types.Deposits{}
} else {
deposits = deposits[start:end]
}
return &types.QueryDepositsResponse{
Deposits: deposits,
Pagination: nil,
}, nil
}
func (s queryServer) TotalSupply(ctx context.Context, req *types.QueryTotalSupplyRequest) (*types.QueryTotalSupplyResponse, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
totalSupply := sdk.NewCoins()
liquidStakedDerivatives := sdk.NewCoins()
s.keeper.IterateDeposits(sdkCtx, func(deposit types.Deposit) (stop bool) {
for _, c := range deposit.Amount {
// separate out bkava denoms
if strings.HasPrefix(c.Denom, bkavaPrefix) {
liquidStakedDerivatives = liquidStakedDerivatives.Add(c)
} else {
totalSupply = totalSupply.Add(c)
}
}
return false
})
// determine underlying value of bkava denoms
if len(liquidStakedDerivatives) > 0 {
underlyingValue, err := s.keeper.liquidKeeper.GetStakedTokensForDerivatives(
sdkCtx,
liquidStakedDerivatives,
)
if err != nil {
return nil, err
}
totalSupply = totalSupply.Add(sdk.NewCoin(bkavaDenom, underlyingValue.Amount))
}
return &types.QueryTotalSupplyResponse{
Height: sdkCtx.BlockHeight(),
Result: totalSupply,
}, nil
}