Skip to content

Latest commit

 

History

History
43 lines (31 loc) · 2.73 KB

File metadata and controls

43 lines (31 loc) · 2.73 KB

gRPC

gRPC is a simple protocol built on top of HTTP/2. The typical way of working with gRPC is to use the protoc compiler to generate stubs for each method in a gRPC service. The stubs take pre-parsed protobuf objects and return protobuf objects and all serialization is handled by the framework. This doesn't work all that well for us.

When we receive a gRPC request for paid queries or for any transaction, we need the raw bytes to send to the hashgraph platform for consensus. We would like to get the raw bytes from the gRPC request, not pre-parsed objects. We also have our own highly tuned protobuf parsing library that generates nearly no garbage, and we would like to use it for parsing rather than the code generated by protoc. For these reasons, the built-in gRPC frameworks are of little to use to us.

It turns out that gRPC is an extremely simple API built on top of HTTP/2, and we can therefore have our own simple gRPC framework built on top of an HTTP/2 server (like Netty) and get everything we want.

Architecture Overview

The gRPC package in Hedera App defines GrpcServerManager interface with a number of lifecycle methods such as start(), stop() and isRunning(), and an implementation of this interface based on Netty. Hedera App runs at least one gRPC server on the port specified in the config, and optionally it will also attempt to run additional gRPC servers on the TLS or node operator ports specified in the same config.

NettyGrpcServerManager

NettyGrpcServerManager is an implementation of GrpcServerManager and it uses the Hedera App's services registry in order to gather the set of RPC endpoints and their corresponding handlers. Given that set and using the GrpcServiceBuilder class we produce gRPC ServerServiceDefinitions which can be directly registered with the Netty server.

GrpcServiceBuilder

As mentioned earlier, the GrpcServiceBuilder produces gRPC ServerServiceDefinitions. These definitions are configured with the appropriate service handlers and gRPC ServerCall.Listener methods. At runtime, the Netty server invokes these listener methods. For instance, the onMessage() method is where service logic is integrated to handle transactions or queries using the abstract MethodBase type.

MethodBase

In this abstract class, the size of incoming requests is validated, and requests that exceed the allowed size are rejected. Additionally, we track metrics for number of calls and calls per second that were received, failed or successfully handled. There are two concrete types(QueryMethod and TransactionMethod) that extend MethodBase and implement the handle() method, which when called will invoke the QueryWorkflow or IngestWorkflow respectively.

NEXT: Records