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