github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/access/legacy/handler.go (about)

     1  package handler
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/onflow/flow/protobuf/go/flow/entities"
     7  	accessproto "github.com/onflow/flow/protobuf/go/flow/legacy/access"
     8  	entitiesproto "github.com/onflow/flow/protobuf/go/flow/legacy/entities"
     9  	"google.golang.org/grpc/codes"
    10  	"google.golang.org/grpc/status"
    11  
    12  	"github.com/onflow/flow-go/access"
    13  	"github.com/onflow/flow-go/access/legacy/convert"
    14  	"github.com/onflow/flow-go/model/flow"
    15  )
    16  
    17  type Handler struct {
    18  	api   access.API
    19  	chain flow.Chain
    20  }
    21  
    22  func NewHandler(api access.API, chain flow.Chain) *Handler {
    23  	return &Handler{
    24  		api:   api,
    25  		chain: chain,
    26  	}
    27  }
    28  
    29  // Ping the Access API server for a response.
    30  func (h *Handler) Ping(context.Context, *accessproto.PingRequest) (*accessproto.PingResponse, error) {
    31  	return &accessproto.PingResponse{}, nil
    32  }
    33  
    34  func (h *Handler) GetNetworkParameters(
    35  	context.Context,
    36  	*accessproto.GetNetworkParametersRequest,
    37  ) (*accessproto.GetNetworkParametersResponse, error) {
    38  	panic("implement me")
    39  }
    40  
    41  // SendTransaction submits a transaction to the network.
    42  func (h *Handler) SendTransaction(
    43  	ctx context.Context,
    44  	req *accessproto.SendTransactionRequest,
    45  ) (*accessproto.SendTransactionResponse, error) {
    46  	txMsg := req.GetTransaction()
    47  
    48  	tx, err := convert.MessageToTransaction(txMsg, h.chain)
    49  	if err != nil {
    50  		return nil, status.Error(codes.InvalidArgument, err.Error())
    51  	}
    52  
    53  	err = h.api.SendTransaction(ctx, &tx)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	txID := tx.ID()
    59  
    60  	return &accessproto.SendTransactionResponse{
    61  		Id: txID[:],
    62  	}, nil
    63  }
    64  
    65  // GetLatestBlockHeader gets the latest sealed block header.
    66  func (h *Handler) GetLatestBlockHeader(
    67  	ctx context.Context,
    68  	req *accessproto.GetLatestBlockHeaderRequest,
    69  ) (*accessproto.BlockHeaderResponse, error) {
    70  	header, _, err := h.api.GetLatestBlockHeader(ctx, req.GetIsSealed())
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  
    75  	return blockHeaderResponse(header)
    76  }
    77  
    78  // GetBlockHeaderByHeight gets a block header by height.
    79  func (h *Handler) GetBlockHeaderByHeight(
    80  	ctx context.Context,
    81  	req *accessproto.GetBlockHeaderByHeightRequest,
    82  ) (*accessproto.BlockHeaderResponse, error) {
    83  	header, _, err := h.api.GetBlockHeaderByHeight(ctx, req.GetHeight())
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  
    88  	return blockHeaderResponse(header)
    89  }
    90  
    91  // GetBlockHeaderByID gets a block header by ID.
    92  func (h *Handler) GetBlockHeaderByID(
    93  	ctx context.Context,
    94  	req *accessproto.GetBlockHeaderByIDRequest,
    95  ) (*accessproto.BlockHeaderResponse, error) {
    96  	blockID := convert.MessageToIdentifier(req.GetId())
    97  
    98  	header, _, err := h.api.GetBlockHeaderByID(ctx, blockID)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	return blockHeaderResponse(header)
   104  }
   105  
   106  // GetLatestBlock gets the latest sealed block.
   107  func (h *Handler) GetLatestBlock(
   108  	ctx context.Context,
   109  	req *accessproto.GetLatestBlockRequest,
   110  ) (*accessproto.BlockResponse, error) {
   111  	block, _, err := h.api.GetLatestBlock(ctx, req.GetIsSealed())
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  
   116  	return blockResponse(block)
   117  }
   118  
   119  // GetBlockByHeight gets a block by height.
   120  func (h *Handler) GetBlockByHeight(
   121  	ctx context.Context,
   122  	req *accessproto.GetBlockByHeightRequest,
   123  ) (*accessproto.BlockResponse, error) {
   124  	block, _, err := h.api.GetBlockByHeight(ctx, req.GetHeight())
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	return blockResponse(block)
   130  }
   131  
   132  // GetBlockByHeight gets a block by ID.
   133  func (h *Handler) GetBlockByID(
   134  	ctx context.Context,
   135  	req *accessproto.GetBlockByIDRequest,
   136  ) (*accessproto.BlockResponse, error) {
   137  	blockID := convert.MessageToIdentifier(req.GetId())
   138  
   139  	block, _, err := h.api.GetBlockByID(ctx, blockID)
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  
   144  	return blockResponse(block)
   145  }
   146  
   147  // GetCollectionByID gets a collection by ID.
   148  func (h *Handler) GetCollectionByID(
   149  	ctx context.Context,
   150  	req *accessproto.GetCollectionByIDRequest,
   151  ) (*accessproto.CollectionResponse, error) {
   152  	id := convert.MessageToIdentifier(req.GetId())
   153  
   154  	col, err := h.api.GetCollectionByID(ctx, id)
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  
   159  	colMsg, err := convert.LightCollectionToMessage(col)
   160  	if err != nil {
   161  		return nil, status.Error(codes.Internal, err.Error())
   162  	}
   163  
   164  	return &accessproto.CollectionResponse{
   165  		Collection: colMsg,
   166  	}, nil
   167  }
   168  
   169  // GetTransaction gets a transaction by ID.
   170  func (h *Handler) GetTransaction(
   171  	ctx context.Context,
   172  	req *accessproto.GetTransactionRequest,
   173  ) (*accessproto.TransactionResponse, error) {
   174  	id := convert.MessageToIdentifier(req.GetId())
   175  
   176  	tx, err := h.api.GetTransaction(ctx, id)
   177  	if err != nil {
   178  		return nil, err
   179  	}
   180  
   181  	return &accessproto.TransactionResponse{
   182  		Transaction: convert.TransactionToMessage(*tx),
   183  	}, nil
   184  }
   185  
   186  // GetTransactionResult gets a transaction by ID.
   187  func (h *Handler) GetTransactionResult(
   188  	ctx context.Context,
   189  	req *accessproto.GetTransactionRequest,
   190  ) (*accessproto.TransactionResultResponse, error) {
   191  	id := convert.MessageToIdentifier(req.GetId())
   192  
   193  	result, err := h.api.GetTransactionResult(
   194  		ctx,
   195  		id,
   196  		flow.ZeroID,
   197  		flow.ZeroID,
   198  		entities.EventEncodingVersion_JSON_CDC_V0,
   199  	)
   200  	if err != nil {
   201  		return nil, err
   202  	}
   203  
   204  	return convert.TransactionResultToMessage(*result), nil
   205  }
   206  
   207  // GetAccount returns an account by address at the latest sealed block.
   208  func (h *Handler) GetAccount(
   209  	ctx context.Context,
   210  	req *accessproto.GetAccountRequest,
   211  ) (*accessproto.GetAccountResponse, error) {
   212  	address := flow.BytesToAddress(req.GetAddress())
   213  
   214  	account, err := h.api.GetAccount(ctx, address)
   215  	if err != nil {
   216  		return nil, err
   217  	}
   218  
   219  	accountMsg, err := convert.AccountToMessage(account)
   220  	if err != nil {
   221  		return nil, status.Error(codes.Internal, err.Error())
   222  	}
   223  
   224  	return &accessproto.GetAccountResponse{
   225  		Account: accountMsg,
   226  	}, nil
   227  }
   228  
   229  // GetAccountAtLatestBlock returns an account by address at the latest sealed block.
   230  func (h *Handler) GetAccountAtLatestBlock(
   231  	ctx context.Context,
   232  	req *accessproto.GetAccountAtLatestBlockRequest,
   233  ) (*accessproto.AccountResponse, error) {
   234  	address := flow.BytesToAddress(req.GetAddress())
   235  
   236  	account, err := h.api.GetAccountAtLatestBlock(ctx, address)
   237  	if err != nil {
   238  		return nil, err
   239  	}
   240  
   241  	accountMsg, err := convert.AccountToMessage(account)
   242  	if err != nil {
   243  		return nil, status.Error(codes.Internal, err.Error())
   244  	}
   245  
   246  	return &accessproto.AccountResponse{
   247  		Account: accountMsg,
   248  	}, nil
   249  }
   250  
   251  func (h *Handler) GetAccountAtBlockHeight(
   252  	ctx context.Context,
   253  	request *accessproto.GetAccountAtBlockHeightRequest,
   254  ) (*accessproto.AccountResponse, error) {
   255  	panic("implement me")
   256  }
   257  
   258  // ExecuteScriptAtLatestBlock executes a script at a the latest block
   259  func (h *Handler) ExecuteScriptAtLatestBlock(
   260  	ctx context.Context,
   261  	req *accessproto.ExecuteScriptAtLatestBlockRequest,
   262  ) (*accessproto.ExecuteScriptResponse, error) {
   263  	script := req.GetScript()
   264  	arguments := req.GetArguments()
   265  
   266  	value, err := h.api.ExecuteScriptAtLatestBlock(ctx, script, arguments)
   267  	if err != nil {
   268  		return nil, err
   269  	}
   270  
   271  	return &accessproto.ExecuteScriptResponse{
   272  		Value: value,
   273  	}, nil
   274  }
   275  
   276  // ExecuteScriptAtBlockHeight executes a script at a specific block height
   277  func (h *Handler) ExecuteScriptAtBlockHeight(
   278  	ctx context.Context,
   279  	req *accessproto.ExecuteScriptAtBlockHeightRequest,
   280  ) (*accessproto.ExecuteScriptResponse, error) {
   281  	script := req.GetScript()
   282  	arguments := req.GetArguments()
   283  	blockHeight := req.GetBlockHeight()
   284  
   285  	value, err := h.api.ExecuteScriptAtBlockHeight(ctx, blockHeight, script, arguments)
   286  	if err != nil {
   287  		return nil, err
   288  	}
   289  
   290  	return &accessproto.ExecuteScriptResponse{
   291  		Value: value,
   292  	}, nil
   293  }
   294  
   295  // ExecuteScriptAtBlockID executes a script at a specific block ID
   296  func (h *Handler) ExecuteScriptAtBlockID(
   297  	ctx context.Context,
   298  	req *accessproto.ExecuteScriptAtBlockIDRequest,
   299  ) (*accessproto.ExecuteScriptResponse, error) {
   300  	script := req.GetScript()
   301  	arguments := req.GetArguments()
   302  	blockID := convert.MessageToIdentifier(req.GetBlockId())
   303  
   304  	value, err := h.api.ExecuteScriptAtBlockID(ctx, blockID, script, arguments)
   305  	if err != nil {
   306  		return nil, err
   307  	}
   308  
   309  	return &accessproto.ExecuteScriptResponse{
   310  		Value: value,
   311  	}, nil
   312  }
   313  
   314  // GetEventsForHeightRange returns events matching a query.
   315  func (h *Handler) GetEventsForHeightRange(
   316  	ctx context.Context,
   317  	req *accessproto.GetEventsForHeightRangeRequest,
   318  ) (*accessproto.EventsResponse, error) {
   319  	eventType := req.GetType()
   320  	startHeight := req.GetStartHeight()
   321  	endHeight := req.GetEndHeight()
   322  
   323  	results, err := h.api.GetEventsForHeightRange(ctx, eventType, startHeight, endHeight, entities.EventEncodingVersion_JSON_CDC_V0)
   324  	if err != nil {
   325  		return nil, err
   326  	}
   327  
   328  	return &accessproto.EventsResponse{
   329  		Results: blockEventsToMessages(results),
   330  	}, nil
   331  }
   332  
   333  // GetEventsForBlockIDs returns events matching a set of block IDs.
   334  func (h *Handler) GetEventsForBlockIDs(
   335  	ctx context.Context,
   336  	req *accessproto.GetEventsForBlockIDsRequest,
   337  ) (*accessproto.EventsResponse, error) {
   338  	eventType := req.GetType()
   339  	blockIDs := convert.MessagesToIdentifiers(req.GetBlockIds())
   340  
   341  	results, err := h.api.GetEventsForBlockIDs(ctx, eventType, blockIDs, entities.EventEncodingVersion_JSON_CDC_V0)
   342  	if err != nil {
   343  		return nil, err
   344  	}
   345  
   346  	return &accessproto.EventsResponse{
   347  		Results: blockEventsToMessages(results),
   348  	}, nil
   349  }
   350  
   351  func blockResponse(block *flow.Block) (*accessproto.BlockResponse, error) {
   352  	msg, err := convert.BlockToMessage(block)
   353  	if err != nil {
   354  		return nil, err
   355  	}
   356  
   357  	return &accessproto.BlockResponse{
   358  		Block: msg,
   359  	}, nil
   360  }
   361  
   362  func blockHeaderResponse(header *flow.Header) (*accessproto.BlockHeaderResponse, error) {
   363  	msg, err := convert.BlockHeaderToMessage(header)
   364  	if err != nil {
   365  		return nil, err
   366  	}
   367  
   368  	return &accessproto.BlockHeaderResponse{
   369  		Block: msg,
   370  	}, nil
   371  }
   372  
   373  func blockEventsToMessages(blocks []flow.BlockEvents) []*accessproto.EventsResponse_Result {
   374  	results := make([]*accessproto.EventsResponse_Result, len(blocks))
   375  
   376  	for i, block := range blocks {
   377  		results[i] = blockEventsToMessage(block)
   378  	}
   379  
   380  	return results
   381  }
   382  
   383  func blockEventsToMessage(block flow.BlockEvents) *accessproto.EventsResponse_Result {
   384  	eventMessages := make([]*entitiesproto.Event, len(block.Events))
   385  	for i, event := range block.Events {
   386  		eventMessages[i] = convert.EventToMessage(event)
   387  	}
   388  
   389  	return &accessproto.EventsResponse_Result{
   390  		BlockId:     block.BlockID[:],
   391  		BlockHeight: block.BlockHeight,
   392  		Events:      eventMessages,
   393  	}
   394  }