func (s TransactionService) getTransactionAndStatus(txID types.TransactionID) (retTx *types.Transaction, state pb.TransactionState_TransactionState) {
	tx, err := s.Mesh.GetMeshTransaction(txID)  
	if err != nil {
		retTx, err = s.Mempool.Get(txID)  
		if err != nil {                   
			return
		}
		state = pb.TransactionState_TRANSACTION_STATE_MEMPOOL
		return
	}
	retTx = &tx.Transaction
	layer := s.Mesh.GetLayerApplied(txID)
	if layer != nil {
		state = pb.TransactionState_TRANSACTION_STATE_PROCESSED
	} else {
		nonce := s.Mesh.GetNonce(tx.Origin())
		if nonce > tx.AccountNonce {
			state = pb.TransactionState_TRANSACTION_STATE_REJECTED
		} else {
			state = pb.TransactionState_TRANSACTION_STATE_MESH
		}
	}
	return
}
Get transaction and status for a given txid. It's not an error if we cannot find the tx,
we just return all nils.
package grpcserver
import (
	"bytes"
	"context"
	"fmt"
	pb "github.com/spacemeshos/api/release/go/spacemesh/v1"
	"google.golang.org/genproto/googleapis/rpc/code"
	rpcstatus "google.golang.org/genproto/googleapis/rpc/status"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"github.com/spacemeshos/go-spacemesh/api"
	"github.com/spacemeshos/go-spacemesh/common/types"
	"github.com/spacemeshos/go-spacemesh/events"
	"github.com/spacemeshos/go-spacemesh/log"
	"github.com/spacemeshos/go-spacemesh/svm/state"
)
type TransactionService struct {
	publisher api.Publisher  
	Mesh      api.TxAPI      
	Mempool   api.MempoolAPI
	syncer    api.Syncer
}
func (s TransactionService) RegisterService(server *Server) {
	pb.RegisterTransactionServiceServer(server.GrpcServer, s)
}
func NewTransactionService(
	publisher api.Publisher,
	tx api.TxAPI,
	mempool api.MempoolAPI,
	syncer api.Syncer,
) *TransactionService {
	return &TransactionService{
		publisher: publisher,
		Mesh:      tx,
		Mempool:   mempool,
		syncer:    syncer,
	}
}
func (s TransactionService) SubmitTransaction(ctx context.Context, in *pb.SubmitTransactionRequest) (*pb.SubmitTransactionResponse, error) {
	log.Info("GRPC TransactionService.SubmitTransaction")
	if len(in.Transaction) == 0 {
		return nil, status.Error(codes.InvalidArgument, "`Transaction` payload empty")
	}
	if !s.syncer.IsSynced(ctx) {
		return nil, status.Error(codes.FailedPrecondition,
			"Cannot submit transaction, node is not in sync yet, try again later")
	}
	tx, err := types.BytesToTransaction(in.Transaction)
	if err != nil {
		log.Error("failed to deserialize tx, error: %v", err)
		return nil, status.Error(codes.InvalidArgument,
			"`Transaction` must contain a valid, serialized transaction")
	}
	if err := tx.CalcAndSetOrigin(); err != nil {
		log.Error("failed to calculate tx origin: %v", err)
		return nil, status.Error(codes.InvalidArgument,
			"`Transaction` must contain a valid, serialized transaction")
	}
	if !s.Mesh.AddressExists(tx.Origin()) {
		log.With().Error("tx origin address not found in global state",
			tx.ID(), log.String("origin", tx.Origin().Short()))
		return nil, status.Error(codes.InvalidArgument, "`Transaction` origin account not found")
	}
	if err := s.Mesh.ValidateNonceAndBalance(tx); err != nil {
		log.Error("tx failed nonce and balance check: %v", err)
		return nil, status.Error(codes.InvalidArgument, "`Transaction` incorrect counter or insufficient balance")
	}
	log.Info("GRPC TransactionService.SubmitTransaction BROADCAST tx address: %x (len: %v), amount: %v, gas limit: %v, fee: %v, id: %v, nonce: %v",
		tx.Recipient, len(tx.Recipient), tx.Amount, tx.GasLimit, tx.Fee, tx.ID().ShortString(), tx.AccountNonce)
	go func() {
		if err := s.publisher.Publish(ctx, state.IncomingTxProtocol, in.Transaction); err != nil {
			log.Error("error broadcasting incoming tx: %v", err)
		}
	}()
	return &pb.SubmitTransactionResponse{
		Status: &rpcstatus.Status{Code: int32(code.Code_OK)},
		Txstate: &pb.TransactionState{
			Id:    &pb.TransactionId{Id: tx.ID().Bytes()},
			State: pb.TransactionState_TRANSACTION_STATE_MEMPOOL,
		},
	}, nil
}