rippled
Loading...
Searching...
No Matches
GRPCServer.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_CORE_GRPCSERVER_H_INCLUDED
21#define RIPPLE_CORE_GRPCSERVER_H_INCLUDED
22
23#include <xrpld/app/main/Application.h>
24#include <xrpld/core/JobQueue.h>
25#include <xrpld/rpc/Context.h>
26#include <xrpld/rpc/GRPCHandlers.h>
27#include <xrpld/rpc/InfoSub.h>
28#include <xrpld/rpc/Role.h>
29#include <xrpld/rpc/detail/Handler.h>
30#include <xrpld/rpc/detail/RPCHelpers.h>
31
32#include <xrpl/proto/org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h>
33#include <xrpl/resource/Charge.h>
34
35#include <grpcpp/grpcpp.h>
36
37namespace ripple {
38
39// Interface that CallData implements
41{
42public:
43 virtual ~Processor() = default;
44
45 Processor() = default;
46
47 Processor(Processor const&) = delete;
48
50 operator=(Processor const&) = delete;
51
52 // process a request that has arrived. Can only be called once per instance
53 virtual void
54 process() = 0;
55
56 // create a new instance of this CallData object, with the same type
57 //(same template parameters) as original. This is called when a CallData
58 // object starts processing a request. Creating a new instance allows the
59 // server to handle additional requests while the first is being processed
61 clone() = 0;
62
63 // true if this object has finished processing the request. Object will be
64 // deleted once this function returns true
65 virtual bool
67};
68
69class GRPCServerImpl final
70{
71private:
72 // CompletionQueue returns events that have occurred, or events that have
73 // been cancelled
75
77
78 // The gRPC service defined by the .proto files
79 org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService service_;
80
82
84
87
89
91
92 // typedef for function to bind a listener
93 // This is always of the form:
94 // org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService::Request[RPC NAME]
95 template <class Request, class Response>
97 org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService&,
98 grpc::ServerContext*,
99 Request*,
100 grpc::ServerAsyncResponseWriter<Response>*,
101 grpc::CompletionQueue*,
102 grpc::ServerCompletionQueue*,
103 void*)>;
104
105 // typedef for actual handler (that populates a response)
106 // handlers are defined in rpc/GRPCHandlers.h
107 template <class Request, class Response>
110 // This implementation is currently limited to v1 of the API
111 static unsigned constexpr apiVersion = 1;
112
113 template <class Request, class Response>
114 using Forward = std::function<grpc::Status(
115 org::xrpl::rpc::v1::XRPLedgerAPIService::Stub*,
116 grpc::ClientContext*,
117 Request,
118 Response*)>;
119
120public:
121 explicit GRPCServerImpl(Application& app);
122
124
126 operator=(GRPCServerImpl const&) = delete;
127
128 void
129 shutdown();
130
131 // setup the server and listeners
132 // returns true if server started successfully
133 bool
134 start();
135
136 // the main event loop
137 void
138 handleRpcs();
139
140 // Create a CallData object for each RPC. Return created objects in vector
143
144 // Obtaining actually binded endpoint (if port 0 was used for server setup).
145 boost::asio::ip::tcp::endpoint
146 getEndpoint() const;
147
148private:
149 // Class encompasing the state and logic needed to serve a request.
150 template <class Request, class Response>
152 : public Processor,
153 public std::enable_shared_from_this<CallData<Request, Response>>
154 {
155 private:
156 // The means of communication with the gRPC runtime for an asynchronous
157 // server.
158 org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService& service_;
159
160 // The producer-consumer queue for asynchronous server notifications.
161 grpc::ServerCompletionQueue& cq_;
162
163 // Context for the rpc, allowing to tweak aspects of it such as the use
164 // of compression, authentication, as well as to send metadata back to
165 // the client.
166 grpc::ServerContext ctx_;
167
168 // true if finished processing request
169 // Note, this variable does not need to be atomic, since it is
170 // currently only accessed from one thread. However, isFinished(),
171 // which returns the value of this variable, is public facing. In the
172 // interest of avoiding future concurrency bugs, we make it atomic.
174
176
177 // What we get from the client.
178 Request request_;
179
180 // The means to get back to the client.
181 grpc::ServerAsyncResponseWriter<Response> responder_;
182
183 // Function that creates a listener for specific request type
185
186 // Function that processes a request
188
189 // Function to call to forward to another server
191
192 // Condition required for this RPC
194
195 // Load type for this RPC
197
199
200 public:
201 virtual ~CallData() = default;
202
203 // Take in the "service" instance (in this case representing an
204 // asynchronous server) and the completion queue "cq" used for
205 // asynchronous communication with the gRPC runtime.
206 explicit CallData(
207 org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService& service,
208 grpc::ServerCompletionQueue& cq,
209 Application& app,
213 RPC::Condition requiredCondition,
214 Resource::Charge loadType,
215 std::vector<boost::asio::ip::address> const& secureGatewayIPs);
216
217 CallData(CallData const&) = delete;
218
219 CallData&
220 operator=(CallData const&) = delete;
221
222 virtual void
223 process() override;
224
225 virtual bool
226 isFinished() override;
227
229 clone() override;
230
231 private:
232 // process the request. Called inside the coroutine passed to JobQueue
233 void
235
236 // return load type of this RPC
238 getLoadType();
239
240 // return the Role used for this RPC
241 Role
242 getRole(bool isUnlimited);
243
244 // register endpoint with ResourceManager and return usage
246 getUsage();
247
248 // Returns the ip of the client
249 // Empty optional if there was an error decoding the client ip
252
253 // Returns the endpoint of the client.
254 // Empty optional if there was an error decoding the client
255 // endpoint
258
259 // If the request was proxied through
260 // another rippled node, returns the ip of the originating client.
261 // Empty optional if request was not proxied or there was an error
262 // decoding the client ip
265
266 // If the request was proxied through
267 // another rippled node, returns the endpoint of the originating client.
268 // Empty optional if request was not proxied or there was an error
269 // decoding the client endpoint
272
273 // Returns the user specified in the request. Empty optional if no user
274 // was specified
276 getUser();
277
278 // Sets is_unlimited in response to value of clientIsUnlimited
279 // Does nothing if is_unlimited is not a field of the response
280 void
281 setIsUnlimited(Response& response, bool isUnlimited);
282
283 // True if the client is exempt from resource controls
284 bool
286
287 // True if the request was proxied through another rippled node prior
288 // to arriving here
289 bool
291
292 // forward request to a p2p node
293 void
295
296 }; // CallData
297
298}; // GRPCServerImpl
299
301{
302public:
303 explicit GRPCServer(Application& app) : impl_(app)
304 {
305 }
306
307 GRPCServer(GRPCServer const&) = delete;
308
310 operator=(GRPCServer const&) = delete;
311
312 bool
313 start();
314
315 void
316 stop();
317
318 ~GRPCServer();
319
320 boost::asio::ip::tcp::endpoint
321 getEndpoint() const;
322
323private:
326 bool running_ = false;
327};
328} // namespace ripple
329#endif
A generic endpoint for log messages.
Definition Journal.h:60
CallData(CallData const &)=delete
Forward< Request, Response > forward_
Definition GRPCServer.h:190
Resource::Consumer getUsage()
std::optional< std::string > getUser()
grpc::ServerCompletionQueue & cq_
Definition GRPCServer.h:161
Handler< Request, Response > handler_
Definition GRPCServer.h:187
CallData & operator=(CallData const &)=delete
void setIsUnlimited(Response &response, bool isUnlimited)
std::optional< boost::asio::ip::address > getClientIpAddress()
std::optional< boost::asio::ip::tcp::endpoint > getProxiedClientEndpoint()
BindListener< Request, Response > bindListener_
Definition GRPCServer.h:184
grpc::ServerAsyncResponseWriter< Response > responder_
Definition GRPCServer.h:181
Role getRole(bool isUnlimited)
std::vector< boost::asio::ip::address > const & secureGatewayIPs_
Definition GRPCServer.h:198
std::shared_ptr< Processor > clone() override
std::optional< boost::asio::ip::tcp::endpoint > getClientEndpoint()
std::optional< boost::asio::ip::address > getProxiedClientIpAddress()
org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService & service_
Definition GRPCServer.h:158
virtual void process() override
virtual bool isFinished() override
void forwardToP2p(RPC::GRPCContext< Request > &context)
std::string serverAddress_
Definition GRPCServer.h:85
Application & app_
Definition GRPCServer.h:83
std::vector< std::shared_ptr< Processor > > setupListeners()
std::unique_ptr< grpc::Server > server_
Definition GRPCServer.h:81
std::unique_ptr< grpc::ServerCompletionQueue > cq_
Definition GRPCServer.h:74
org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService service_
Definition GRPCServer.h:79
std::vector< std::shared_ptr< Processor > > requests_
Definition GRPCServer.h:76
GRPCServerImpl(GRPCServerImpl const &)=delete
GRPCServerImpl & operator=(GRPCServerImpl const &)=delete
static unsigned constexpr apiVersion
Definition GRPCServer.h:111
boost::asio::ip::tcp::endpoint getEndpoint() const
std::vector< boost::asio::ip::address > secureGatewayIPs_
Definition GRPCServer.h:88
std::uint16_t serverPort_
Definition GRPCServer.h:86
beast::Journal journal_
Definition GRPCServer.h:90
GRPCServer(Application &app)
Definition GRPCServer.h:303
GRPCServer & operator=(GRPCServer const &)=delete
std::thread thread_
Definition GRPCServer.h:325
boost::asio::ip::tcp::endpoint getEndpoint() const
GRPCServerImpl impl_
Definition GRPCServer.h:324
GRPCServer(GRPCServer const &)=delete
virtual void process()=0
virtual bool isFinished()=0
Processor()=default
virtual std::shared_ptr< Processor > clone()=0
Processor(Processor const &)=delete
Processor & operator=(Processor const &)=delete
virtual ~Processor()=default
A consumption charge.
Definition Charge.h:30
An endpoint that consumes resources.
Definition Consumer.h:35
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition Role.cpp:125
Role
Indicates the level of administrative permission to grant.
Definition Role.h:44