github.com/onflow/flow-go@v0.33.17/engine/access/apiproxy/access_api_proxy.go (about)

     1  package apiproxy
     2  
     3  import (
     4  	"context"
     5  
     6  	"google.golang.org/grpc/status"
     7  
     8  	"github.com/rs/zerolog"
     9  
    10  	"github.com/onflow/flow/protobuf/go/flow/access"
    11  
    12  	"github.com/onflow/flow-go/engine/access/rpc/connection"
    13  	"github.com/onflow/flow-go/engine/common/grpc/forwarder"
    14  	"github.com/onflow/flow-go/engine/protocol"
    15  	"github.com/onflow/flow-go/model/flow"
    16  	"github.com/onflow/flow-go/module/metrics"
    17  )
    18  
    19  // FlowAccessAPIRouter is a structure that represents the routing proxy algorithm.
    20  // It splits requests between a local and a remote API service.
    21  type FlowAccessAPIRouter struct {
    22  	Logger   zerolog.Logger
    23  	Metrics  *metrics.ObserverCollector
    24  	Upstream *FlowAccessAPIForwarder
    25  	Observer *protocol.Handler
    26  }
    27  
    28  func (h *FlowAccessAPIRouter) log(handler, rpc string, err error) {
    29  	code := status.Code(err)
    30  	h.Metrics.RecordRPC(handler, rpc, code)
    31  
    32  	logger := h.Logger.With().
    33  		Str("handler", handler).
    34  		Str("grpc_method", rpc).
    35  		Str("grpc_code", code.String()).
    36  		Logger()
    37  
    38  	if err != nil {
    39  		logger.Error().Err(err).Msg("request failed")
    40  		return
    41  	}
    42  
    43  	logger.Info().Msg("request succeeded")
    44  }
    45  
    46  // Ping pings the service. It is special in the sense that it responds successful,
    47  // only if all underlying services are ready.
    48  func (h *FlowAccessAPIRouter) Ping(context context.Context, req *access.PingRequest) (*access.PingResponse, error) {
    49  	h.log("observer", "Ping", nil)
    50  	return &access.PingResponse{}, nil
    51  }
    52  
    53  func (h *FlowAccessAPIRouter) GetNodeVersionInfo(ctx context.Context, request *access.GetNodeVersionInfoRequest) (*access.GetNodeVersionInfoResponse, error) {
    54  	res, err := h.Observer.GetNodeVersionInfo(ctx, request)
    55  	h.log("observer", "GetNodeVersionInfo", err)
    56  	return res, err
    57  }
    58  
    59  func (h *FlowAccessAPIRouter) GetLatestBlockHeader(context context.Context, req *access.GetLatestBlockHeaderRequest) (*access.BlockHeaderResponse, error) {
    60  	res, err := h.Observer.GetLatestBlockHeader(context, req)
    61  	h.log("observer", "GetLatestBlockHeader", err)
    62  	return res, err
    63  }
    64  
    65  func (h *FlowAccessAPIRouter) GetBlockHeaderByID(context context.Context, req *access.GetBlockHeaderByIDRequest) (*access.BlockHeaderResponse, error) {
    66  	res, err := h.Observer.GetBlockHeaderByID(context, req)
    67  	h.log("observer", "GetBlockHeaderByID", err)
    68  	return res, err
    69  }
    70  
    71  func (h *FlowAccessAPIRouter) GetBlockHeaderByHeight(context context.Context, req *access.GetBlockHeaderByHeightRequest) (*access.BlockHeaderResponse, error) {
    72  	res, err := h.Observer.GetBlockHeaderByHeight(context, req)
    73  	h.log("observer", "GetBlockHeaderByHeight", err)
    74  	return res, err
    75  }
    76  
    77  func (h *FlowAccessAPIRouter) GetLatestBlock(context context.Context, req *access.GetLatestBlockRequest) (*access.BlockResponse, error) {
    78  	res, err := h.Observer.GetLatestBlock(context, req)
    79  	h.log("observer", "GetLatestBlock", err)
    80  	return res, err
    81  }
    82  
    83  func (h *FlowAccessAPIRouter) GetBlockByID(context context.Context, req *access.GetBlockByIDRequest) (*access.BlockResponse, error) {
    84  	res, err := h.Observer.GetBlockByID(context, req)
    85  	h.log("observer", "GetBlockByID", err)
    86  	return res, err
    87  }
    88  
    89  func (h *FlowAccessAPIRouter) GetBlockByHeight(context context.Context, req *access.GetBlockByHeightRequest) (*access.BlockResponse, error) {
    90  	res, err := h.Observer.GetBlockByHeight(context, req)
    91  	h.log("observer", "GetBlockByHeight", err)
    92  	return res, err
    93  }
    94  
    95  func (h *FlowAccessAPIRouter) GetCollectionByID(context context.Context, req *access.GetCollectionByIDRequest) (*access.CollectionResponse, error) {
    96  	res, err := h.Upstream.GetCollectionByID(context, req)
    97  	h.log("upstream", "GetCollectionByID", err)
    98  	return res, err
    99  }
   100  
   101  func (h *FlowAccessAPIRouter) SendTransaction(context context.Context, req *access.SendTransactionRequest) (*access.SendTransactionResponse, error) {
   102  	res, err := h.Upstream.SendTransaction(context, req)
   103  	h.log("upstream", "SendTransaction", err)
   104  	return res, err
   105  }
   106  
   107  func (h *FlowAccessAPIRouter) GetTransaction(context context.Context, req *access.GetTransactionRequest) (*access.TransactionResponse, error) {
   108  	res, err := h.Upstream.GetTransaction(context, req)
   109  	h.log("upstream", "GetTransaction", err)
   110  	return res, err
   111  }
   112  
   113  func (h *FlowAccessAPIRouter) GetTransactionResult(context context.Context, req *access.GetTransactionRequest) (*access.TransactionResultResponse, error) {
   114  	res, err := h.Upstream.GetTransactionResult(context, req)
   115  	h.log("upstream", "GetTransactionResult", err)
   116  	return res, err
   117  }
   118  
   119  func (h *FlowAccessAPIRouter) GetTransactionResultsByBlockID(context context.Context, req *access.GetTransactionsByBlockIDRequest) (*access.TransactionResultsResponse, error) {
   120  	res, err := h.Upstream.GetTransactionResultsByBlockID(context, req)
   121  	h.log("upstream", "GetTransactionResultsByBlockID", err)
   122  	return res, err
   123  }
   124  
   125  func (h *FlowAccessAPIRouter) GetTransactionsByBlockID(context context.Context, req *access.GetTransactionsByBlockIDRequest) (*access.TransactionsResponse, error) {
   126  	res, err := h.Upstream.GetTransactionsByBlockID(context, req)
   127  	h.log("upstream", "GetTransactionsByBlockID", err)
   128  	return res, err
   129  }
   130  
   131  func (h *FlowAccessAPIRouter) GetTransactionResultByIndex(context context.Context, req *access.GetTransactionByIndexRequest) (*access.TransactionResultResponse, error) {
   132  	res, err := h.Upstream.GetTransactionResultByIndex(context, req)
   133  	h.log("upstream", "GetTransactionResultByIndex", err)
   134  	return res, err
   135  }
   136  
   137  func (h *FlowAccessAPIRouter) GetSystemTransaction(context context.Context, req *access.GetSystemTransactionRequest) (*access.TransactionResponse, error) {
   138  	res, err := h.Upstream.GetSystemTransaction(context, req)
   139  	h.log("upstream", "GetSystemTransaction", err)
   140  	return res, err
   141  }
   142  
   143  func (h *FlowAccessAPIRouter) GetSystemTransactionResult(context context.Context, req *access.GetSystemTransactionResultRequest) (*access.TransactionResultResponse, error) {
   144  	res, err := h.Upstream.GetSystemTransactionResult(context, req)
   145  	h.log("upstream", "GetSystemTransactionResult", err)
   146  	return res, err
   147  }
   148  
   149  func (h *FlowAccessAPIRouter) GetAccount(context context.Context, req *access.GetAccountRequest) (*access.GetAccountResponse, error) {
   150  	res, err := h.Upstream.GetAccount(context, req)
   151  	h.log("upstream", "GetAccount", err)
   152  	return res, err
   153  }
   154  
   155  func (h *FlowAccessAPIRouter) GetAccountAtLatestBlock(context context.Context, req *access.GetAccountAtLatestBlockRequest) (*access.AccountResponse, error) {
   156  	res, err := h.Upstream.GetAccountAtLatestBlock(context, req)
   157  	h.log("upstream", "GetAccountAtLatestBlock", err)
   158  	return res, err
   159  }
   160  
   161  func (h *FlowAccessAPIRouter) GetAccountAtBlockHeight(context context.Context, req *access.GetAccountAtBlockHeightRequest) (*access.AccountResponse, error) {
   162  	res, err := h.Upstream.GetAccountAtBlockHeight(context, req)
   163  	h.log("upstream", "GetAccountAtBlockHeight", err)
   164  	return res, err
   165  }
   166  
   167  func (h *FlowAccessAPIRouter) ExecuteScriptAtLatestBlock(context context.Context, req *access.ExecuteScriptAtLatestBlockRequest) (*access.ExecuteScriptResponse, error) {
   168  	res, err := h.Upstream.ExecuteScriptAtLatestBlock(context, req)
   169  	h.log("upstream", "ExecuteScriptAtLatestBlock", err)
   170  	return res, err
   171  }
   172  
   173  func (h *FlowAccessAPIRouter) ExecuteScriptAtBlockID(context context.Context, req *access.ExecuteScriptAtBlockIDRequest) (*access.ExecuteScriptResponse, error) {
   174  	res, err := h.Upstream.ExecuteScriptAtBlockID(context, req)
   175  	h.log("upstream", "ExecuteScriptAtBlockID", err)
   176  	return res, err
   177  }
   178  
   179  func (h *FlowAccessAPIRouter) ExecuteScriptAtBlockHeight(context context.Context, req *access.ExecuteScriptAtBlockHeightRequest) (*access.ExecuteScriptResponse, error) {
   180  	res, err := h.Upstream.ExecuteScriptAtBlockHeight(context, req)
   181  	h.log("upstream", "ExecuteScriptAtBlockHeight", err)
   182  	return res, err
   183  }
   184  
   185  func (h *FlowAccessAPIRouter) GetEventsForHeightRange(context context.Context, req *access.GetEventsForHeightRangeRequest) (*access.EventsResponse, error) {
   186  	res, err := h.Upstream.GetEventsForHeightRange(context, req)
   187  	h.log("upstream", "GetEventsForHeightRange", err)
   188  	return res, err
   189  }
   190  
   191  func (h *FlowAccessAPIRouter) GetEventsForBlockIDs(context context.Context, req *access.GetEventsForBlockIDsRequest) (*access.EventsResponse, error) {
   192  	res, err := h.Upstream.GetEventsForBlockIDs(context, req)
   193  	h.log("upstream", "GetEventsForBlockIDs", err)
   194  	return res, err
   195  }
   196  
   197  func (h *FlowAccessAPIRouter) GetNetworkParameters(context context.Context, req *access.GetNetworkParametersRequest) (*access.GetNetworkParametersResponse, error) {
   198  	res, err := h.Observer.GetNetworkParameters(context, req)
   199  	h.log("observer", "GetNetworkParameters", err)
   200  	return res, err
   201  }
   202  
   203  func (h *FlowAccessAPIRouter) GetLatestProtocolStateSnapshot(context context.Context, req *access.GetLatestProtocolStateSnapshotRequest) (*access.ProtocolStateSnapshotResponse, error) {
   204  	res, err := h.Observer.GetLatestProtocolStateSnapshot(context, req)
   205  	h.log("observer", "GetLatestProtocolStateSnapshot", err)
   206  	return res, err
   207  }
   208  
   209  func (h *FlowAccessAPIRouter) GetProtocolStateSnapshotByBlockID(context context.Context, req *access.GetProtocolStateSnapshotByBlockIDRequest) (*access.ProtocolStateSnapshotResponse, error) {
   210  	res, err := h.Observer.GetProtocolStateSnapshotByBlockID(context, req)
   211  	h.log("observer", "GetProtocolStateSnapshotByBlockID", err)
   212  	return res, err
   213  }
   214  
   215  func (h *FlowAccessAPIRouter) GetProtocolStateSnapshotByHeight(context context.Context, req *access.GetProtocolStateSnapshotByHeightRequest) (*access.ProtocolStateSnapshotResponse, error) {
   216  	res, err := h.Observer.GetProtocolStateSnapshotByHeight(context, req)
   217  	h.log("observer", "GetProtocolStateSnapshotByHeight", err)
   218  	return res, err
   219  }
   220  
   221  func (h *FlowAccessAPIRouter) GetExecutionResultForBlockID(context context.Context, req *access.GetExecutionResultForBlockIDRequest) (*access.ExecutionResultForBlockIDResponse, error) {
   222  	res, err := h.Upstream.GetExecutionResultForBlockID(context, req)
   223  	h.log("upstream", "GetExecutionResultForBlockID", err)
   224  	return res, err
   225  }
   226  
   227  func (h *FlowAccessAPIRouter) GetExecutionResultByID(context context.Context, req *access.GetExecutionResultByIDRequest) (*access.ExecutionResultByIDResponse, error) {
   228  	res, err := h.Upstream.GetExecutionResultByID(context, req)
   229  	h.log("upstream", "GetExecutionResultByID", err)
   230  	return res, err
   231  }
   232  
   233  // FlowAccessAPIForwarder forwards all requests to a set of upstream access nodes or observers
   234  type FlowAccessAPIForwarder struct {
   235  	*forwarder.Forwarder
   236  }
   237  
   238  func NewFlowAccessAPIForwarder(identities flow.IdentityList, connectionFactory connection.ConnectionFactory) (*FlowAccessAPIForwarder, error) {
   239  	forwarder, err := forwarder.NewForwarder(identities, connectionFactory)
   240  	if err != nil {
   241  		return nil, err
   242  	}
   243  
   244  	return &FlowAccessAPIForwarder{
   245  		Forwarder: forwarder,
   246  	}, nil
   247  }
   248  
   249  // Ping pings the service. It is special in the sense that it responds successful,
   250  // only if all underlying services are ready.
   251  func (h *FlowAccessAPIForwarder) Ping(context context.Context, req *access.PingRequest) (*access.PingResponse, error) {
   252  	// This is a passthrough request
   253  	upstream, closer, err := h.FaultTolerantClient()
   254  	if err != nil {
   255  		return nil, err
   256  	}
   257  	defer closer.Close()
   258  	return upstream.Ping(context, req)
   259  }
   260  
   261  func (h *FlowAccessAPIForwarder) GetNodeVersionInfo(context context.Context, req *access.GetNodeVersionInfoRequest) (*access.GetNodeVersionInfoResponse, error) {
   262  	// This is a passthrough request
   263  	upstream, closer, err := h.FaultTolerantClient()
   264  	if err != nil {
   265  		return nil, err
   266  	}
   267  	defer closer.Close()
   268  	return upstream.GetNodeVersionInfo(context, req)
   269  }
   270  
   271  func (h *FlowAccessAPIForwarder) GetLatestBlockHeader(context context.Context, req *access.GetLatestBlockHeaderRequest) (*access.BlockHeaderResponse, error) {
   272  	// This is a passthrough request
   273  	upstream, closer, err := h.FaultTolerantClient()
   274  	if err != nil {
   275  		return nil, err
   276  	}
   277  	defer closer.Close()
   278  	return upstream.GetLatestBlockHeader(context, req)
   279  }
   280  
   281  func (h *FlowAccessAPIForwarder) GetBlockHeaderByID(context context.Context, req *access.GetBlockHeaderByIDRequest) (*access.BlockHeaderResponse, error) {
   282  	// This is a passthrough request
   283  	upstream, closer, err := h.FaultTolerantClient()
   284  	if err != nil {
   285  		return nil, err
   286  	}
   287  	defer closer.Close()
   288  	return upstream.GetBlockHeaderByID(context, req)
   289  }
   290  
   291  func (h *FlowAccessAPIForwarder) GetBlockHeaderByHeight(context context.Context, req *access.GetBlockHeaderByHeightRequest) (*access.BlockHeaderResponse, error) {
   292  	// This is a passthrough request
   293  	upstream, closer, err := h.FaultTolerantClient()
   294  	if err != nil {
   295  		return nil, err
   296  	}
   297  	defer closer.Close()
   298  	return upstream.GetBlockHeaderByHeight(context, req)
   299  }
   300  
   301  func (h *FlowAccessAPIForwarder) GetLatestBlock(context context.Context, req *access.GetLatestBlockRequest) (*access.BlockResponse, error) {
   302  	// This is a passthrough request
   303  	upstream, closer, err := h.FaultTolerantClient()
   304  	if err != nil {
   305  		return nil, err
   306  	}
   307  	defer closer.Close()
   308  	return upstream.GetLatestBlock(context, req)
   309  }
   310  
   311  func (h *FlowAccessAPIForwarder) GetBlockByID(context context.Context, req *access.GetBlockByIDRequest) (*access.BlockResponse, error) {
   312  	// This is a passthrough request
   313  	upstream, closer, err := h.FaultTolerantClient()
   314  	if err != nil {
   315  		return nil, err
   316  	}
   317  	defer closer.Close()
   318  	return upstream.GetBlockByID(context, req)
   319  }
   320  
   321  func (h *FlowAccessAPIForwarder) GetBlockByHeight(context context.Context, req *access.GetBlockByHeightRequest) (*access.BlockResponse, error) {
   322  	// This is a passthrough request
   323  	upstream, closer, err := h.FaultTolerantClient()
   324  	if err != nil {
   325  		return nil, err
   326  	}
   327  	defer closer.Close()
   328  	return upstream.GetBlockByHeight(context, req)
   329  }
   330  
   331  func (h *FlowAccessAPIForwarder) GetCollectionByID(context context.Context, req *access.GetCollectionByIDRequest) (*access.CollectionResponse, error) {
   332  	// This is a passthrough request
   333  	upstream, closer, err := h.FaultTolerantClient()
   334  	if err != nil {
   335  		return nil, err
   336  	}
   337  	defer closer.Close()
   338  	return upstream.GetCollectionByID(context, req)
   339  }
   340  
   341  func (h *FlowAccessAPIForwarder) SendTransaction(context context.Context, req *access.SendTransactionRequest) (*access.SendTransactionResponse, error) {
   342  	// This is a passthrough request
   343  	upstream, closer, err := h.FaultTolerantClient()
   344  	if err != nil {
   345  		return nil, err
   346  	}
   347  	defer closer.Close()
   348  	return upstream.SendTransaction(context, req)
   349  }
   350  
   351  func (h *FlowAccessAPIForwarder) GetTransaction(context context.Context, req *access.GetTransactionRequest) (*access.TransactionResponse, error) {
   352  	// This is a passthrough request
   353  	upstream, closer, err := h.FaultTolerantClient()
   354  	if err != nil {
   355  		return nil, err
   356  	}
   357  	defer closer.Close()
   358  	return upstream.GetTransaction(context, req)
   359  }
   360  
   361  func (h *FlowAccessAPIForwarder) GetTransactionResult(context context.Context, req *access.GetTransactionRequest) (*access.TransactionResultResponse, error) {
   362  	// This is a passthrough request
   363  	upstream, closer, err := h.FaultTolerantClient()
   364  	if err != nil {
   365  		return nil, err
   366  	}
   367  	defer closer.Close()
   368  	return upstream.GetTransactionResult(context, req)
   369  }
   370  
   371  func (h *FlowAccessAPIForwarder) GetSystemTransaction(context context.Context, req *access.GetSystemTransactionRequest) (*access.TransactionResponse, error) {
   372  	// This is a passthrough request
   373  	upstream, closer, err := h.FaultTolerantClient()
   374  	if err != nil {
   375  		return nil, err
   376  	}
   377  	defer closer.Close()
   378  	return upstream.GetSystemTransaction(context, req)
   379  }
   380  
   381  func (h *FlowAccessAPIForwarder) GetSystemTransactionResult(context context.Context, req *access.GetSystemTransactionResultRequest) (*access.TransactionResultResponse, error) {
   382  	// This is a passthrough request
   383  	upstream, closer, err := h.FaultTolerantClient()
   384  	if err != nil {
   385  		return nil, err
   386  	}
   387  	defer closer.Close()
   388  	return upstream.GetSystemTransactionResult(context, req)
   389  }
   390  
   391  func (h *FlowAccessAPIForwarder) GetTransactionResultByIndex(context context.Context, req *access.GetTransactionByIndexRequest) (*access.TransactionResultResponse, error) {
   392  	// This is a passthrough request
   393  	upstream, closer, err := h.FaultTolerantClient()
   394  	if err != nil {
   395  		return nil, err
   396  	}
   397  	defer closer.Close()
   398  	return upstream.GetTransactionResultByIndex(context, req)
   399  }
   400  
   401  func (h *FlowAccessAPIForwarder) GetTransactionResultsByBlockID(context context.Context, req *access.GetTransactionsByBlockIDRequest) (*access.TransactionResultsResponse, error) {
   402  	// This is a passthrough request
   403  	upstream, closer, err := h.FaultTolerantClient()
   404  	if err != nil {
   405  		return nil, err
   406  	}
   407  	defer closer.Close()
   408  	return upstream.GetTransactionResultsByBlockID(context, req)
   409  }
   410  
   411  func (h *FlowAccessAPIForwarder) GetTransactionsByBlockID(context context.Context, req *access.GetTransactionsByBlockIDRequest) (*access.TransactionsResponse, error) {
   412  	upstream, closer, err := h.FaultTolerantClient()
   413  	if err != nil {
   414  		return nil, err
   415  	}
   416  	defer closer.Close()
   417  	return upstream.GetTransactionsByBlockID(context, req)
   418  }
   419  
   420  func (h *FlowAccessAPIForwarder) GetAccount(context context.Context, req *access.GetAccountRequest) (*access.GetAccountResponse, error) {
   421  	// This is a passthrough request
   422  	upstream, closer, err := h.FaultTolerantClient()
   423  	if err != nil {
   424  		return nil, err
   425  	}
   426  	defer closer.Close()
   427  	return upstream.GetAccount(context, req)
   428  }
   429  
   430  func (h *FlowAccessAPIForwarder) GetAccountAtLatestBlock(context context.Context, req *access.GetAccountAtLatestBlockRequest) (*access.AccountResponse, error) {
   431  	// This is a passthrough request
   432  	upstream, closer, err := h.FaultTolerantClient()
   433  	if err != nil {
   434  		return nil, err
   435  	}
   436  	defer closer.Close()
   437  	return upstream.GetAccountAtLatestBlock(context, req)
   438  }
   439  
   440  func (h *FlowAccessAPIForwarder) GetAccountAtBlockHeight(context context.Context, req *access.GetAccountAtBlockHeightRequest) (*access.AccountResponse, error) {
   441  	// This is a passthrough request
   442  	upstream, closer, err := h.FaultTolerantClient()
   443  	if err != nil {
   444  		return nil, err
   445  	}
   446  	defer closer.Close()
   447  	return upstream.GetAccountAtBlockHeight(context, req)
   448  }
   449  
   450  func (h *FlowAccessAPIForwarder) ExecuteScriptAtLatestBlock(context context.Context, req *access.ExecuteScriptAtLatestBlockRequest) (*access.ExecuteScriptResponse, error) {
   451  	// This is a passthrough request
   452  	upstream, closer, err := h.FaultTolerantClient()
   453  	if err != nil {
   454  		return nil, err
   455  	}
   456  	defer closer.Close()
   457  	return upstream.ExecuteScriptAtLatestBlock(context, req)
   458  }
   459  
   460  func (h *FlowAccessAPIForwarder) ExecuteScriptAtBlockID(context context.Context, req *access.ExecuteScriptAtBlockIDRequest) (*access.ExecuteScriptResponse, error) {
   461  	// This is a passthrough request
   462  	upstream, closer, err := h.FaultTolerantClient()
   463  	if err != nil {
   464  		return nil, err
   465  	}
   466  	defer closer.Close()
   467  	return upstream.ExecuteScriptAtBlockID(context, req)
   468  }
   469  
   470  func (h *FlowAccessAPIForwarder) ExecuteScriptAtBlockHeight(context context.Context, req *access.ExecuteScriptAtBlockHeightRequest) (*access.ExecuteScriptResponse, error) {
   471  	// This is a passthrough request
   472  	upstream, closer, err := h.FaultTolerantClient()
   473  	if err != nil {
   474  		return nil, err
   475  	}
   476  	defer closer.Close()
   477  	return upstream.ExecuteScriptAtBlockHeight(context, req)
   478  }
   479  
   480  func (h *FlowAccessAPIForwarder) GetEventsForHeightRange(context context.Context, req *access.GetEventsForHeightRangeRequest) (*access.EventsResponse, error) {
   481  	// This is a passthrough request
   482  	upstream, closer, err := h.FaultTolerantClient()
   483  	if err != nil {
   484  		return nil, err
   485  	}
   486  	defer closer.Close()
   487  	return upstream.GetEventsForHeightRange(context, req)
   488  }
   489  
   490  func (h *FlowAccessAPIForwarder) GetEventsForBlockIDs(context context.Context, req *access.GetEventsForBlockIDsRequest) (*access.EventsResponse, error) {
   491  	// This is a passthrough request
   492  	upstream, closer, err := h.FaultTolerantClient()
   493  	if err != nil {
   494  		return nil, err
   495  	}
   496  	defer closer.Close()
   497  	return upstream.GetEventsForBlockIDs(context, req)
   498  }
   499  
   500  func (h *FlowAccessAPIForwarder) GetNetworkParameters(context context.Context, req *access.GetNetworkParametersRequest) (*access.GetNetworkParametersResponse, error) {
   501  	// This is a passthrough request
   502  	upstream, closer, err := h.FaultTolerantClient()
   503  	if err != nil {
   504  		return nil, err
   505  	}
   506  	defer closer.Close()
   507  	return upstream.GetNetworkParameters(context, req)
   508  }
   509  
   510  func (h *FlowAccessAPIForwarder) GetLatestProtocolStateSnapshot(context context.Context, req *access.GetLatestProtocolStateSnapshotRequest) (*access.ProtocolStateSnapshotResponse, error) {
   511  	// This is a passthrough request
   512  	upstream, closer, err := h.FaultTolerantClient()
   513  	if err != nil {
   514  		return nil, err
   515  	}
   516  	defer closer.Close()
   517  	return upstream.GetLatestProtocolStateSnapshot(context, req)
   518  }
   519  
   520  func (h *FlowAccessAPIForwarder) GetExecutionResultForBlockID(context context.Context, req *access.GetExecutionResultForBlockIDRequest) (*access.ExecutionResultForBlockIDResponse, error) {
   521  	// This is a passthrough request
   522  	upstream, closer, err := h.FaultTolerantClient()
   523  	if err != nil {
   524  		return nil, err
   525  	}
   526  	defer closer.Close()
   527  	return upstream.GetExecutionResultForBlockID(context, req)
   528  }
   529  
   530  func (h *FlowAccessAPIForwarder) GetExecutionResultByID(context context.Context, req *access.GetExecutionResultByIDRequest) (*access.ExecutionResultByIDResponse, error) {
   531  	// This is a passthrough request
   532  	upstream, closer, err := h.FaultTolerantClient()
   533  	if err != nil {
   534  		return nil, err
   535  	}
   536  	defer closer.Close()
   537  	return upstream.GetExecutionResultByID(context, req)
   538  }