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