Files
clio/proto/org/xrpl/rpc/v1
2020-12-14 21:39:44 -05:00
..
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00
2020-12-14 21:39:44 -05:00

This folder contains the protocol buffer definitions used by the rippled gRPC API. The gRPC API attempts to mimic the JSON/Websocket API as much as possible. As of April 2020, the gRPC API supports a subset of the full rippled API: tx, account_tx, account_info, fee and submit.

Making Changes

Wire Format and Backwards Compatibility

When making changes to the protocol buffer definitions in this folder, care must be taken to ensure the changes do not break the wire format, which would break backwards compatibility. At a high level, do not change any existing fields. This includes the field's name, type and field number. Do not remove any existing fields. It is always safe to add fields; just remember to give each of the new fields a unique field number. The field numbers don't have to be in any particular order and there can be gaps. More info about what changes break the wire format can be found here.

Conventions

For fields that are reused across different message types, we define the field as a unique message type in common.proto. The name of the message type is the same as the field name, with the exception that the field name itself is snake case, whereas the message type is in Pascal case. The message type has one field, called value. This pattern does not need to be strictly followed across the entire API, but should be followed for transactions and ledger objects, since there is a high rate of field reuse across different transactions and ledger objects. The motivation for this pattern is two-fold. First, we ensure the field has the same type everywhere that the field is used. Second, wrapping primitive types in their own message type prevents default initialization of those primitive types. For example, uint32 is initialized to 0 if not explicitly set; there is no way to tell if the client or server set the field to 0 (which may be a valid value for the field) or the field was default initialized.

Name Collisions

Each message type must have a unique name. To resolve collisions, add a suffix to one or more message types. For instance, ledger objects and transaction types often have the same name (DepositPreauth for example). To resolve this, the DepositPreauth ledger object is named DepositPreauthObject.

To add a field or message type

To add a field to a message, define the fields type, name and unique index. To add a new message type, give the message type a unique name. Then, add the appropriate C++ code in GRPCHelpers.cpp, or in the handler itself, to serialize/deserialize the new field or message type.

To add a new gRPC method

To add a new gRPC method, add the gRPC method in xrp_ledger.proto. The method name should begin with a verb. Define the request and response types in their own file. The name of the request type should be the method name suffixed with Request, and the response type name should be the method name suffixed with Response. For example, the GetAccountInfo method has request type GetAccountInfoRequest and response type GetAccountInfoResponse.

After defining the protobuf messages for the new method, add an instantiation of the templated CallData class in GRPCServerImpl::setupListeners(). The template parameters should be the request type and the response type.

Finally, define the handler itself in the appropriate file under the src/ripple/rpc/handlers folder. If the method already has a JSON/Websocket equivalent, write the gRPC handler in the same file, and abstract common logic into helper functions (see Tx.cpp or AccountTx.cpp for an example).

Testing

When modifying an existing gRPC method, be sure to test that modification in the corresponding, existing unit test. When creating a new gRPC method, implement a class that derives from GRPCTestClientBase, and use the newly created class to call the new method. See the class GrpcTxClient in the file Tx_test.cpp for an example. The gRPC tests are paired with their JSON counterpart, and the tests should mirror the JSON test as much as possible.

Refer to the Protocol Buffers language guide for more detailed information about Protocol Buffers.