rippled
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 <ripple/app/main/Application.h>
24 #include <ripple/core/JobQueue.h>
25 #include <ripple/core/Stoppable.h>
26 #include <ripple/net/InfoSub.h>
27 #include <ripple/protocol/ErrorCodes.h>
28 #include <ripple/resource/Charge.h>
29 #include <ripple/rpc/Context.h>
30 #include <ripple/rpc/GRPCHandlers.h>
31 #include <ripple/rpc/Role.h>
32 #include <ripple/rpc/impl/Handler.h>
33 #include <ripple/rpc/impl/RPCHelpers.h>
34 #include <ripple/rpc/impl/Tuning.h>
35 
36 #include "org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h"
37 #include <grpcpp/grpcpp.h>
38 
39 namespace ripple {
40 
41 // Interface that CallData implements
42 class Processor
43 {
44 public:
45  virtual ~Processor() = default;
46 
47  Processor() = default;
48 
49  Processor(const Processor&) = delete;
50 
51  Processor&
52  operator=(const Processor&) = delete;
53 
54  // process a request that has arrived. Can only be called once per instance
55  virtual void
56  process() = 0;
57 
58  // create a new instance of this CallData object, with the same type
59  //(same template parameters) as original. This is called when a CallData
60  // object starts processing a request. Creating a new instance allows the
61  // server to handle additional requests while the first is being processed
63  clone() = 0;
64 
65  // true if this object has finished processing the request. Object will be
66  // deleted once this function returns true
67  virtual bool
68  isFinished() = 0;
69 };
70 
71 class GRPCServerImpl final
72 {
73 private:
74  // CompletionQueue returns events that have occurred, or events that have
75  // been cancelled
77 
79 
80  // The gRPC service defined by the .proto files
81  org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService service_;
82 
84 
86 
88 
90 
92 
93  // typedef for function to bind a listener
94  // This is always of the form:
95  // org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService::Request[RPC NAME]
96  template <class Request, class Response>
97  using BindListener = std::function<void(
98  org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService&,
99  grpc::ServerContext*,
100  Request*,
101  grpc::ServerAsyncResponseWriter<Response>*,
102  grpc::CompletionQueue*,
103  grpc::ServerCompletionQueue*,
104  void*)>;
105 
106  // typedef for actual handler (that populates a response)
107  // handlers are defined in rpc/GRPCHandlers.h
108  template <class Request, class Response>
111  // This implementation is currently limited to v1 of the API
112  static unsigned constexpr apiVersion = 1;
113 
114  template <class Request, class Response>
115  using Forward = std::function<grpc::Status(
116  org::xrpl::rpc::v1::XRPLedgerAPIService::Stub*,
117  grpc::ClientContext*,
118  Request,
119  Response*)>;
120 
121 public:
122  explicit GRPCServerImpl(Application& app);
123 
124  GRPCServerImpl(const GRPCServerImpl&) = delete;
125 
127  operator=(const GRPCServerImpl&) = delete;
128 
129  void
130  shutdown();
131 
132  // setup the server and listeners
133  // returns true if server started successfully
134  bool
135  start();
136 
137  // the main event loop
138  void
139  handleRpcs();
140 
141  // Create a CallData object for each RPC. Return created objects in vector
143  setupListeners();
144 
145 private:
146  // Class encompasing the state and logic needed to serve a request.
147  template <class Request, class Response>
148  class CallData
149  : public Processor,
150  public std::enable_shared_from_this<CallData<Request, Response>>
151  {
152  private:
153  // The means of communication with the gRPC runtime for an asynchronous
154  // server.
155  org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService& service_;
156 
157  // The producer-consumer queue for asynchronous server notifications.
158  grpc::ServerCompletionQueue& cq_;
159 
160  // Context for the rpc, allowing to tweak aspects of it such as the use
161  // of compression, authentication, as well as to send metadata back to
162  // the client.
163  grpc::ServerContext ctx_;
164 
165  // true if finished processing request
166  // Note, this variable does not need to be atomic, since it is
167  // currently only accessed from one thread. However, isFinished(),
168  // which returns the value of this variable, is public facing. In the
169  // interest of avoiding future concurrency bugs, we make it atomic.
171 
173 
174  // What we get from the client.
175  Request request_;
176 
177  // The means to get back to the client.
178  grpc::ServerAsyncResponseWriter<Response> responder_;
179 
180  // Function that creates a listener for specific request type
182 
183  // Function that processes a request
185 
186  // Function to call to forward to another server
188 
189  // Condition required for this RPC
191 
192  // Load type for this RPC
194 
196 
197  public:
198  virtual ~CallData() = default;
199 
200  // Take in the "service" instance (in this case representing an
201  // asynchronous server) and the completion queue "cq" used for
202  // asynchronous communication with the gRPC runtime.
203  explicit CallData(
204  org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService& service,
205  grpc::ServerCompletionQueue& cq,
206  Application& app,
207  BindListener<Request, Response> bindListener,
210  RPC::Condition requiredCondition,
211  Resource::Charge loadType,
212  std::vector<boost::asio::ip::address> const& secureGatewayIPs);
213 
214  CallData(const CallData&) = delete;
215 
216  CallData&
217  operator=(const CallData&) = delete;
218 
219  virtual void
220  process() override;
221 
222  virtual bool
223  isFinished() override;
224 
226  clone() override;
227 
228  private:
229  // process the request. Called inside the coroutine passed to JobQueue
230  void
232 
233  // return load type of this RPC
235  getLoadType();
236 
237  // return the Role used for this RPC
238  Role
239  getRole(bool isUnlimited);
240 
241  // register endpoint with ResourceManager and return usage
243  getUsage();
244 
245  // Returns the ip of the client
246  // Empty optional if there was an error decoding the client ip
249 
250  // Returns the endpoint of the client.
251  // Empty optional if there was an error decoding the client
252  // endpoint
255 
256  // If the request was proxied through
257  // another rippled node, returns the ip of the originating client.
258  // Empty optional if request was not proxied or there was an error
259  // decoding the client ip
262 
263  // If the request was proxied through
264  // another rippled node, returns the endpoint of the originating client.
265  // Empty optional if request was not proxied or there was an error
266  // decoding the client endpoint
269 
270  // Returns the user specified in the request. Empty optional if no user
271  // was specified
273  getUser();
274 
275  // Sets is_unlimited in response to value of clientIsUnlimited
276  // Does nothing if is_unlimited is not a field of the response
277  void
278  setIsUnlimited(Response& response, bool isUnlimited);
279 
280  // True if the client is exempt from resource controls
281  bool
283 
284  // True if the request was proxied through another rippled node prior
285  // to arriving here
286  bool
287  wasForwarded();
288 
289  // forward request to a p2p node
290  void
292 
293  }; // CallData
294 
295 }; // GRPCServerImpl
296 
297 class GRPCServer : public Stoppable
298 {
299 public:
300  explicit GRPCServer(Application& app, Stoppable& parent)
301  : Stoppable("GRPCServer", parent), impl_(app)
302  {
303  }
304 
305  GRPCServer(const GRPCServer&) = delete;
306 
307  GRPCServer&
308  operator=(const GRPCServer&) = delete;
309 
310  void
311  onStart() override;
312 
313  void
314  onStop() override;
315 
316  ~GRPCServer() override;
317 
318 private:
321  bool running_ = false;
322 };
323 } // namespace ripple
324 #endif
ripple::GRPCServer::onStart
void onStart() override
Override called during start.
Definition: GRPCServer.cpp:777
ripple::Application
Definition: Application.h:101
ripple::Processor
Definition: GRPCServer.h:42
std::string
STL class.
std::shared_ptr
STL class.
ripple::GRPCServer::impl_
GRPCServerImpl impl_
Definition: GRPCServer.h:319
ripple::GRPCServerImpl::CallData::clone
std::shared_ptr< Processor > clone() override
Definition: GRPCServer.cpp:89
ripple::GRPCServerImpl::CallData::operator=
CallData & operator=(const CallData &)=delete
ripple::GRPCServerImpl::CallData::app_
Application & app_
Definition: GRPCServer.h:172
ripple::GRPCServerImpl::apiVersion
static constexpr unsigned apiVersion
Definition: GRPCServer.h:112
ripple::GRPCServerImpl::secureGatewayIPs_
std::vector< boost::asio::ip::address > secureGatewayIPs_
Definition: GRPCServer.h:89
ripple::Processor::process
virtual void process()=0
ripple::GRPCServerImpl::start
bool start()
Definition: GRPCServer.cpp:753
ripple::GRPCServerImpl::CallData::secureGatewayIPs_
std::vector< boost::asio::ip::address > const & secureGatewayIPs_
Definition: GRPCServer.h:195
std::vector
STL class.
ripple::GRPCServerImpl::shutdown
void shutdown()
Definition: GRPCServer.cpp:492
ripple::GRPCServerImpl::CallData::request_
Request request_
Definition: GRPCServer.h:175
ripple::GRPCServerImpl::service_
org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService service_
Definition: GRPCServer.h:81
ripple::GRPCServerImpl::requests_
std::vector< std::shared_ptr< Processor > > requests_
Definition: GRPCServer.h:78
ripple::GRPCServerImpl::CallData::cq_
grpc::ServerCompletionQueue & cq_
Definition: GRPCServer.h:158
ripple::GRPCServer::running_
bool running_
Definition: GRPCServer.h:321
ripple::GRPCServerImpl::CallData::requiredCondition_
RPC::Condition requiredCondition_
Definition: GRPCServer.h:190
ripple::GRPCServerImpl::server_
std::unique_ptr< grpc::Server > server_
Definition: GRPCServer.h:83
std::function
ripple::GRPCServerImpl::handleRpcs
void handleRpcs()
Definition: GRPCServer.cpp:514
ripple::GRPCServerImpl::CallData::isFinished
virtual bool isFinished() override
Definition: GRPCServer.cpp:273
ripple::GRPCServerImpl
Definition: GRPCServer.h:71
ripple::GRPCServerImpl::CallData::finished_
std::atomic_bool finished_
Definition: GRPCServer.h:170
ripple::GRPCServerImpl::CallData::handler_
Handler< Request, Response > handler_
Definition: GRPCServer.h:184
ripple::Processor::isFinished
virtual bool isFinished()=0
ripple::GRPCServerImpl::CallData::CallData
CallData(org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService &service, grpc::ServerCompletionQueue &cq, Application &app, BindListener< Request, Response > bindListener, Handler< Request, Response > handler, Forward< Request, Response > forward, RPC::Condition requiredCondition, Resource::Charge loadType, std::vector< boost::asio::ip::address > const &secureGatewayIPs)
Definition: GRPCServer.cpp:60
ripple::GRPCServer::thread_
std::thread thread_
Definition: GRPCServer.h:320
ripple::GRPCServerImpl::CallData::service_
org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService & service_
Definition: GRPCServer.h:155
ripple::GRPCServerImpl::CallData::forward_
Forward< Request, Response > forward_
Definition: GRPCServer.h:187
ripple::GRPCServerImpl::cq_
std::unique_ptr< grpc::ServerCompletionQueue > cq_
Definition: GRPCServer.h:76
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:201
ripple::GRPCServerImpl::CallData::getUsage
Resource::Consumer getUsage()
Definition: GRPCServer.cpp:413
std::thread
STL class.
ripple::GRPCServer::operator=
GRPCServer & operator=(const GRPCServer &)=delete
ripple::RPC::GRPCContext
Definition: Context.h:70
ripple::Processor::operator=
Processor & operator=(const Processor &)=delete
std::enable_shared_from_this
ripple::GRPCServerImpl::operator=
GRPCServerImpl & operator=(const GRPCServerImpl &)=delete
ripple::GRPCServerImpl::GRPCServerImpl
GRPCServerImpl(Application &app)
Definition: GRPCServer.cpp:426
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::RPC::Condition
Condition
Definition: Handler.h:39
std::atomic_bool
ripple::GRPCServerImpl::CallData::getLoadType
Resource::Charge getLoadType()
Definition: GRPCServer.cpp:280
ripple::GRPCServerImpl::CallData::getProxiedClientEndpoint
std::optional< boost::asio::ip::tcp::endpoint > getProxiedClientEndpoint()
Definition: GRPCServer.cpp:352
ripple::GRPCServerImpl::CallData::wasForwarded
bool wasForwarded()
Definition: GRPCServer.cpp:299
ripple::GRPCServerImpl::CallData::setIsUnlimited
void setIsUnlimited(Response &response, bool isUnlimited)
Definition: GRPCServer.cpp:397
ripple::GRPCServerImpl::CallData::bindListener_
BindListener< Request, Response > bindListener_
Definition: GRPCServer.h:181
ripple::isUnlimited
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition: Role.cpp:94
ripple::GRPCServerImpl::CallData::loadType_
Resource::Charge loadType_
Definition: GRPCServer.h:193
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Processor::Processor
Processor()=default
ripple::GRPCServerImpl::setupListeners
std::vector< std::shared_ptr< Processor > > setupListeners()
Definition: GRPCServer.cpp:585
ripple::GRPCServerImpl::CallData::ctx_
grpc::ServerContext ctx_
Definition: GRPCServer.h:163
ripple::GRPCServer
Definition: GRPCServer.h:297
ripple::Resource::Consumer
An endpoint that consumes resources.
Definition: Consumer.h:33
ripple::Resource::Charge
A consumption charge.
Definition: Charge.h:30
ripple::GRPCServerImpl::CallData
Definition: GRPCServer.h:148
ripple::Processor::clone
virtual std::shared_ptr< Processor > clone()=0
ripple::GRPCServerImpl::CallData::getRole
Role getRole(bool isUnlimited)
Definition: GRPCServer.cpp:287
ripple::GRPCServerImpl::CallData::getProxiedClientIpAddress
std::optional< boost::asio::ip::address > getProxiedClientIpAddress()
Definition: GRPCServer.cpp:342
ripple::GRPCServerImpl::CallData::forwardToP2p
void forwardToP2p(RPC::GRPCContext< Request > &context)
Definition: GRPCServer.cpp:233
std::optional
ripple::GRPCServer::onStop
void onStop() override
Override called when the stop notification is issued.
Definition: GRPCServer.cpp:792
ripple::GRPCServerImpl::CallData::getClientEndpoint
std::optional< boost::asio::ip::tcp::endpoint > getClientEndpoint()
Definition: GRPCServer.cpp:371
ripple::GRPCServerImpl::app_
Application & app_
Definition: GRPCServer.h:85
ripple::GRPCServer::GRPCServer
GRPCServer(Application &app, Stoppable &parent)
Definition: GRPCServer.h:300
ripple::GRPCServerImpl::CallData::~CallData
virtual ~CallData()=default
ripple::Processor::~Processor
virtual ~Processor()=default
ripple::GRPCServerImpl::CallData::clientIsUnlimited
bool clientIsUnlimited()
Definition: GRPCServer.cpp:378
std::unique_ptr< grpc::ServerCompletionQueue >
ripple::GRPCServerImpl::journal_
beast::Journal journal_
Definition: GRPCServer.h:91
ripple::GRPCServer::~GRPCServer
~GRPCServer() override
Definition: GRPCServer.cpp:804
ripple::GRPCServerImpl::CallData::getUser
std::optional< std::string > getUser()
Definition: GRPCServer.cpp:316
ripple::Role
Role
Indicates the level of administrative permission to grant.
Definition: Role.h:40
ripple::GRPCServerImpl::CallData::process
virtual void process() override
Definition: GRPCServer.cpp:105
ripple::GRPCServerImpl::serverAddress_
std::string serverAddress_
Definition: GRPCServer.h:87
ripple::GRPCServerImpl::CallData::responder_
grpc::ServerAsyncResponseWriter< Response > responder_
Definition: GRPCServer.h:178
ripple::GRPCServerImpl::CallData::getClientIpAddress
std::optional< boost::asio::ip::address > getClientIpAddress()
Definition: GRPCServer.cpp:332