github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/auth/client/utils/service.go (about)

     1  package utils
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	gogogrpc "github.com/gogo/protobuf/grpc"
     9  
    10  	"github.com/gogo/protobuf/proto"
    11  	"google.golang.org/grpc/codes"
    12  	"google.golang.org/grpc/status"
    13  
    14  	cliContext "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    15  	codectypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    17  	typeadapter "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/ibc-adapter"
    18  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/query"
    19  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/tx"
    20  )
    21  
    22  var _ tx.ServiceServer = txServer{}
    23  
    24  const (
    25  	eventFormat = "{eventType}.{eventAttribute}={value}"
    26  )
    27  
    28  type baseAppSimulateFn func(txBytes []byte) (types.GasInfo, *types.Result, error)
    29  
    30  // txServer is the server for the protobuf Tx service.
    31  type txServer struct {
    32  	clientCtx         cliContext.CLIContext
    33  	simulate          baseAppSimulateFn
    34  	interfaceRegistry codectypes.InterfaceRegistry
    35  }
    36  
    37  // NewTxServer creates a new Tx service server.
    38  func NewTxServer(clientCtx cliContext.CLIContext, simulate baseAppSimulateFn, interfaceRegistry codectypes.InterfaceRegistry) tx.ServiceServer {
    39  	return txServer{
    40  		clientCtx:         clientCtx,
    41  		simulate:          simulate,
    42  		interfaceRegistry: interfaceRegistry,
    43  	}
    44  }
    45  
    46  func (t txServer) Simulate(ctx context.Context, req *tx.SimulateRequest) (*tx.SimulateResponse, error) {
    47  	if req == nil {
    48  		return nil, status.Error(codes.InvalidArgument, "invalid empty tx")
    49  	}
    50  
    51  	txBytes := req.TxBytes
    52  	if txBytes == nil && req.Tx != nil {
    53  		// This block is for backwards-compatibility.
    54  		// We used to support passing a `Tx` in req. But if we do that, sig
    55  		// verification might not pass, because the .Marshal() below might not
    56  		// be the same marshaling done by the client.
    57  		var err error
    58  		txBytes, err = proto.Marshal(req.Tx)
    59  		if err != nil {
    60  			return nil, status.Errorf(codes.InvalidArgument, "invalid tx; %v", err)
    61  		}
    62  	}
    63  
    64  	if txBytes == nil {
    65  		return nil, status.Errorf(codes.InvalidArgument, "empty txBytes is not allowed")
    66  	}
    67  
    68  	gasInfo, res, err := t.simulate(txBytes)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	return &tx.SimulateResponse{
    74  		GasInfo: &typeadapter.GasInfo{
    75  			GasWanted: gasInfo.GasWanted,
    76  			GasUsed:   gasInfo.GasUsed,
    77  		},
    78  		Result: ConvCM39SimulateResultTCM40(res),
    79  	}, nil
    80  }
    81  
    82  func (t txServer) GetTx(ctx context.Context, req *tx.GetTxRequest) (*tx.GetTxResponse, error) {
    83  	if req == nil {
    84  		return nil, status.Error(codes.InvalidArgument, "request cannot be nil")
    85  	}
    86  
    87  	if len(req.Hash) == 0 {
    88  		return nil, status.Error(codes.InvalidArgument, "tx hash cannot be empty")
    89  	}
    90  
    91  	result, err := Query40Tx(t.clientCtx, req.Hash)
    92  	if nil != err {
    93  		return nil, err
    94  	}
    95  
    96  	protoTx, ok := result.Tx.GetCachedValue().(*tx.Tx)
    97  	if !ok {
    98  		return nil, status.Errorf(codes.Internal, "expected %T, got %T", tx.Tx{}, result.Tx.GetCachedValue())
    99  	}
   100  
   101  	return &tx.GetTxResponse{
   102  		Tx:         protoTx,
   103  		TxResponse: result,
   104  	}, nil
   105  }
   106  
   107  func (t txServer) BroadcastTx(ctx context.Context, request *tx.BroadcastTxRequest) (*tx.BroadcastTxResponse, error) {
   108  	resp, err := cliContext.TxServiceBroadcast(ctx, t.clientCtx, request)
   109  	if nil != err {
   110  		return nil, err
   111  	}
   112  	ret := new(tx.BroadcastTxResponse)
   113  	ret.HandleResponse(t.clientCtx.CodecProy, resp)
   114  	return ret, nil
   115  }
   116  
   117  func (t txServer) GetTxsEvent(ctx context.Context, req *tx.GetTxsEventRequest) (*tx.GetTxsEventResponse, error) {
   118  	if req == nil {
   119  		return nil, status.Error(codes.InvalidArgument, "request cannot be nil")
   120  	}
   121  
   122  	page := 1
   123  	// Tendermint node.TxSearch that is used for querying txs defines pages starting from 1,
   124  	// so we default to 1 if not provided in the request.
   125  	limit := query.DefaultLimit
   126  
   127  	if len(req.Events) == 0 {
   128  		return nil, status.Error(codes.InvalidArgument, "must declare at least one event to search")
   129  	}
   130  
   131  	for _, event := range req.Events {
   132  		if !strings.Contains(event, "=") || strings.Count(event, "=") > 1 {
   133  			return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid event; event %s should be of the format: %s", event, eventFormat))
   134  		}
   135  	}
   136  
   137  	result, err := Query40TxsByEvents(t.clientCtx, req.Events, page, limit)
   138  	if err != nil {
   139  		return nil, err
   140  	}
   141  
   142  	// Create a proto codec, we need it to unmarshal the tx bytes.
   143  	txsList := make([]*tx.Tx, len(result.Txs))
   144  
   145  	for i, txx := range result.Txs {
   146  		protoTx, ok := txx.Tx.GetCachedValue().(*tx.Tx)
   147  		if !ok {
   148  			return nil, status.Errorf(codes.Internal, "expected %T, got %T", tx.Tx{}, txx.Tx.GetCachedValue())
   149  		}
   150  
   151  		txsList[i] = protoTx
   152  	}
   153  
   154  	return &tx.GetTxsEventResponse{
   155  		Txs:         txsList,
   156  		TxResponses: result.Txs,
   157  	}, nil
   158  }
   159  
   160  // RegisterTxService registers the tx service on the gRPC router.
   161  func RegisterTxService(
   162  	qrt gogogrpc.Server,
   163  	clientCtx cliContext.CLIContext,
   164  	simulateFn baseAppSimulateFn,
   165  	interfaceRegistry codectypes.InterfaceRegistry,
   166  ) {
   167  	tx.RegisterServiceServer(
   168  		qrt,
   169  		NewTxServer(clientCtx, simulateFn, interfaceRegistry),
   170  	)
   171  }