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

     1  package access
     2  
     3  import (
     4  	"context"
     5  
     6  	"google.golang.org/grpc/codes"
     7  	"google.golang.org/grpc/status"
     8  	"google.golang.org/protobuf/types/known/timestamppb"
     9  
    10  	"github.com/onflow/flow-go/consensus/hotstuff"
    11  	"github.com/onflow/flow-go/consensus/hotstuff/signature"
    12  	"github.com/onflow/flow-go/engine/access/subscription"
    13  	"github.com/onflow/flow-go/engine/common/rpc"
    14  	"github.com/onflow/flow-go/engine/common/rpc/convert"
    15  	"github.com/onflow/flow-go/model/flow"
    16  	"github.com/onflow/flow-go/module"
    17  	"github.com/onflow/flow-go/module/counters"
    18  
    19  	"github.com/onflow/flow/protobuf/go/flow/access"
    20  	"github.com/onflow/flow/protobuf/go/flow/entities"
    21  )
    22  
    23  type Handler struct {
    24  	subscription.StreamingData
    25  	api                  API
    26  	chain                flow.Chain
    27  	signerIndicesDecoder hotstuff.BlockSignerDecoder
    28  	finalizedHeaderCache module.FinalizedHeaderCache
    29  	me                   module.Local
    30  }
    31  
    32  // HandlerOption is used to hand over optional constructor parameters
    33  type HandlerOption func(*Handler)
    34  
    35  var _ access.AccessAPIServer = (*Handler)(nil)
    36  
    37  // sendSubscribeBlocksResponseFunc is a callback function used to send
    38  // SubscribeBlocksResponse to the client stream.
    39  type sendSubscribeBlocksResponseFunc func(*access.SubscribeBlocksResponse) error
    40  
    41  // sendSubscribeBlockHeadersResponseFunc is a callback function used to send
    42  // SubscribeBlockHeadersResponse to the client stream.
    43  type sendSubscribeBlockHeadersResponseFunc func(*access.SubscribeBlockHeadersResponse) error
    44  
    45  // sendSubscribeBlockDigestsResponseFunc is a callback function used to send
    46  // SubscribeBlockDigestsResponse to the client stream.
    47  type sendSubscribeBlockDigestsResponseFunc func(*access.SubscribeBlockDigestsResponse) error
    48  
    49  func NewHandler(
    50  	api API,
    51  	chain flow.Chain,
    52  	finalizedHeader module.FinalizedHeaderCache,
    53  	me module.Local,
    54  	maxStreams uint32,
    55  	options ...HandlerOption,
    56  ) *Handler {
    57  	h := &Handler{
    58  		StreamingData:        subscription.NewStreamingData(maxStreams),
    59  		api:                  api,
    60  		chain:                chain,
    61  		finalizedHeaderCache: finalizedHeader,
    62  		me:                   me,
    63  		signerIndicesDecoder: &signature.NoopBlockSignerDecoder{},
    64  	}
    65  	for _, opt := range options {
    66  		opt(h)
    67  	}
    68  	return h
    69  }
    70  
    71  // Ping the Access API server for a response.
    72  func (h *Handler) Ping(ctx context.Context, _ *access.PingRequest) (*access.PingResponse, error) {
    73  	err := h.api.Ping(ctx)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	return &access.PingResponse{}, nil
    79  }
    80  
    81  // GetNodeVersionInfo gets node version information such as semver, commit, sporkID, protocolVersion, etc
    82  func (h *Handler) GetNodeVersionInfo(
    83  	ctx context.Context,
    84  	_ *access.GetNodeVersionInfoRequest,
    85  ) (*access.GetNodeVersionInfoResponse, error) {
    86  	nodeVersionInfo, err := h.api.GetNodeVersionInfo(ctx)
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  
    91  	return &access.GetNodeVersionInfoResponse{
    92  		Info: &entities.NodeVersionInfo{
    93  			Semver:               nodeVersionInfo.Semver,
    94  			Commit:               nodeVersionInfo.Commit,
    95  			SporkId:              nodeVersionInfo.SporkId[:],
    96  			ProtocolVersion:      nodeVersionInfo.ProtocolVersion,
    97  			SporkRootBlockHeight: nodeVersionInfo.SporkRootBlockHeight,
    98  			NodeRootBlockHeight:  nodeVersionInfo.NodeRootBlockHeight,
    99  		},
   100  	}, nil
   101  }
   102  
   103  func (h *Handler) GetNetworkParameters(
   104  	ctx context.Context,
   105  	_ *access.GetNetworkParametersRequest,
   106  ) (*access.GetNetworkParametersResponse, error) {
   107  	params := h.api.GetNetworkParameters(ctx)
   108  
   109  	return &access.GetNetworkParametersResponse{
   110  		ChainId: string(params.ChainID),
   111  	}, nil
   112  }
   113  
   114  // GetLatestBlockHeader gets the latest sealed block header.
   115  func (h *Handler) GetLatestBlockHeader(
   116  	ctx context.Context,
   117  	req *access.GetLatestBlockHeaderRequest,
   118  ) (*access.BlockHeaderResponse, error) {
   119  	header, status, err := h.api.GetLatestBlockHeader(ctx, req.GetIsSealed())
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  	return h.blockHeaderResponse(header, status)
   124  }
   125  
   126  // GetBlockHeaderByHeight gets a block header by height.
   127  func (h *Handler) GetBlockHeaderByHeight(
   128  	ctx context.Context,
   129  	req *access.GetBlockHeaderByHeightRequest,
   130  ) (*access.BlockHeaderResponse, error) {
   131  	header, status, err := h.api.GetBlockHeaderByHeight(ctx, req.GetHeight())
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  	return h.blockHeaderResponse(header, status)
   136  }
   137  
   138  // GetBlockHeaderByID gets a block header by ID.
   139  func (h *Handler) GetBlockHeaderByID(
   140  	ctx context.Context,
   141  	req *access.GetBlockHeaderByIDRequest,
   142  ) (*access.BlockHeaderResponse, error) {
   143  	id, err := convert.BlockID(req.GetId())
   144  	if err != nil {
   145  		return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err)
   146  	}
   147  	header, status, err := h.api.GetBlockHeaderByID(ctx, id)
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  	return h.blockHeaderResponse(header, status)
   152  }
   153  
   154  // GetLatestBlock gets the latest sealed block.
   155  func (h *Handler) GetLatestBlock(
   156  	ctx context.Context,
   157  	req *access.GetLatestBlockRequest,
   158  ) (*access.BlockResponse, error) {
   159  	block, status, err := h.api.GetLatestBlock(ctx, req.GetIsSealed())
   160  	if err != nil {
   161  		return nil, err
   162  	}
   163  	return h.blockResponse(block, req.GetFullBlockResponse(), status)
   164  }
   165  
   166  // GetBlockByHeight gets a block by height.
   167  func (h *Handler) GetBlockByHeight(
   168  	ctx context.Context,
   169  	req *access.GetBlockByHeightRequest,
   170  ) (*access.BlockResponse, error) {
   171  	block, status, err := h.api.GetBlockByHeight(ctx, req.GetHeight())
   172  	if err != nil {
   173  		return nil, err
   174  	}
   175  	return h.blockResponse(block, req.GetFullBlockResponse(), status)
   176  }
   177  
   178  // GetBlockByID gets a block by ID.
   179  func (h *Handler) GetBlockByID(
   180  	ctx context.Context,
   181  	req *access.GetBlockByIDRequest,
   182  ) (*access.BlockResponse, error) {
   183  	id, err := convert.BlockID(req.GetId())
   184  	if err != nil {
   185  		return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err)
   186  	}
   187  	block, status, err := h.api.GetBlockByID(ctx, id)
   188  	if err != nil {
   189  		return nil, err
   190  	}
   191  	return h.blockResponse(block, req.GetFullBlockResponse(), status)
   192  }
   193  
   194  // GetCollectionByID gets a collection by ID.
   195  func (h *Handler) GetCollectionByID(
   196  	ctx context.Context,
   197  	req *access.GetCollectionByIDRequest,
   198  ) (*access.CollectionResponse, error) {
   199  	metadata := h.buildMetadataResponse()
   200  
   201  	id, err := convert.CollectionID(req.GetId())
   202  	if err != nil {
   203  		return nil, status.Errorf(codes.InvalidArgument, "invalid collection id: %v", err)
   204  	}
   205  
   206  	col, err := h.api.GetCollectionByID(ctx, id)
   207  	if err != nil {
   208  		return nil, err
   209  	}
   210  
   211  	colMsg, err := convert.LightCollectionToMessage(col)
   212  	if err != nil {
   213  		return nil, status.Error(codes.Internal, err.Error())
   214  	}
   215  
   216  	return &access.CollectionResponse{
   217  		Collection: colMsg,
   218  		Metadata:   metadata,
   219  	}, nil
   220  }
   221  
   222  // SendTransaction submits a transaction to the network.
   223  func (h *Handler) SendTransaction(
   224  	ctx context.Context,
   225  	req *access.SendTransactionRequest,
   226  ) (*access.SendTransactionResponse, error) {
   227  	metadata := h.buildMetadataResponse()
   228  
   229  	txMsg := req.GetTransaction()
   230  
   231  	tx, err := convert.MessageToTransaction(txMsg, h.chain)
   232  	if err != nil {
   233  		return nil, status.Error(codes.InvalidArgument, err.Error())
   234  	}
   235  
   236  	err = h.api.SendTransaction(ctx, &tx)
   237  	if err != nil {
   238  		return nil, err
   239  	}
   240  
   241  	txID := tx.ID()
   242  
   243  	return &access.SendTransactionResponse{
   244  		Id:       txID[:],
   245  		Metadata: metadata,
   246  	}, nil
   247  }
   248  
   249  // GetTransaction gets a transaction by ID.
   250  func (h *Handler) GetTransaction(
   251  	ctx context.Context,
   252  	req *access.GetTransactionRequest,
   253  ) (*access.TransactionResponse, error) {
   254  	metadata := h.buildMetadataResponse()
   255  
   256  	id, err := convert.TransactionID(req.GetId())
   257  	if err != nil {
   258  		return nil, status.Errorf(codes.InvalidArgument, "invalid transaction id: %v", err)
   259  	}
   260  
   261  	tx, err := h.api.GetTransaction(ctx, id)
   262  	if err != nil {
   263  		return nil, err
   264  	}
   265  
   266  	return &access.TransactionResponse{
   267  		Transaction: convert.TransactionToMessage(*tx),
   268  		Metadata:    metadata,
   269  	}, nil
   270  }
   271  
   272  // GetTransactionResult gets a transaction by ID.
   273  func (h *Handler) GetTransactionResult(
   274  	ctx context.Context,
   275  	req *access.GetTransactionRequest,
   276  ) (*access.TransactionResultResponse, error) {
   277  	metadata := h.buildMetadataResponse()
   278  
   279  	transactionID, err := convert.TransactionID(req.GetId())
   280  	if err != nil {
   281  		return nil, status.Errorf(codes.InvalidArgument, "invalid transaction id: %v", err)
   282  	}
   283  
   284  	blockId := flow.ZeroID
   285  	requestBlockId := req.GetBlockId()
   286  	if requestBlockId != nil {
   287  		blockId, err = convert.BlockID(requestBlockId)
   288  		if err != nil {
   289  			return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err)
   290  		}
   291  	}
   292  
   293  	collectionId := flow.ZeroID
   294  	requestCollectionId := req.GetCollectionId()
   295  	if requestCollectionId != nil {
   296  		collectionId, err = convert.CollectionID(requestCollectionId)
   297  		if err != nil {
   298  			return nil, status.Errorf(codes.InvalidArgument, "invalid collection id: %v", err)
   299  		}
   300  	}
   301  
   302  	eventEncodingVersion := req.GetEventEncodingVersion()
   303  	result, err := h.api.GetTransactionResult(ctx, transactionID, blockId, collectionId, eventEncodingVersion)
   304  	if err != nil {
   305  		return nil, err
   306  	}
   307  
   308  	message := TransactionResultToMessage(result)
   309  	message.Metadata = metadata
   310  
   311  	return message, nil
   312  }
   313  
   314  func (h *Handler) GetTransactionResultsByBlockID(
   315  	ctx context.Context,
   316  	req *access.GetTransactionsByBlockIDRequest,
   317  ) (*access.TransactionResultsResponse, error) {
   318  	metadata := h.buildMetadataResponse()
   319  
   320  	id, err := convert.BlockID(req.GetBlockId())
   321  	if err != nil {
   322  		return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err)
   323  	}
   324  
   325  	eventEncodingVersion := req.GetEventEncodingVersion()
   326  
   327  	results, err := h.api.GetTransactionResultsByBlockID(ctx, id, eventEncodingVersion)
   328  	if err != nil {
   329  		return nil, err
   330  	}
   331  
   332  	message := TransactionResultsToMessage(results)
   333  	message.Metadata = metadata
   334  
   335  	return message, nil
   336  }
   337  
   338  func (h *Handler) GetSystemTransaction(
   339  	ctx context.Context,
   340  	req *access.GetSystemTransactionRequest,
   341  ) (*access.TransactionResponse, error) {
   342  	metadata := h.buildMetadataResponse()
   343  
   344  	id, err := convert.BlockID(req.GetBlockId())
   345  	if err != nil {
   346  		return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err)
   347  	}
   348  
   349  	tx, err := h.api.GetSystemTransaction(ctx, id)
   350  	if err != nil {
   351  		return nil, err
   352  	}
   353  
   354  	return &access.TransactionResponse{
   355  		Transaction: convert.TransactionToMessage(*tx),
   356  		Metadata:    metadata,
   357  	}, nil
   358  }
   359  
   360  func (h *Handler) GetSystemTransactionResult(
   361  	ctx context.Context,
   362  	req *access.GetSystemTransactionResultRequest,
   363  ) (*access.TransactionResultResponse, error) {
   364  	metadata := h.buildMetadataResponse()
   365  
   366  	id, err := convert.BlockID(req.GetBlockId())
   367  	if err != nil {
   368  		return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err)
   369  	}
   370  
   371  	result, err := h.api.GetSystemTransactionResult(ctx, id, req.GetEventEncodingVersion())
   372  	if err != nil {
   373  		return nil, err
   374  	}
   375  
   376  	message := TransactionResultToMessage(result)
   377  	message.Metadata = metadata
   378  
   379  	return message, nil
   380  }
   381  
   382  func (h *Handler) GetTransactionsByBlockID(
   383  	ctx context.Context,
   384  	req *access.GetTransactionsByBlockIDRequest,
   385  ) (*access.TransactionsResponse, error) {
   386  	metadata := h.buildMetadataResponse()
   387  
   388  	id, err := convert.BlockID(req.GetBlockId())
   389  	if err != nil {
   390  		return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err)
   391  	}
   392  
   393  	transactions, err := h.api.GetTransactionsByBlockID(ctx, id)
   394  	if err != nil {
   395  		return nil, err
   396  	}
   397  
   398  	return &access.TransactionsResponse{
   399  		Transactions: convert.TransactionsToMessages(transactions),
   400  		Metadata:     metadata,
   401  	}, nil
   402  }
   403  
   404  // GetTransactionResultByIndex gets a transaction at a specific index for in a block that is executed,
   405  // pending or finalized transactions return errors
   406  func (h *Handler) GetTransactionResultByIndex(
   407  	ctx context.Context,
   408  	req *access.GetTransactionByIndexRequest,
   409  ) (*access.TransactionResultResponse, error) {
   410  	metadata := h.buildMetadataResponse()
   411  
   412  	blockID, err := convert.BlockID(req.GetBlockId())
   413  	if err != nil {
   414  		return nil, status.Errorf(codes.InvalidArgument, "invalid block id: %v", err)
   415  	}
   416  
   417  	eventEncodingVersion := req.GetEventEncodingVersion()
   418  
   419  	result, err := h.api.GetTransactionResultByIndex(ctx, blockID, req.GetIndex(), eventEncodingVersion)
   420  	if err != nil {
   421  		return nil, err
   422  	}
   423  
   424  	message := TransactionResultToMessage(result)
   425  	message.Metadata = metadata
   426  
   427  	return message, nil
   428  }
   429  
   430  // GetAccount returns an account by address at the latest sealed block.
   431  func (h *Handler) GetAccount(
   432  	ctx context.Context,
   433  	req *access.GetAccountRequest,
   434  ) (*access.GetAccountResponse, error) {
   435  	metadata := h.buildMetadataResponse()
   436  
   437  	address, err := convert.Address(req.GetAddress(), h.chain)
   438  	if err != nil {
   439  		return nil, status.Errorf(codes.InvalidArgument, "invalid address: %v", err)
   440  	}
   441  
   442  	account, err := h.api.GetAccount(ctx, address)
   443  	if err != nil {
   444  		return nil, err
   445  	}
   446  
   447  	accountMsg, err := convert.AccountToMessage(account)
   448  	if err != nil {
   449  		return nil, status.Error(codes.Internal, err.Error())
   450  	}
   451  
   452  	return &access.GetAccountResponse{
   453  		Account:  accountMsg,
   454  		Metadata: metadata,
   455  	}, nil
   456  }
   457  
   458  // GetAccountAtLatestBlock returns an account by address at the latest sealed block.
   459  func (h *Handler) GetAccountAtLatestBlock(
   460  	ctx context.Context,
   461  	req *access.GetAccountAtLatestBlockRequest,
   462  ) (*access.AccountResponse, error) {
   463  	metadata := h.buildMetadataResponse()
   464  
   465  	address, err := convert.Address(req.GetAddress(), h.chain)
   466  	if err != nil {
   467  		return nil, status.Errorf(codes.InvalidArgument, "invalid address: %v", err)
   468  	}
   469  
   470  	account, err := h.api.GetAccountAtLatestBlock(ctx, address)
   471  	if err != nil {
   472  		return nil, err
   473  	}
   474  
   475  	accountMsg, err := convert.AccountToMessage(account)
   476  	if err != nil {
   477  		return nil, status.Error(codes.Internal, err.Error())
   478  	}
   479  
   480  	return &access.AccountResponse{
   481  		Account:  accountMsg,
   482  		Metadata: metadata,
   483  	}, nil
   484  }
   485  
   486  func (h *Handler) GetAccountAtBlockHeight(
   487  	ctx context.Context,
   488  	req *access.GetAccountAtBlockHeightRequest,
   489  ) (*access.AccountResponse, error) {
   490  	metadata := h.buildMetadataResponse()
   491  
   492  	address, err := convert.Address(req.GetAddress(), h.chain)
   493  	if err != nil {
   494  		return nil, status.Errorf(codes.InvalidArgument, "invalid address: %v", err)
   495  	}
   496  
   497  	account, err := h.api.GetAccountAtBlockHeight(ctx, address, req.GetBlockHeight())
   498  	if err != nil {
   499  		return nil, err
   500  	}
   501  
   502  	accountMsg, err := convert.AccountToMessage(account)
   503  	if err != nil {
   504  		return nil, status.Error(codes.Internal, err.Error())
   505  	}
   506  
   507  	return &access.AccountResponse{
   508  		Account:  accountMsg,
   509  		Metadata: metadata,
   510  	}, nil
   511  }
   512  
   513  // ExecuteScriptAtLatestBlock executes a script at a the latest block.
   514  func (h *Handler) ExecuteScriptAtLatestBlock(
   515  	ctx context.Context,
   516  	req *access.ExecuteScriptAtLatestBlockRequest,
   517  ) (*access.ExecuteScriptResponse, error) {
   518  	metadata := h.buildMetadataResponse()
   519  
   520  	script := req.GetScript()
   521  	arguments := req.GetArguments()
   522  
   523  	value, err := h.api.ExecuteScriptAtLatestBlock(ctx, script, arguments)
   524  	if err != nil {
   525  		return nil, err
   526  	}
   527  
   528  	return &access.ExecuteScriptResponse{
   529  		Value:    value,
   530  		Metadata: metadata,
   531  	}, nil
   532  }
   533  
   534  // ExecuteScriptAtBlockHeight executes a script at a specific block height.
   535  func (h *Handler) ExecuteScriptAtBlockHeight(
   536  	ctx context.Context,
   537  	req *access.ExecuteScriptAtBlockHeightRequest,
   538  ) (*access.ExecuteScriptResponse, error) {
   539  	metadata := h.buildMetadataResponse()
   540  
   541  	script := req.GetScript()
   542  	arguments := req.GetArguments()
   543  	blockHeight := req.GetBlockHeight()
   544  
   545  	value, err := h.api.ExecuteScriptAtBlockHeight(ctx, blockHeight, script, arguments)
   546  	if err != nil {
   547  		return nil, err
   548  	}
   549  
   550  	return &access.ExecuteScriptResponse{
   551  		Value:    value,
   552  		Metadata: metadata,
   553  	}, nil
   554  }
   555  
   556  // ExecuteScriptAtBlockID executes a script at a specific block ID.
   557  func (h *Handler) ExecuteScriptAtBlockID(
   558  	ctx context.Context,
   559  	req *access.ExecuteScriptAtBlockIDRequest,
   560  ) (*access.ExecuteScriptResponse, error) {
   561  	metadata := h.buildMetadataResponse()
   562  
   563  	script := req.GetScript()
   564  	arguments := req.GetArguments()
   565  	blockID := convert.MessageToIdentifier(req.GetBlockId())
   566  
   567  	value, err := h.api.ExecuteScriptAtBlockID(ctx, blockID, script, arguments)
   568  	if err != nil {
   569  		return nil, err
   570  	}
   571  
   572  	return &access.ExecuteScriptResponse{
   573  		Value:    value,
   574  		Metadata: metadata,
   575  	}, nil
   576  }
   577  
   578  // GetEventsForHeightRange returns events matching a query.
   579  func (h *Handler) GetEventsForHeightRange(
   580  	ctx context.Context,
   581  	req *access.GetEventsForHeightRangeRequest,
   582  ) (*access.EventsResponse, error) {
   583  	metadata := h.buildMetadataResponse()
   584  
   585  	eventType, err := convert.EventType(req.GetType())
   586  	if err != nil {
   587  		return nil, err
   588  	}
   589  
   590  	startHeight := req.GetStartHeight()
   591  	endHeight := req.GetEndHeight()
   592  
   593  	eventEncodingVersion := req.GetEventEncodingVersion()
   594  
   595  	results, err := h.api.GetEventsForHeightRange(ctx, eventType, startHeight, endHeight, eventEncodingVersion)
   596  	if err != nil {
   597  		return nil, err
   598  	}
   599  
   600  	resultEvents, err := convert.BlockEventsToMessages(results)
   601  	if err != nil {
   602  		return nil, err
   603  	}
   604  	return &access.EventsResponse{
   605  		Results:  resultEvents,
   606  		Metadata: metadata,
   607  	}, nil
   608  }
   609  
   610  // GetEventsForBlockIDs returns events matching a set of block IDs.
   611  func (h *Handler) GetEventsForBlockIDs(
   612  	ctx context.Context,
   613  	req *access.GetEventsForBlockIDsRequest,
   614  ) (*access.EventsResponse, error) {
   615  	metadata := h.buildMetadataResponse()
   616  
   617  	eventType, err := convert.EventType(req.GetType())
   618  	if err != nil {
   619  		return nil, err
   620  	}
   621  
   622  	blockIDs, err := convert.BlockIDs(req.GetBlockIds())
   623  	if err != nil {
   624  		return nil, err
   625  	}
   626  
   627  	eventEncodingVersion := req.GetEventEncodingVersion()
   628  
   629  	results, err := h.api.GetEventsForBlockIDs(ctx, eventType, blockIDs, eventEncodingVersion)
   630  	if err != nil {
   631  		return nil, err
   632  	}
   633  
   634  	resultEvents, err := convert.BlockEventsToMessages(results)
   635  	if err != nil {
   636  		return nil, err
   637  	}
   638  
   639  	return &access.EventsResponse{
   640  		Results:  resultEvents,
   641  		Metadata: metadata,
   642  	}, nil
   643  }
   644  
   645  // GetLatestProtocolStateSnapshot returns the latest serializable Snapshot
   646  func (h *Handler) GetLatestProtocolStateSnapshot(ctx context.Context, req *access.GetLatestProtocolStateSnapshotRequest) (*access.ProtocolStateSnapshotResponse, error) {
   647  	metadata := h.buildMetadataResponse()
   648  
   649  	snapshot, err := h.api.GetLatestProtocolStateSnapshot(ctx)
   650  	if err != nil {
   651  		return nil, err
   652  	}
   653  
   654  	return &access.ProtocolStateSnapshotResponse{
   655  		SerializedSnapshot: snapshot,
   656  		Metadata:           metadata,
   657  	}, nil
   658  }
   659  
   660  // GetProtocolStateSnapshotByBlockID returns serializable Snapshot by blockID
   661  func (h *Handler) GetProtocolStateSnapshotByBlockID(ctx context.Context, req *access.GetProtocolStateSnapshotByBlockIDRequest) (*access.ProtocolStateSnapshotResponse, error) {
   662  	metadata := h.buildMetadataResponse()
   663  
   664  	blockID := convert.MessageToIdentifier(req.GetBlockId())
   665  
   666  	snapshot, err := h.api.GetProtocolStateSnapshotByBlockID(ctx, blockID)
   667  	if err != nil {
   668  		return nil, err
   669  	}
   670  
   671  	return &access.ProtocolStateSnapshotResponse{
   672  		SerializedSnapshot: snapshot,
   673  		Metadata:           metadata,
   674  	}, nil
   675  }
   676  
   677  // GetProtocolStateSnapshotByHeight returns serializable Snapshot by block height
   678  func (h *Handler) GetProtocolStateSnapshotByHeight(ctx context.Context, req *access.GetProtocolStateSnapshotByHeightRequest) (*access.ProtocolStateSnapshotResponse, error) {
   679  	metadata := h.buildMetadataResponse()
   680  
   681  	snapshot, err := h.api.GetProtocolStateSnapshotByHeight(ctx, req.GetBlockHeight())
   682  	if err != nil {
   683  		return nil, err
   684  	}
   685  
   686  	return &access.ProtocolStateSnapshotResponse{
   687  		SerializedSnapshot: snapshot,
   688  		Metadata:           metadata,
   689  	}, nil
   690  }
   691  
   692  // GetExecutionResultForBlockID returns the latest received execution result for the given block ID.
   693  // AN might receive multiple receipts with conflicting results for unsealed blocks.
   694  // If this case happens, since AN is not able to determine which result is the correct one until the block is sealed, it has to pick one result to respond to this query. For now, we return the result from the latest received receipt.
   695  func (h *Handler) GetExecutionResultForBlockID(ctx context.Context, req *access.GetExecutionResultForBlockIDRequest) (*access.ExecutionResultForBlockIDResponse, error) {
   696  	metadata := h.buildMetadataResponse()
   697  
   698  	blockID := convert.MessageToIdentifier(req.GetBlockId())
   699  
   700  	result, err := h.api.GetExecutionResultForBlockID(ctx, blockID)
   701  	if err != nil {
   702  		return nil, err
   703  	}
   704  
   705  	return executionResultToMessages(result, metadata)
   706  }
   707  
   708  // GetExecutionResultByID returns the execution result for the given ID.
   709  func (h *Handler) GetExecutionResultByID(ctx context.Context, req *access.GetExecutionResultByIDRequest) (*access.ExecutionResultByIDResponse, error) {
   710  	metadata := h.buildMetadataResponse()
   711  
   712  	resultID := convert.MessageToIdentifier(req.GetId())
   713  
   714  	result, err := h.api.GetExecutionResultByID(ctx, resultID)
   715  	if err != nil {
   716  		return nil, err
   717  	}
   718  
   719  	execResult, err := convert.ExecutionResultToMessage(result)
   720  	if err != nil {
   721  		return nil, err
   722  	}
   723  	return &access.ExecutionResultByIDResponse{
   724  		ExecutionResult: execResult,
   725  		Metadata:        metadata,
   726  	}, nil
   727  }
   728  
   729  // SubscribeBlocksFromStartBlockID handles subscription requests for blocks started from block id.
   730  // It takes a SubscribeBlocksFromStartBlockIDRequest and an AccessAPI_SubscribeBlocksFromStartBlockIDServer stream as input.
   731  // The handler manages the subscription to block updates and sends the subscribed block information
   732  // to the client via the provided stream.
   733  //
   734  // Expected errors during normal operation:
   735  // - codes.InvalidArgument - if invalid startBlockID provided or unknown block status provided.
   736  // - codes.ResourceExhausted - if the maximum number of streams is reached.
   737  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block to message or could not send response.
   738  func (h *Handler) SubscribeBlocksFromStartBlockID(request *access.SubscribeBlocksFromStartBlockIDRequest, stream access.AccessAPI_SubscribeBlocksFromStartBlockIDServer) error {
   739  	// check if the maximum number of streams is reached
   740  	if h.StreamCount.Load() >= h.MaxStreams {
   741  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
   742  	}
   743  	h.StreamCount.Add(1)
   744  	defer h.StreamCount.Add(-1)
   745  
   746  	startBlockID, blockStatus, err := h.getSubscriptionDataFromStartBlockID(request.GetStartBlockId(), request.GetBlockStatus())
   747  	if err != nil {
   748  		return err
   749  	}
   750  
   751  	sub := h.api.SubscribeBlocksFromStartBlockID(stream.Context(), startBlockID, blockStatus)
   752  	return subscription.HandleSubscription(sub, h.handleBlocksResponse(stream.Send, request.GetFullBlockResponse(), blockStatus))
   753  }
   754  
   755  // SubscribeBlocksFromStartHeight handles subscription requests for blocks started from block height.
   756  // It takes a SubscribeBlocksFromStartHeightRequest and an AccessAPI_SubscribeBlocksFromStartHeightServer stream as input.
   757  // The handler manages the subscription to block updates and sends the subscribed block information
   758  // to the client via the provided stream.
   759  //
   760  // Expected errors during normal operation:
   761  // - codes.InvalidArgument - if unknown block status provided.
   762  // - codes.ResourceExhausted - if the maximum number of streams is reached.
   763  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block to message or could not send response.
   764  func (h *Handler) SubscribeBlocksFromStartHeight(request *access.SubscribeBlocksFromStartHeightRequest, stream access.AccessAPI_SubscribeBlocksFromStartHeightServer) error {
   765  	// check if the maximum number of streams is reached
   766  	if h.StreamCount.Load() >= h.MaxStreams {
   767  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
   768  	}
   769  	h.StreamCount.Add(1)
   770  	defer h.StreamCount.Add(-1)
   771  
   772  	blockStatus := convert.MessageToBlockStatus(request.GetBlockStatus())
   773  	err := checkBlockStatus(blockStatus)
   774  	if err != nil {
   775  		return err
   776  	}
   777  
   778  	sub := h.api.SubscribeBlocksFromStartHeight(stream.Context(), request.GetStartBlockHeight(), blockStatus)
   779  	return subscription.HandleSubscription(sub, h.handleBlocksResponse(stream.Send, request.GetFullBlockResponse(), blockStatus))
   780  }
   781  
   782  // SubscribeBlocksFromLatest handles subscription requests for blocks started from latest sealed block.
   783  // It takes a SubscribeBlocksFromLatestRequest and an AccessAPI_SubscribeBlocksFromLatestServer stream as input.
   784  // The handler manages the subscription to block updates and sends the subscribed block information
   785  // to the client via the provided stream.
   786  //
   787  // Expected errors during normal operation:
   788  // - codes.InvalidArgument - if unknown block status provided.
   789  // - codes.ResourceExhausted - if the maximum number of streams is reached.
   790  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block to message or could not send response.
   791  func (h *Handler) SubscribeBlocksFromLatest(request *access.SubscribeBlocksFromLatestRequest, stream access.AccessAPI_SubscribeBlocksFromLatestServer) error {
   792  	// check if the maximum number of streams is reached
   793  	if h.StreamCount.Load() >= h.MaxStreams {
   794  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
   795  	}
   796  	h.StreamCount.Add(1)
   797  	defer h.StreamCount.Add(-1)
   798  
   799  	blockStatus := convert.MessageToBlockStatus(request.GetBlockStatus())
   800  	err := checkBlockStatus(blockStatus)
   801  	if err != nil {
   802  		return err
   803  	}
   804  
   805  	sub := h.api.SubscribeBlocksFromLatest(stream.Context(), blockStatus)
   806  	return subscription.HandleSubscription(sub, h.handleBlocksResponse(stream.Send, request.GetFullBlockResponse(), blockStatus))
   807  }
   808  
   809  // handleBlocksResponse handles the subscription to block updates and sends
   810  // the subscribed block information to the client via the provided stream.
   811  //
   812  // Parameters:
   813  // - send: The function responsible for sending the block response to the client.
   814  // - fullBlockResponse: A boolean indicating whether to include full block responses.
   815  // - blockStatus: The current block status.
   816  //
   817  // Returns a function that can be used as a callback for block updates.
   818  //
   819  // This function is designed to be used as a callback for block updates in a subscription.
   820  // It takes a block, processes it, and sends the corresponding response to the client using the provided send function.
   821  //
   822  // Expected errors during normal operation:
   823  //   - codes.Internal: If cannot convert a block to a message or the stream could not send a response.
   824  func (h *Handler) handleBlocksResponse(send sendSubscribeBlocksResponseFunc, fullBlockResponse bool, blockStatus flow.BlockStatus) func(*flow.Block) error {
   825  	return func(block *flow.Block) error {
   826  		msgBlockResponse, err := h.blockResponse(block, fullBlockResponse, blockStatus)
   827  		if err != nil {
   828  			return rpc.ConvertError(err, "could not convert block to message", codes.Internal)
   829  		}
   830  
   831  		err = send(&access.SubscribeBlocksResponse{
   832  			Block: msgBlockResponse.Block,
   833  		})
   834  		if err != nil {
   835  			return rpc.ConvertError(err, "could not send response", codes.Internal)
   836  		}
   837  
   838  		return nil
   839  	}
   840  }
   841  
   842  // SubscribeBlockHeadersFromStartBlockID handles subscription requests for block headers started from block id.
   843  // It takes a SubscribeBlockHeadersFromStartBlockIDRequest and an AccessAPI_SubscribeBlockHeadersFromStartBlockIDServer stream as input.
   844  // The handler manages the subscription to block updates and sends the subscribed block header information
   845  // to the client via the provided stream.
   846  //
   847  // Expected errors during normal operation:
   848  // - codes.InvalidArgument - if invalid startBlockID provided or unknown block status provided.
   849  // - codes.ResourceExhausted - if the maximum number of streams is reached.
   850  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block header to message or could not send response.
   851  func (h *Handler) SubscribeBlockHeadersFromStartBlockID(request *access.SubscribeBlockHeadersFromStartBlockIDRequest, stream access.AccessAPI_SubscribeBlockHeadersFromStartBlockIDServer) error {
   852  	// check if the maximum number of streams is reached
   853  	if h.StreamCount.Load() >= h.MaxStreams {
   854  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
   855  	}
   856  	h.StreamCount.Add(1)
   857  	defer h.StreamCount.Add(-1)
   858  
   859  	startBlockID, blockStatus, err := h.getSubscriptionDataFromStartBlockID(request.GetStartBlockId(), request.GetBlockStatus())
   860  	if err != nil {
   861  		return err
   862  	}
   863  
   864  	sub := h.api.SubscribeBlockHeadersFromStartBlockID(stream.Context(), startBlockID, blockStatus)
   865  	return subscription.HandleSubscription(sub, h.handleBlockHeadersResponse(stream.Send))
   866  }
   867  
   868  // SubscribeBlockHeadersFromStartHeight handles subscription requests for block headers started from block height.
   869  // It takes a SubscribeBlockHeadersFromStartHeightRequest and an AccessAPI_SubscribeBlockHeadersFromStartHeightServer stream as input.
   870  // The handler manages the subscription to block updates and sends the subscribed block header information
   871  // to the client via the provided stream.
   872  //
   873  // Expected errors during normal operation:
   874  // - codes.InvalidArgument - if unknown block status provided.
   875  // - codes.ResourceExhausted - if the maximum number of streams is reached.
   876  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block header to message or could not send response.
   877  func (h *Handler) SubscribeBlockHeadersFromStartHeight(request *access.SubscribeBlockHeadersFromStartHeightRequest, stream access.AccessAPI_SubscribeBlockHeadersFromStartHeightServer) error {
   878  	// check if the maximum number of streams is reached
   879  	if h.StreamCount.Load() >= h.MaxStreams {
   880  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
   881  	}
   882  	h.StreamCount.Add(1)
   883  	defer h.StreamCount.Add(-1)
   884  
   885  	blockStatus := convert.MessageToBlockStatus(request.GetBlockStatus())
   886  	err := checkBlockStatus(blockStatus)
   887  	if err != nil {
   888  		return err
   889  	}
   890  
   891  	sub := h.api.SubscribeBlockHeadersFromStartHeight(stream.Context(), request.GetStartBlockHeight(), blockStatus)
   892  	return subscription.HandleSubscription(sub, h.handleBlockHeadersResponse(stream.Send))
   893  }
   894  
   895  // SubscribeBlockHeadersFromLatest handles subscription requests for block headers started from latest sealed block.
   896  // It takes a SubscribeBlockHeadersFromLatestRequest and an AccessAPI_SubscribeBlockHeadersFromLatestServer stream as input.
   897  // The handler manages the subscription to block updates and sends the subscribed block header information
   898  // to the client via the provided stream.
   899  //
   900  // Expected errors during normal operation:
   901  // - codes.InvalidArgument - if unknown block status provided.
   902  // - codes.ResourceExhausted - if the maximum number of streams is reached.
   903  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block header to message or could not send response.
   904  func (h *Handler) SubscribeBlockHeadersFromLatest(request *access.SubscribeBlockHeadersFromLatestRequest, stream access.AccessAPI_SubscribeBlockHeadersFromLatestServer) error {
   905  	// check if the maximum number of streams is reached
   906  	if h.StreamCount.Load() >= h.MaxStreams {
   907  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
   908  	}
   909  	h.StreamCount.Add(1)
   910  	defer h.StreamCount.Add(-1)
   911  
   912  	blockStatus := convert.MessageToBlockStatus(request.GetBlockStatus())
   913  	err := checkBlockStatus(blockStatus)
   914  	if err != nil {
   915  		return err
   916  	}
   917  
   918  	sub := h.api.SubscribeBlockHeadersFromLatest(stream.Context(), blockStatus)
   919  	return subscription.HandleSubscription(sub, h.handleBlockHeadersResponse(stream.Send))
   920  }
   921  
   922  // handleBlockHeadersResponse handles the subscription to block updates and sends
   923  // the subscribed block header information to the client via the provided stream.
   924  //
   925  // Parameters:
   926  // - send: The function responsible for sending the block header response to the client.
   927  //
   928  // Returns a function that can be used as a callback for block header updates.
   929  //
   930  // This function is designed to be used as a callback for block header updates in a subscription.
   931  // It takes a block header, processes it, and sends the corresponding response to the client using the provided send function.
   932  //
   933  // Expected errors during normal operation:
   934  //   - codes.Internal: If could not decode the signer indices from the given block header, could not convert a block header to a message or the stream could not send a response.
   935  func (h *Handler) handleBlockHeadersResponse(send sendSubscribeBlockHeadersResponseFunc) func(*flow.Header) error {
   936  	return func(header *flow.Header) error {
   937  		signerIDs, err := h.signerIndicesDecoder.DecodeSignerIDs(header)
   938  		if err != nil {
   939  			return rpc.ConvertError(err, "could not decode the signer indices from the given block header", codes.Internal) // the block was retrieved from local storage - so no errors are expected
   940  		}
   941  
   942  		msgHeader, err := convert.BlockHeaderToMessage(header, signerIDs)
   943  		if err != nil {
   944  			return rpc.ConvertError(err, "could not convert block header to message", codes.Internal)
   945  		}
   946  
   947  		err = send(&access.SubscribeBlockHeadersResponse{
   948  			Header: msgHeader,
   949  		})
   950  		if err != nil {
   951  			return rpc.ConvertError(err, "could not send response", codes.Internal)
   952  		}
   953  
   954  		return nil
   955  	}
   956  }
   957  
   958  // SubscribeBlockDigestsFromStartBlockID streams finalized or sealed lightweight block starting at the requested block id.
   959  // It takes a SubscribeBlockDigestsFromStartBlockIDRequest and an AccessAPI_SubscribeBlockDigestsFromStartBlockIDServer stream as input.
   960  //
   961  // Expected errors during normal operation:
   962  // - codes.InvalidArgument - if invalid startBlockID provided or unknown block status provided,
   963  // - codes.ResourceExhausted - if the maximum number of streams is reached.
   964  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block to message or could not send response.
   965  func (h *Handler) SubscribeBlockDigestsFromStartBlockID(request *access.SubscribeBlockDigestsFromStartBlockIDRequest, stream access.AccessAPI_SubscribeBlockDigestsFromStartBlockIDServer) error {
   966  	// check if the maximum number of streams is reached
   967  	if h.StreamCount.Load() >= h.MaxStreams {
   968  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
   969  	}
   970  	h.StreamCount.Add(1)
   971  	defer h.StreamCount.Add(-1)
   972  
   973  	startBlockID, blockStatus, err := h.getSubscriptionDataFromStartBlockID(request.GetStartBlockId(), request.GetBlockStatus())
   974  	if err != nil {
   975  		return err
   976  	}
   977  
   978  	sub := h.api.SubscribeBlockDigestsFromStartBlockID(stream.Context(), startBlockID, blockStatus)
   979  	return subscription.HandleSubscription(sub, h.handleBlockDigestsResponse(stream.Send))
   980  }
   981  
   982  // SubscribeBlockDigestsFromStartHeight handles subscription requests for lightweight blocks started from block height.
   983  // It takes a SubscribeBlockDigestsFromStartHeightRequest and an AccessAPI_SubscribeBlockDigestsFromStartHeightServer stream as input.
   984  // The handler manages the subscription to block updates and sends the subscribed block information
   985  // to the client via the provided stream.
   986  //
   987  // Expected errors during normal operation:
   988  // - codes.InvalidArgument - if unknown block status provided.
   989  // - codes.ResourceExhausted - if the maximum number of streams is reached.
   990  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block to message or could not send response.
   991  func (h *Handler) SubscribeBlockDigestsFromStartHeight(request *access.SubscribeBlockDigestsFromStartHeightRequest, stream access.AccessAPI_SubscribeBlockDigestsFromStartHeightServer) error {
   992  	// check if the maximum number of streams is reached
   993  	if h.StreamCount.Load() >= h.MaxStreams {
   994  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
   995  	}
   996  	h.StreamCount.Add(1)
   997  	defer h.StreamCount.Add(-1)
   998  
   999  	blockStatus := convert.MessageToBlockStatus(request.GetBlockStatus())
  1000  	err := checkBlockStatus(blockStatus)
  1001  	if err != nil {
  1002  		return err
  1003  	}
  1004  
  1005  	sub := h.api.SubscribeBlockDigestsFromStartHeight(stream.Context(), request.GetStartBlockHeight(), blockStatus)
  1006  	return subscription.HandleSubscription(sub, h.handleBlockDigestsResponse(stream.Send))
  1007  }
  1008  
  1009  // SubscribeBlockDigestsFromLatest handles subscription requests for lightweight block started from latest sealed block.
  1010  // It takes a SubscribeBlockDigestsFromLatestRequest and an AccessAPI_SubscribeBlockDigestsFromLatestServer stream as input.
  1011  // The handler manages the subscription to block updates and sends the subscribed block header information
  1012  // to the client via the provided stream.
  1013  //
  1014  // Expected errors during normal operation:
  1015  // - codes.InvalidArgument - if unknown block status provided.
  1016  // - codes.ResourceExhausted - if the maximum number of streams is reached.
  1017  // - codes.Internal - if stream encountered an error, if stream got unexpected response or could not convert block to message or could not send response.
  1018  func (h *Handler) SubscribeBlockDigestsFromLatest(request *access.SubscribeBlockDigestsFromLatestRequest, stream access.AccessAPI_SubscribeBlockDigestsFromLatestServer) error {
  1019  	// check if the maximum number of streams is reached
  1020  	if h.StreamCount.Load() >= h.MaxStreams {
  1021  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
  1022  	}
  1023  	h.StreamCount.Add(1)
  1024  	defer h.StreamCount.Add(-1)
  1025  
  1026  	blockStatus := convert.MessageToBlockStatus(request.GetBlockStatus())
  1027  	err := checkBlockStatus(blockStatus)
  1028  	if err != nil {
  1029  		return err
  1030  	}
  1031  
  1032  	sub := h.api.SubscribeBlockDigestsFromLatest(stream.Context(), blockStatus)
  1033  	return subscription.HandleSubscription(sub, h.handleBlockDigestsResponse(stream.Send))
  1034  }
  1035  
  1036  // handleBlockDigestsResponse handles the subscription to block updates and sends
  1037  // the subscribed block digest information to the client via the provided stream.
  1038  //
  1039  // Parameters:
  1040  // - send: The function responsible for sending the block digest response to the client.
  1041  //
  1042  // Returns a function that can be used as a callback for block digest updates.
  1043  //
  1044  // This function is designed to be used as a callback for block digest updates in a subscription.
  1045  // It takes a block digest, processes it, and sends the corresponding response to the client using the provided send function.
  1046  //
  1047  // Expected errors during normal operation:
  1048  //   - codes.Internal: if the stream cannot send a response.
  1049  func (h *Handler) handleBlockDigestsResponse(send sendSubscribeBlockDigestsResponseFunc) func(*flow.BlockDigest) error {
  1050  	return func(blockDigest *flow.BlockDigest) error {
  1051  		err := send(&access.SubscribeBlockDigestsResponse{
  1052  			BlockId:        convert.IdentifierToMessage(blockDigest.ID()),
  1053  			BlockHeight:    blockDigest.Height,
  1054  			BlockTimestamp: timestamppb.New(blockDigest.Timestamp),
  1055  		})
  1056  		if err != nil {
  1057  			return rpc.ConvertError(err, "could not send response", codes.Internal)
  1058  		}
  1059  
  1060  		return nil
  1061  	}
  1062  }
  1063  
  1064  // getSubscriptionDataFromStartBlockID processes subscription start data from start block id.
  1065  // It takes a union representing the start block id and a BlockStatus from the entities package.
  1066  // Performs validation of input data and returns it in expected format for further processing.
  1067  //
  1068  // Returns:
  1069  // - flow.Identifier: The start block id for searching.
  1070  // - flow.BlockStatus: Block status.
  1071  // - error: An error indicating the result of the operation, if any.
  1072  //
  1073  // Expected errors during normal operation:
  1074  // - codes.InvalidArgument: If blockStatus is flow.BlockStatusUnknown, or startBlockID could not convert to flow.Identifier.
  1075  func (h *Handler) getSubscriptionDataFromStartBlockID(msgBlockId []byte, msgBlockStatus entities.BlockStatus) (flow.Identifier, flow.BlockStatus, error) {
  1076  	startBlockID, err := convert.BlockID(msgBlockId)
  1077  	if err != nil {
  1078  		return flow.ZeroID, flow.BlockStatusUnknown, err
  1079  	}
  1080  
  1081  	blockStatus := convert.MessageToBlockStatus(msgBlockStatus)
  1082  	err = checkBlockStatus(blockStatus)
  1083  	if err != nil {
  1084  		return flow.ZeroID, flow.BlockStatusUnknown, err
  1085  	}
  1086  
  1087  	return startBlockID, blockStatus, nil
  1088  }
  1089  
  1090  // SendAndSubscribeTransactionStatuses streams transaction statuses starting from the reference block saved in the
  1091  // transaction itself until the block containing the transaction becomes sealed or expired. When the transaction
  1092  // status becomes TransactionStatusSealed or TransactionStatusExpired, the subscription will automatically shut down.
  1093  func (h *Handler) SendAndSubscribeTransactionStatuses(
  1094  	request *access.SendAndSubscribeTransactionStatusesRequest,
  1095  	stream access.AccessAPI_SendAndSubscribeTransactionStatusesServer,
  1096  ) error {
  1097  	ctx := stream.Context()
  1098  
  1099  	// check if the maximum number of streams is reached
  1100  	if h.StreamCount.Load() >= h.MaxStreams {
  1101  		return status.Errorf(codes.ResourceExhausted, "maximum number of streams reached")
  1102  	}
  1103  	h.StreamCount.Add(1)
  1104  	defer h.StreamCount.Add(-1)
  1105  
  1106  	tx, err := convert.MessageToTransaction(request.GetTransaction(), h.chain)
  1107  	if err != nil {
  1108  		return status.Error(codes.InvalidArgument, err.Error())
  1109  	}
  1110  
  1111  	err = h.api.SendTransaction(ctx, &tx)
  1112  	if err != nil {
  1113  		return err
  1114  	}
  1115  
  1116  	sub := h.api.SubscribeTransactionStatuses(ctx, &tx, request.GetEventEncodingVersion())
  1117  
  1118  	messageIndex := counters.NewMonotonousCounter(0)
  1119  	return subscription.HandleSubscription(sub, func(txResults []*TransactionResult) error {
  1120  		for i := range txResults {
  1121  			value := messageIndex.Increment()
  1122  
  1123  			err = stream.Send(&access.SendAndSubscribeTransactionStatusesResponse{
  1124  				TransactionResults: TransactionResultToMessage(txResults[i]),
  1125  				MessageIndex:       value,
  1126  			})
  1127  			if err != nil {
  1128  				return rpc.ConvertError(err, "could not send response", codes.Internal)
  1129  			}
  1130  		}
  1131  
  1132  		return nil
  1133  	})
  1134  }
  1135  
  1136  func (h *Handler) blockResponse(block *flow.Block, fullResponse bool, status flow.BlockStatus) (*access.BlockResponse, error) {
  1137  	metadata := h.buildMetadataResponse()
  1138  
  1139  	signerIDs, err := h.signerIndicesDecoder.DecodeSignerIDs(block.Header)
  1140  	if err != nil {
  1141  		return nil, err // the block was retrieved from local storage - so no errors are expected
  1142  	}
  1143  
  1144  	var msg *entities.Block
  1145  	if fullResponse {
  1146  		msg, err = convert.BlockToMessage(block, signerIDs)
  1147  		if err != nil {
  1148  			return nil, rpc.ConvertError(err, "could not convert block to message", codes.Internal)
  1149  		}
  1150  	} else {
  1151  		msg = convert.BlockToMessageLight(block)
  1152  	}
  1153  
  1154  	return &access.BlockResponse{
  1155  		Block:       msg,
  1156  		BlockStatus: entities.BlockStatus(status),
  1157  		Metadata:    metadata,
  1158  	}, nil
  1159  }
  1160  
  1161  func (h *Handler) blockHeaderResponse(header *flow.Header, status flow.BlockStatus) (*access.BlockHeaderResponse, error) {
  1162  	metadata := h.buildMetadataResponse()
  1163  
  1164  	signerIDs, err := h.signerIndicesDecoder.DecodeSignerIDs(header)
  1165  	if err != nil {
  1166  		return nil, err // the block was retrieved from local storage - so no errors are expected
  1167  	}
  1168  
  1169  	msg, err := convert.BlockHeaderToMessage(header, signerIDs)
  1170  	if err != nil {
  1171  		return nil, rpc.ConvertError(err, "could not convert block header to message", codes.Internal)
  1172  	}
  1173  
  1174  	return &access.BlockHeaderResponse{
  1175  		Block:       msg,
  1176  		BlockStatus: entities.BlockStatus(status),
  1177  		Metadata:    metadata,
  1178  	}, nil
  1179  }
  1180  
  1181  // buildMetadataResponse builds and returns the metadata response object.
  1182  func (h *Handler) buildMetadataResponse() *entities.Metadata {
  1183  	lastFinalizedHeader := h.finalizedHeaderCache.Get()
  1184  	blockId := lastFinalizedHeader.ID()
  1185  	nodeId := h.me.NodeID()
  1186  
  1187  	return &entities.Metadata{
  1188  		LatestFinalizedBlockId: blockId[:],
  1189  		LatestFinalizedHeight:  lastFinalizedHeader.Height,
  1190  		NodeId:                 nodeId[:],
  1191  	}
  1192  }
  1193  
  1194  func executionResultToMessages(er *flow.ExecutionResult, metadata *entities.Metadata) (*access.ExecutionResultForBlockIDResponse, error) {
  1195  	execResult, err := convert.ExecutionResultToMessage(er)
  1196  	if err != nil {
  1197  		return nil, err
  1198  	}
  1199  	return &access.ExecutionResultForBlockIDResponse{
  1200  		ExecutionResult: execResult,
  1201  		Metadata:        metadata,
  1202  	}, nil
  1203  }
  1204  
  1205  // WithBlockSignerDecoder configures the Handler to decode signer indices
  1206  // via the provided hotstuff.BlockSignerDecoder
  1207  func WithBlockSignerDecoder(signerIndicesDecoder hotstuff.BlockSignerDecoder) func(*Handler) {
  1208  	return func(handler *Handler) {
  1209  		handler.signerIndicesDecoder = signerIndicesDecoder
  1210  	}
  1211  }
  1212  
  1213  // checkBlockStatus checks the validity of the provided block status.
  1214  //
  1215  // Expected errors during normal operation:
  1216  // - codes.InvalidArgument - if blockStatus is flow.BlockStatusUnknown
  1217  func checkBlockStatus(blockStatus flow.BlockStatus) error {
  1218  	if blockStatus != flow.BlockStatusFinalized && blockStatus != flow.BlockStatusSealed {
  1219  		return status.Errorf(codes.InvalidArgument, "block status is unknown. Possible variants: BLOCK_FINALIZED, BLOCK_SEALED")
  1220  	}
  1221  	return nil
  1222  }