0g-chain/x/bep3/keeper/grpc_query.go
2024-04-25 15:31:20 +08:00

182 lines
5.4 KiB
Go

package keeper
import (
"context"
"encoding/hex"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/0glabs/0g-chain/x/bep3/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 queries module params
func (s queryServer) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
params := s.keeper.GetParams(sdkCtx)
return &types.QueryParamsResponse{Params: params}, nil
}
// AssetSupply queries info about an asset's supply
func (s queryServer) AssetSupply(ctx context.Context, req *types.QueryAssetSupplyRequest) (*types.QueryAssetSupplyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
assetSupply, ok := s.keeper.GetAssetSupply(sdkCtx, req.Denom)
if !ok {
return nil, status.Errorf(codes.NotFound, "denom not found")
}
return &types.QueryAssetSupplyResponse{AssetSupply: mapAssetSupplyToResponse(assetSupply)}, nil
}
// AssetSupplies queries a list of asset supplies
func (s queryServer) AssetSupplies(ctx context.Context, req *types.QueryAssetSuppliesRequest) (*types.QueryAssetSuppliesResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
var queryResults []types.AssetSupplyResponse
s.keeper.IterateAssetSupplies(sdkCtx, func(assetSupply types.AssetSupply) bool {
queryResults = append(queryResults, mapAssetSupplyToResponse(assetSupply))
return false
})
return &types.QueryAssetSuppliesResponse{
AssetSupplies: queryResults,
}, nil
}
// AtomicSwap queries info about an atomic swap
func (s queryServer) AtomicSwap(ctx context.Context, req *types.QueryAtomicSwapRequest) (*types.QueryAtomicSwapResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
swapId, err := hex.DecodeString(req.SwapId)
if err != nil {
return nil, status.Errorf(codes.NotFound, "invalid atomic swap id")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
atomicSwap, ok := s.keeper.GetAtomicSwap(sdkCtx, swapId)
if !ok {
return nil, status.Errorf(codes.NotFound, "invalid atomic swap")
}
return &types.QueryAtomicSwapResponse{
AtomicSwap: mapAtomicSwapToResponse(atomicSwap),
}, nil
}
// AtomicSwaps queries a list of atomic swaps
func (s queryServer) AtomicSwaps(ctx context.Context, req *types.QueryAtomicSwapsRequest) (*types.QueryAtomicSwapsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
store := prefix.NewStore(sdkCtx.KVStore(s.keeper.key), types.AtomicSwapKeyPrefix)
var queryResults []types.AtomicSwapResponse
pageRes, err := query.FilteredPaginate(store, req.Pagination, func(_, value []byte, shouldAccumulate bool) (bool, error) {
var atomicSwap types.AtomicSwap
err := s.keeper.cdc.Unmarshal(value, &atomicSwap)
if err != nil {
return false, err
}
if len(req.Involve) > 0 {
if atomicSwap.Sender.String() != req.Involve && atomicSwap.Recipient.String() != req.Involve {
return false, nil
}
}
// match expiration block limit (if supplied)
if req.Expiration > 0 {
if atomicSwap.ExpireHeight > req.Expiration {
return false, nil
}
}
// match status (if supplied/valid)
if req.Status.IsValid() {
if atomicSwap.Status != req.Status {
return false, nil
}
}
// match direction (if supplied/valid)
if req.Direction.IsValid() {
if atomicSwap.Direction != req.Direction {
return false, nil
}
}
if shouldAccumulate {
queryResults = append(queryResults, mapAtomicSwapToResponse(atomicSwap))
}
return true, nil
})
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err)
}
return &types.QueryAtomicSwapsResponse{
AtomicSwaps: queryResults,
Pagination: pageRes,
}, nil
}
func mapAssetSupplyToResponse(assetSupply types.AssetSupply) types.AssetSupplyResponse {
return types.AssetSupplyResponse{
IncomingSupply: assetSupply.IncomingSupply,
OutgoingSupply: assetSupply.OutgoingSupply,
CurrentSupply: assetSupply.CurrentSupply,
TimeLimitedCurrentSupply: assetSupply.TimeLimitedCurrentSupply,
TimeElapsed: assetSupply.TimeElapsed,
}
}
func mapAtomicSwapToResponse(atomicSwap types.AtomicSwap) types.AtomicSwapResponse {
return types.AtomicSwapResponse{
Id: atomicSwap.GetSwapID().String(),
Amount: atomicSwap.Amount,
RandomNumberHash: atomicSwap.RandomNumberHash.String(),
ExpireHeight: atomicSwap.ExpireHeight,
Timestamp: atomicSwap.Timestamp,
Sender: atomicSwap.Sender.String(),
Recipient: atomicSwap.Recipient.String(),
SenderOtherChain: atomicSwap.SenderOtherChain,
RecipientOtherChain: atomicSwap.RecipientOtherChain,
ClosedBlock: atomicSwap.ClosedBlock,
Status: atomicSwap.Status,
CrossChain: atomicSwap.CrossChain,
Direction: atomicSwap.Direction,
}
}