rippled
GRPCServer.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2020 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 #include <ripple/app/main/GRPCServer.h>
21 #include <ripple/app/reporting/P2pProxy.h>
22 #include <ripple/beast/core/CurrentThreadName.h>
23 #include <ripple/resource/Fees.h>
24 
25 #include <ripple/beast/net/IPAddressConversion.h>
26 #include <ripple/core/ConfigSections.h>
27 
28 namespace ripple {
29 
30 namespace {
31 
32 // helper function. converts string to endpoint. handles ipv4 and ipv6, with or
33 // without port, with or without prepended scheme
35 getEndpoint(std::string const& peer)
36 {
37  try
38  {
39  std::size_t first = peer.find_first_of(":");
40  std::size_t last = peer.find_last_of(":");
41  std::string peerClean(peer);
42  if (first != last)
43  {
44  peerClean = peer.substr(first + 1);
45  }
46 
49  if (endpoint)
50  return beast::IP::to_asio_endpoint(endpoint.value());
51  }
52  catch (std::exception const&)
53  {
54  }
55  return {};
56 }
57 
58 } // namespace
59 
60 template <class Request, class Response>
62  org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService& service,
63  grpc::ServerCompletionQueue& cq,
64  Application& app,
68  RPC::Condition requiredCondition,
69  Resource::Charge loadType,
70  std::vector<boost::asio::ip::address> const& secureGatewayIPs)
71  : service_(service)
72  , cq_(cq)
73  , finished_(false)
74  , app_(app)
75  , responder_(&ctx_)
76  , bindListener_(std::move(bindListener))
77  , handler_(std::move(handler))
78  , forward_(std::move(forward))
79  , requiredCondition_(std::move(requiredCondition))
80  , loadType_(std::move(loadType))
81  , secureGatewayIPs_(secureGatewayIPs)
82 {
83  // Bind a listener. When a request is received, "this" will be returned
84  // from CompletionQueue::Next
86 }
87 
88 template <class Request, class Response>
91 {
92  return std::make_shared<CallData<Request, Response>>(
93  service_,
94  cq_,
95  app_,
96  bindListener_,
97  handler_,
98  forward_,
99  requiredCondition_,
100  loadType_,
102 }
103 
104 template <class Request, class Response>
105 void
107 {
108  // sanity check
109  BOOST_ASSERT(!finished_);
110 
112  this->shared_from_this();
113 
114  // Need to set finished to true before processing the response,
115  // because as soon as the response is posted to the completion
116  // queue (via responder_.Finish(...) or responder_.FinishWithError(...)),
117  // the CallData object is returned as a tag in handleRpcs().
118  // handleRpcs() checks the finished variable, and if true, destroys
119  // the object. Setting finished to true before calling process
120  // ensures that finished is always true when this CallData object
121  // is returned as a tag in handleRpcs(), after sending the response
122  finished_ = true;
123  auto coro = app_.getJobQueue().postCoro(
124  JobType::jtRPC,
125  "gRPC-Client",
126  [thisShared](std::shared_ptr<JobQueue::Coro> coro) {
127  thisShared->process(coro);
128  });
129 
130  // If coro is null, then the JobQueue has already been shutdown
131  if (!coro)
132  {
133  grpc::Status status{
134  grpc::StatusCode::INTERNAL, "Job Queue is already stopped"};
135  responder_.FinishWithError(status, this);
136  }
137 }
138 
139 template <class Request, class Response>
140 void
143 {
144  try
145  {
146  auto usage = getUsage();
147  bool isUnlimited = clientIsUnlimited();
148  if (!isUnlimited && usage.disconnect(app_.journal("gRPCServer")))
149  {
150  grpc::Status status{
151  grpc::StatusCode::RESOURCE_EXHAUSTED,
152  "usage balance exceeds threshold"};
153  responder_.FinishWithError(status, this);
154  }
155  else
156  {
157  auto loadType = getLoadType();
158  usage.charge(loadType);
159  auto role = getRole(isUnlimited);
160 
161  {
162  std::stringstream toLog;
163  toLog << "role = " << (int)role;
164 
165  toLog << " address = ";
166  if (auto clientIp = getClientIpAddress())
167  toLog << clientIp.value();
168 
169  toLog << " user = ";
170  if (auto user = getUser())
171  toLog << user.value();
172  toLog << " isUnlimited = " << isUnlimited;
173 
174  JLOG(app_.journal("GRPCServer::Calldata").debug())
175  << toLog.str();
176  }
177 
179  {app_.journal("gRPCServer"),
180  app_,
181  loadType,
182  app_.getOPs(),
184  usage,
185  role,
186  coro,
188  apiVersion},
189  request_};
190  if (shouldForwardToP2p(context, requiredCondition_))
191  {
192  forwardToP2p(context);
193  return;
194  }
195 
196  // Make sure we can currently handle the rpc
197  error_code_i conditionMetRes =
198  RPC::conditionMet(requiredCondition_, context);
199 
200  if (conditionMetRes != rpcSUCCESS)
201  {
202  RPC::ErrorInfo errorInfo = RPC::get_error_info(conditionMetRes);
203  grpc::Status status{
204  grpc::StatusCode::FAILED_PRECONDITION,
205  errorInfo.message.c_str()};
206  responder_.FinishWithError(status, this);
207  }
208  else
209  {
210  try
211  {
213  handler_(context);
214  setIsUnlimited(result.first, isUnlimited);
215  responder_.Finish(result.first, result.second, this);
216  }
217  catch (ReportingShouldProxy&)
218  {
219  forwardToP2p(context);
220  return;
221  }
222  }
223  }
224  }
225  catch (std::exception const& ex)
226  {
227  grpc::Status status{grpc::StatusCode::INTERNAL, ex.what()};
228  responder_.FinishWithError(status, this);
229  }
230 }
231 
232 template <class Request, class Response>
233 void
235  RPC::GRPCContext<Request>& context)
236 {
237  if (auto descriptor =
238  Request::GetDescriptor()->FindFieldByName("client_ip"))
239  {
240  Request::GetReflection()->SetString(&request_, descriptor, ctx_.peer());
241  JLOG(app_.journal("gRPCServer").debug())
242  << "Set client_ip to " << ctx_.peer();
243  }
244  else
245  {
246  assert(false);
247  Throw<std::runtime_error>(
248  "Attempting to forward but no client_ip field in "
249  "protobuf message");
250  }
251  auto stub = getP2pForwardingStub(context);
252  if (stub)
253  {
254  grpc::ClientContext clientContext;
255  Response response;
256  auto status = forward_(stub.get(), &clientContext, request_, &response);
257  responder_.Finish(response, status, this);
258  JLOG(app_.journal("gRPCServer").debug()) << "Forwarded request to tx";
259  }
260  else
261  {
262  JLOG(app_.journal("gRPCServer").error())
263  << "Failed to forward request to tx";
264  grpc::Status status{
265  grpc::StatusCode::INTERNAL,
266  "Attempted to act as proxy but failed "
267  "to create forwarding stub"};
268  responder_.FinishWithError(status, this);
269  }
270 }
271 
272 template <class Request, class Response>
273 bool
275 {
276  return finished_;
277 }
278 
279 template <class Request, class Response>
282 {
283  return loadType_;
284 }
285 
286 template <class Request, class Response>
287 Role
289 {
290  if (isUnlimited)
291  return Role::IDENTIFIED;
292  else if (wasForwarded())
293  return Role::PROXY;
294  else
295  return Role::USER;
296 }
297 
298 template <class Request, class Response>
299 bool
301 {
302  if (auto descriptor =
303  Request::GetDescriptor()->FindFieldByName("client_ip"))
304  {
305  std::string clientIp =
306  Request::GetReflection()->GetString(request_, descriptor);
307  if (!clientIp.empty())
308  {
309  return true;
310  }
311  }
312  return false;
313 }
314 
315 template <class Request, class Response>
318 {
319  if (auto descriptor = Request::GetDescriptor()->FindFieldByName("user"))
320  {
321  std::string user =
322  Request::GetReflection()->GetString(request_, descriptor);
323  if (!user.empty())
324  {
325  return user;
326  }
327  }
328  return {};
329 }
330 
331 template <class Request, class Response>
334 {
335  auto endpoint = getClientEndpoint();
336  if (endpoint)
337  return endpoint->address();
338  return {};
339 }
340 
341 template <class Request, class Response>
344 {
345  auto endpoint = getProxiedClientEndpoint();
346  if (endpoint)
347  return endpoint->address();
348  return {};
349 }
350 
351 template <class Request, class Response>
354 {
355  auto descriptor = Request::GetDescriptor()->FindFieldByName("client_ip");
356  if (descriptor)
357  {
358  std::string clientIp =
359  Request::GetReflection()->GetString(request_, descriptor);
360  if (!clientIp.empty())
361  {
362  JLOG(app_.journal("gRPCServer").debug())
363  << "Got client_ip from request : " << clientIp;
364  return getEndpoint(clientIp);
365  }
366  }
367  return {};
368 }
369 
370 template <class Request, class Response>
373 {
374  return getEndpoint(ctx_.peer());
375 }
376 
377 template <class Request, class Response>
378 bool
380 {
381  if (!getUser())
382  return false;
383  auto clientIp = getClientIpAddress();
384  auto proxiedIp = getProxiedClientIpAddress();
385  if (clientIp && !proxiedIp)
386  {
387  for (auto& ip : secureGatewayIPs_)
388  {
389  if (ip == clientIp)
390  return true;
391  }
392  }
393  return false;
394 }
395 
396 template <class Request, class Response>
397 void
399  Response& response,
400  bool isUnlimited)
401 {
402  if (isUnlimited)
403  {
404  if (auto descriptor =
405  Response::GetDescriptor()->FindFieldByName("is_unlimited"))
406  {
407  Response::GetReflection()->SetBool(&response, descriptor, true);
408  }
409  }
410 }
411 
412 template <class Request, class Response>
415 {
416  auto endpoint = getClientEndpoint();
417  auto proxiedEndpoint = getProxiedClientEndpoint();
418  if (proxiedEndpoint)
420  beast::IP::from_asio(proxiedEndpoint.value()));
421  else if (endpoint)
423  beast::IP::from_asio(endpoint.value()));
424  Throw<std::runtime_error>("Failed to get client endpoint");
425 }
426 
428  : app_(app), journal_(app_.journal("gRPC Server"))
429 {
430  // if present, get endpoint from config
431  if (app_.config().exists(SECTION_PORT_GRPC))
432  {
433  Section const& section = app_.config().section(SECTION_PORT_GRPC);
434 
435  auto const optIp = section.get("ip");
436  if (!optIp)
437  return;
438 
439  auto const optPort = section.get("port");
440  if (!optPort)
441  return;
442  try
443  {
444  boost::asio::ip::tcp::endpoint endpoint(
445  boost::asio::ip::make_address(*optIp), std::stoi(*optPort));
446 
448  ss << endpoint;
449  serverAddress_ = ss.str();
450  }
451  catch (std::exception const&)
452  {
453  JLOG(journal_.error()) << "Error setting grpc server address";
454  Throw<std::runtime_error>("Error setting grpc server address");
455  }
456 
457  auto const optSecureGateway = section.get("secure_gateway");
458  if (optSecureGateway)
459  {
460  try
461  {
462  std::stringstream ss{*optSecureGateway};
463  std::string ip;
464  while (std::getline(ss, ip, ','))
465  {
466  boost::algorithm::trim(ip);
467  auto const addr = boost::asio::ip::make_address(ip);
468 
469  if (addr.is_unspecified())
470  {
471  JLOG(journal_.error())
472  << "Can't pass unspecified IP in "
473  << "secure_gateway section of port_grpc";
474  Throw<std::runtime_error>(
475  "Unspecified IP in secure_gateway section");
476  }
477 
479  }
480  }
481  catch (std::exception const&)
482  {
483  JLOG(journal_.error())
484  << "Error parsing secure gateway IPs for grpc server";
485  Throw<std::runtime_error>(
486  "Error parsing secure_gateway section");
487  }
488  }
489  }
490 }
491 
492 void
494 {
495  JLOG(journal_.debug()) << "Shutting down";
496 
497  // The below call cancels all "listeners" (CallData objects that are waiting
498  // for a request, as opposed to processing a request), and blocks until all
499  // requests being processed are completed. CallData objects in the midst of
500  // processing requests need to actually send data back to the client, via
501  // responder_.Finish(...) or responder_.FinishWithError(...), for this call
502  // to unblock. Each cancelled listener is returned via cq_.Next(...) with ok
503  // set to false
504  server_->Shutdown();
505  JLOG(journal_.debug()) << "Server has been shutdown";
506 
507  // Always shutdown the completion queue after the server. This call allows
508  // cq_.Next() to return false, once all events posted to the completion
509  // queue have been processed. See handleRpcs() for more details.
510  cq_->Shutdown();
511  JLOG(journal_.debug()) << "Completion Queue has been shutdown";
512 }
513 
514 void
516 {
517  // This collection should really be an unordered_set. However, to delete
518  // from the unordered_set, we need a shared_ptr, but cq_.Next() (see below
519  // while loop) sets the tag to a raw pointer.
521 
522  auto erase = [&requests](Processor* ptr) {
523  auto it = std::find_if(
524  requests.begin(),
525  requests.end(),
526  [ptr](std::shared_ptr<Processor>& sPtr) {
527  return sPtr.get() == ptr;
528  });
529  BOOST_ASSERT(it != requests.end());
530  it->swap(requests.back());
531  requests.pop_back();
532  };
533 
534  void* tag; // uniquely identifies a request.
535  bool ok;
536  // Block waiting to read the next event from the completion queue. The
537  // event is uniquely identified by its tag, which in this case is the
538  // memory address of a CallData instance.
539  // The return value of Next should always be checked. This return value
540  // tells us whether there is any kind of event or cq_ is shutting down.
541  // When cq_.Next(...) returns false, all work has been completed and the
542  // loop can exit. When the server is shutdown, each CallData object that is
543  // listening for a request is forceably cancelled, and is returned by
544  // cq_->Next() with ok set to false. Then, each CallData object processing
545  // a request must complete (by sending data to the client), each of which
546  // will be returned from cq_->Next() with ok set to true. After all
547  // cancelled listeners and all CallData objects processing requests are
548  // returned via cq_->Next(), cq_->Next() will return false, causing the
549  // loop to exit.
550  while (cq_->Next(&tag, &ok))
551  {
552  auto ptr = static_cast<Processor*>(tag);
553  JLOG(journal_.trace()) << "Processing CallData object."
554  << " ptr = " << ptr << " ok = " << ok;
555 
556  if (!ok)
557  {
558  JLOG(journal_.debug()) << "Request listener cancelled. "
559  << "Destroying object";
560  erase(ptr);
561  }
562  else
563  {
564  if (!ptr->isFinished())
565  {
566  JLOG(journal_.debug()) << "Received new request. Processing";
567  // ptr is now processing a request, so create a new CallData
568  // object to handle additional requests
569  auto cloned = ptr->clone();
570  requests.push_back(cloned);
571  // process the request
572  ptr->process();
573  }
574  else
575  {
576  JLOG(journal_.debug()) << "Sent response. Destroying object";
577  erase(ptr);
578  }
579  }
580  }
581  JLOG(journal_.debug()) << "Completion Queue drained";
582 }
583 
584 // create a CallData instance for each RPC
587 {
589 
590  auto addToRequests = [&requests](auto callData) {
591  requests.push_back(std::move(callData));
592  };
593 
594  {
595  using cd = CallData<
596  org::xrpl::rpc::v1::GetLedgerRequest,
597  org::xrpl::rpc::v1::GetLedgerResponse>;
598 
599  addToRequests(std::make_shared<cd>(
600  service_,
601  *cq_,
602  app_,
603  &org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService::
604  RequestGetLedger,
605  doLedgerGrpc,
606  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedger,
610  }
611  {
612  using cd = CallData<
613  org::xrpl::rpc::v1::GetLedgerDataRequest,
614  org::xrpl::rpc::v1::GetLedgerDataResponse>;
615 
616  addToRequests(std::make_shared<cd>(
617  service_,
618  *cq_,
619  app_,
620  &org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService::
621  RequestGetLedgerData,
623  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerData,
627  }
628  {
629  using cd = CallData<
630  org::xrpl::rpc::v1::GetLedgerDiffRequest,
631  org::xrpl::rpc::v1::GetLedgerDiffResponse>;
632 
633  addToRequests(std::make_shared<cd>(
634  service_,
635  *cq_,
636  app_,
637  &org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService::
638  RequestGetLedgerDiff,
640  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerDiff,
644  }
645  {
646  using cd = CallData<
647  org::xrpl::rpc::v1::GetLedgerEntryRequest,
648  org::xrpl::rpc::v1::GetLedgerEntryResponse>;
649 
650  addToRequests(std::make_shared<cd>(
651  service_,
652  *cq_,
653  app_,
654  &org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService::
655  RequestGetLedgerEntry,
657  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerEntry,
661  }
662  return requests;
663 }
664 
665 bool
667 {
668  // if config does not specify a grpc server address, don't start
669  if (serverAddress_.empty())
670  return false;
671 
672  JLOG(journal_.info()) << "Starting gRPC server at " << serverAddress_;
673 
674  grpc::ServerBuilder builder;
675  // Listen on the given address without any authentication mechanism.
676  builder.AddListeningPort(serverAddress_, grpc::InsecureServerCredentials());
677  // Register "service_" as the instance through which we'll communicate with
678  // clients. In this case it corresponds to an *asynchronous* service.
679  builder.RegisterService(&service_);
680  // Get hold of the completion queue used for the asynchronous communication
681  // with the gRPC runtime.
682  cq_ = builder.AddCompletionQueue();
683  // Finally assemble the server.
684  server_ = builder.BuildAndStart();
685 
686  return true;
687 }
688 
689 void
691 {
692  // Start the server and setup listeners
693  if (running_ = impl_.start(); running_)
694  {
695  thread_ = std::thread([this]() {
696  beast::setCurrentThreadName("rippled : GRPCServer");
697  // Start the event loop and begin handling requests
698  beast::setCurrentThreadName("rippled: grpc");
699  this->impl_.handleRpcs();
700  });
701  }
702 }
703 
704 void
706 {
707  if (running_)
708  {
709  impl_.shutdown();
710  thread_.join();
711  running_ = false;
712  }
713 }
714 
716 {
717  assert(!running_);
718 }
719 
720 } // namespace ripple
ripple::Resource::Manager::newInboundEndpoint
virtual Consumer newInboundEndpoint(beast::IP::Endpoint const &address)=0
Create a new endpoint keyed by inbound IP address or the forwarded IP if proxied.
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:42
ripple::Application
Definition: Application.h:116
ripple::Processor
Definition: GRPCServer.h:41
std::string
STL class.
std::shared_ptr
STL class.
ripple::JobQueue::postCoro
std::shared_ptr< Coro > postCoro(JobType t, std::string const &name, F &&f)
Creates a coroutine and adds a job to the queue which will run it.
Definition: JobQueue.h:411
ripple::GRPCServer::impl_
GRPCServerImpl impl_
Definition: GRPCServer.h:317
std::exception
STL class.
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:308
ripple::GRPCServerImpl::CallData::clone
std::shared_ptr< Processor > clone() override
Definition: GRPCServer.cpp:90
ripple::RPC::get_error_info
ErrorInfo const & get_error_info(error_code_i code)
Returns an ErrorInfo that reflects the error code.
Definition: ErrorCodes.cpp:172
ripple::Resource::feeMediumBurdenRPC
const Charge feeMediumBurdenRPC
std::pair
ripple::GRPCServerImpl::apiVersion
static constexpr unsigned apiVersion
Definition: GRPCServer.h:111
ripple::GRPCServerImpl::secureGatewayIPs_
std::vector< boost::asio::ip::address > secureGatewayIPs_
Definition: GRPCServer.h:88
ripple::GRPCServerImpl::start
bool start()
Definition: GRPCServer.cpp:666
std::vector< boost::asio::ip::address >
std::find_if
T find_if(T... args)
ripple::GRPCServerImpl::shutdown
void shutdown()
Definition: GRPCServer.cpp:493
ripple::GRPCServerImpl::CallData::request_
Request request_
Definition: GRPCServer.h:174
ripple::GRPCServerImpl::service_
org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService service_
Definition: GRPCServer.h:80
ripple::GRPCServerImpl::CallData::cq_
grpc::ServerCompletionQueue & cq_
Definition: GRPCServer.h:157
ripple::GRPCServer::running_
bool running_
Definition: GRPCServer.h:319
ripple::doLedgerGrpc
std::pair< org::xrpl::rpc::v1::GetLedgerResponse, grpc::Status > doLedgerGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerRequest > &context)
Definition: LedgerHandler.cpp:104
std::stringstream
STL class.
ripple::GRPCServerImpl::server_
std::unique_ptr< grpc::Server > server_
Definition: GRPCServer.h:82
ripple::Role::IDENTIFIED
@ IDENTIFIED
ripple::doLedgerDiffGrpc
std::pair< org::xrpl::rpc::v1::GetLedgerDiffResponse, grpc::Status > doLedgerDiffGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerDiffRequest > &context)
Definition: LedgerDiff.cpp:6
std::vector::back
T back(T... args)
std::function
ripple::GRPCServerImpl::handleRpcs
void handleRpcs()
Definition: GRPCServer.cpp:515
Json::StaticString::c_str
constexpr const char * c_str() const
Definition: json_value.h:73
ripple::GRPCServerImpl::CallData::isFinished
virtual bool isFinished() override
Definition: GRPCServer.cpp:274
ripple::Application::getOPs
virtual NetworkOPs & getOPs()=0
ripple::error_code_i
error_code_i
Definition: ErrorCodes.h:40
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:61
std::vector::push_back
T push_back(T... args)
ripple::RPC::ErrorInfo::message
Json::StaticString message
Definition: ErrorCodes.h:202
ripple::erase
void erase(STObject &st, TypedField< U > const &f)
Remove a field in an STObject.
Definition: STExchange.h:171
ripple::GRPCServer::thread_
std::thread thread_
Definition: GRPCServer.h:318
ripple::GRPCServerImpl::CallData::service_
org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService & service_
Definition: GRPCServer.h:154
beast::IP::to_asio_endpoint
boost::asio::ip::tcp::endpoint to_asio_endpoint(Endpoint const &endpoint)
Convert to asio::ip::tcp::endpoint.
Definition: IPAddressConversion.cpp:44
std::stoi
T stoi(T... args)
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
ripple::GRPCServerImpl::cq_
std::unique_ptr< grpc::ServerCompletionQueue > cq_
Definition: GRPCServer.h:75
ripple::GRPCServerImpl::CallData::getUsage
Resource::Consumer getUsage()
Definition: GRPCServer.cpp:414
std::thread
STL class.
ripple::InfoSub::pointer
std::shared_ptr< InfoSub > pointer
Definition: InfoSub.h:54
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::Role::USER
@ USER
ripple::doLedgerEntryGrpc
std::pair< org::xrpl::rpc::v1::GetLedgerEntryResponse, grpc::Status > doLedgerEntryGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerEntryRequest > &context)
Definition: LedgerEntry.cpp:674
ripple::Application::config
virtual Config & config()=0
ripple::RPC::GRPCContext
Definition: Context.h:70
ripple::getP2pForwardingStub
std::unique_ptr< org::xrpl::rpc::v1::XRPLedgerAPIService::Stub > getP2pForwardingStub(RPC::Context &context)
Get stub used to forward gRPC requests to a p2p node.
Definition: P2pProxy.cpp:35
std::string::find_last_of
T find_last_of(T... args)
ripple::Application::getJobQueue
virtual JobQueue & getJobQueue()=0
ripple::RPC::NO_CONDITION
@ NO_CONDITION
Definition: Handler.h:41
ripple::Role::PROXY
@ PROXY
beast::Journal::error
Stream error() const
Definition: Journal.h:332
beast::Journal::info
Stream info() const
Definition: Journal.h:320
ripple::GRPCServerImpl::GRPCServerImpl
GRPCServerImpl(Application &app)
Definition: GRPCServer.cpp:427
beast::IP::from_asio
Endpoint from_asio(boost::asio::ip::address const &address)
Convert to Endpoint.
Definition: IPAddressConversion.cpp:26
ripple::RPC::Condition
Condition
Definition: Handler.h:40
ripple::RPC::ErrorInfo
Maps an rpc error code to its token, default message, and HTTP status.
Definition: ErrorCodes.h:169
ripple::GRPCServerImpl::CallData::getLoadType
Resource::Charge getLoadType()
Definition: GRPCServer.cpp:281
std::vector::pop_back
T pop_back(T... args)
ripple::doLedgerDataGrpc
std::pair< org::xrpl::rpc::v1::GetLedgerDataResponse, grpc::Status > doLedgerDataGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerDataRequest > &context)
Definition: LedgerData.cpp:135
ripple::GRPCServerImpl::CallData::getProxiedClientEndpoint
std::optional< boost::asio::ip::tcp::endpoint > getProxiedClientEndpoint()
Definition: GRPCServer.cpp:353
ripple::GRPCServerImpl::CallData::wasForwarded
bool wasForwarded()
Definition: GRPCServer.cpp:300
ripple::GRPCServerImpl::CallData::setIsUnlimited
void setIsUnlimited(Response &response, bool isUnlimited)
Definition: GRPCServer.cpp:398
ripple::GRPCServerImpl::CallData::bindListener_
BindListener< Request, Response > bindListener_
Definition: GRPCServer.h:180
ripple::GRPCServer::start
void start()
Definition: GRPCServer.cpp:690
ripple::forwardToP2p
Json::Value forwardToP2p(RPC::JsonContext &context)
Forward a JSON request to a p2p node and return the response.
Definition: P2pProxy.cpp:28
ripple::isUnlimited
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition: Role.cpp:124
ripple::Application::getResourceManager
virtual Resource::Manager & getResourceManager()=0
std::string::substr
T substr(T... args)
std::optional::value
T value(T... args)
ripple::GRPCServer::~GRPCServer
~GRPCServer()
Definition: GRPCServer.cpp:715
beast::setCurrentThreadName
void setCurrentThreadName(std::string_view name)
Changes the name of the caller thread.
Definition: CurrentThreadName.cpp:119
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::GRPCServerImpl::setupListeners
std::vector< std::shared_ptr< Processor > > setupListeners()
Definition: GRPCServer.cpp:586
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::GRPCServerImpl::CallData::ctx_
grpc::ServerContext ctx_
Definition: GRPCServer.h:162
ripple::ReportingShouldProxy
Definition: LedgerMaster.h:56
ripple::shouldForwardToP2p
bool shouldForwardToP2p(RPC::JsonContext &context)
Whether a request should be forwarded, based on request parameters.
Definition: P2pProxy.cpp:45
ripple::RPC::conditionMet
error_code_i conditionMet(Condition condition_required, T &context)
Definition: Handler.h:82
std::vector::begin
T begin(T... args)
std::getline
T getline(T... args)
std
STL namespace.
ripple::Resource::Consumer
An endpoint that consumes resources.
Definition: Consumer.h:34
ripple::Resource::Charge
A consumption charge.
Definition: Charge.h:30
ripple::GRPCServerImpl::CallData
Definition: GRPCServer.h:147
ripple::GRPCServer::stop
void stop()
Definition: GRPCServer.cpp:705
ripple::Section::get
std::optional< T > get(std::string const &name) const
Definition: BasicConfig.h:138
std::string::empty
T empty(T... args)
ripple::GRPCServerImpl::CallData::getRole
Role getRole(bool isUnlimited)
Definition: GRPCServer.cpp:288
std::string::find_first_of
T find_first_of(T... args)
ripple::GRPCServerImpl::CallData::getProxiedClientIpAddress
std::optional< boost::asio::ip::address > getProxiedClientIpAddress()
Definition: GRPCServer.cpp:343
ripple::GRPCServerImpl::CallData::forwardToP2p
void forwardToP2p(RPC::GRPCContext< Request > &context)
Definition: GRPCServer.cpp:234
std::optional
std::stringstream::str
T str(T... args)
beast::Journal::debug
Stream debug() const
Definition: Journal.h:314
ripple::GRPCServerImpl::CallData::getClientEndpoint
std::optional< boost::asio::ip::tcp::endpoint > getClientEndpoint()
Definition: GRPCServer.cpp:372
std::size_t
ripple::GRPCServerImpl::app_
Application & app_
Definition: GRPCServer.h:84
std::vector::end
T end(T... args)
ripple::GRPCServerImpl::CallData::clientIsUnlimited
bool clientIsUnlimited()
Definition: GRPCServer.cpp:379
ripple::GRPCServerImpl::journal_
beast::Journal journal_
Definition: GRPCServer.h:90
beast::IP::Endpoint::from_string_checked
static std::optional< Endpoint > from_string_checked(std::string const &s)
Create an Endpoint from a string.
Definition: IPEndpoint.cpp:35
ripple::GRPCServerImpl::CallData::getUser
std::optional< std::string > getUser()
Definition: GRPCServer.cpp:317
ripple::Role
Role
Indicates the level of administrative permission to grant.
Definition: Role.h:43
ripple::GRPCServerImpl::CallData::process
virtual void process() override
Definition: GRPCServer.cpp:106
ripple::GRPCServerImpl::serverAddress_
std::string serverAddress_
Definition: GRPCServer.h:86
std::thread::join
T join(T... args)
std::exception::what
T what(T... args)
ripple::BasicConfig::exists
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
Definition: BasicConfig.cpp:121
ripple::GRPCServerImpl::CallData::responder_
grpc::ServerAsyncResponseWriter< Response > responder_
Definition: GRPCServer.h:177
ripple::BasicConfig::section
Section & section(std::string const &name)
Returns the section with the given name.
Definition: BasicConfig.cpp:127
ripple::GRPCServerImpl::CallData::getClientIpAddress
std::optional< boost::asio::ip::address > getClientIpAddress()
Definition: GRPCServer.cpp:333