github.com/koko1123/flow-go-1@v0.29.6/engine/access/rpc/engine_builder.go (about)

     1  package rpc
     2  
     3  import (
     4  	"fmt"
     5  
     6  	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
     7  	accessproto "github.com/onflow/flow/protobuf/go/flow/access"
     8  	legacyaccessproto "github.com/onflow/flow/protobuf/go/flow/legacy/access"
     9  
    10  	"github.com/koko1123/flow-go-1/access"
    11  	legacyaccess "github.com/koko1123/flow-go-1/access/legacy"
    12  	"github.com/koko1123/flow-go-1/consensus/hotstuff"
    13  )
    14  
    15  type RPCEngineBuilder struct {
    16  	*Engine
    17  
    18  	// optional parameters, only one can be set during build phase
    19  	signerIndicesDecoder hotstuff.BlockSignerDecoder
    20  	handler              accessproto.AccessAPIServer // Use the parent interface instead of implementation, so that we can assign it to proxy.
    21  }
    22  
    23  // NewRPCEngineBuilder helps to build a new RPC engine.
    24  func NewRPCEngineBuilder(engine *Engine) *RPCEngineBuilder {
    25  	// the default handler will use the engine.backend implementation
    26  	return &RPCEngineBuilder{
    27  		Engine: engine,
    28  	}
    29  }
    30  
    31  func (builder *RPCEngineBuilder) Handler() accessproto.AccessAPIServer {
    32  	return builder.handler
    33  }
    34  
    35  // WithBlockSignerDecoder specifies that signer indices in block headers should be translated
    36  // to full node IDs with the given decoder.
    37  // Caution:
    38  // you can inject either a `BlockSignerDecoder` (via method `WithBlockSignerDecoder`)
    39  // or an `AccessAPIServer` (via method `WithNewHandler`); but not both. If both are
    40  // specified, the builder will error during the build step.
    41  //
    42  // Returns self-reference for chaining.
    43  func (builder *RPCEngineBuilder) WithBlockSignerDecoder(signerIndicesDecoder hotstuff.BlockSignerDecoder) *RPCEngineBuilder {
    44  	builder.signerIndicesDecoder = signerIndicesDecoder
    45  	return builder
    46  }
    47  
    48  // WithNewHandler specifies that the given `AccessAPIServer` should be used for serving API queries.
    49  // Caution:
    50  // you can inject either a `BlockSignerDecoder` (via method `WithBlockSignerDecoder`)
    51  // or an `AccessAPIServer` (via method `WithNewHandler`); but not both. If both are
    52  // specified, the builder will error during the build step.
    53  //
    54  // Returns self-reference for chaining.
    55  func (builder *RPCEngineBuilder) WithNewHandler(handler accessproto.AccessAPIServer) *RPCEngineBuilder {
    56  	builder.handler = handler
    57  	return builder
    58  }
    59  
    60  // WithLegacy specifies that a legacy access API should be instantiated
    61  // Returns self-reference for chaining.
    62  func (builder *RPCEngineBuilder) WithLegacy() *RPCEngineBuilder {
    63  	// Register legacy gRPC handlers for backwards compatibility, to be removed at a later date
    64  	legacyaccessproto.RegisterAccessAPIServer(
    65  		builder.unsecureGrpcServer,
    66  		legacyaccess.NewHandler(builder.backend, builder.chain),
    67  	)
    68  	legacyaccessproto.RegisterAccessAPIServer(
    69  		builder.secureGrpcServer,
    70  		legacyaccess.NewHandler(builder.backend, builder.chain),
    71  	)
    72  	return builder
    73  }
    74  
    75  // WithMetrics specifies the metrics should be collected.
    76  // Returns self-reference for chaining.
    77  func (builder *RPCEngineBuilder) WithMetrics() *RPCEngineBuilder {
    78  	// Not interested in legacy metrics, so initialize here
    79  	grpc_prometheus.EnableHandlingTimeHistogram()
    80  	grpc_prometheus.Register(builder.unsecureGrpcServer)
    81  	grpc_prometheus.Register(builder.secureGrpcServer)
    82  	return builder
    83  }
    84  
    85  func (builder *RPCEngineBuilder) Build() (*Engine, error) {
    86  	if builder.signerIndicesDecoder != nil && builder.handler != nil {
    87  		return nil, fmt.Errorf("only BlockSignerDecoder (via method `WithBlockSignerDecoder`) or AccessAPIServer (via method `WithNewHandler`) can be specified but not both")
    88  	}
    89  	handler := builder.handler
    90  	if handler == nil {
    91  		if builder.signerIndicesDecoder == nil {
    92  			handler = access.NewHandler(builder.Engine.backend, builder.Engine.chain)
    93  		} else {
    94  			handler = access.NewHandler(builder.Engine.backend, builder.Engine.chain, access.WithBlockSignerDecoder(builder.signerIndicesDecoder))
    95  		}
    96  	}
    97  	accessproto.RegisterAccessAPIServer(builder.unsecureGrpcServer, handler)
    98  	accessproto.RegisterAccessAPIServer(builder.secureGrpcServer, handler)
    99  	return builder.Engine, nil
   100  }