diff --git a/AMMTest_8cpp_source.html b/AMMTest_8cpp_source.html index a6ae19839c..bb2c7741ee 100644 --- a/AMMTest_8cpp_source.html +++ b/AMMTest_8cpp_source.html @@ -377,7 +377,7 @@ $(function() {
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
ripple::test::jtx::AMM
Convenience class to test AMM functionality.
Definition: AMM.h:62
std::function
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::STParsedJSONObject::object
std::optional< STObject > object
The STObject if the parse was successful.
Definition: STParsedJSON.h:50
ripple::STPathSet
Definition: STPathSet.h:176
ripple::test::jtx::Env::trust
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:259
diff --git a/AMM__test_8cpp_source.html b/AMM__test_8cpp_source.html index 4fc29fc9fe..754f9ef696 100644 --- a/AMM__test_8cpp_source.html +++ b/AMM__test_8cpp_source.html @@ -4941,7 +4941,7 @@ $(function() {
ripple::IOUAmount
Floating point representation of amounts with high dynamic range.
Definition: IOUAmount.h:43
ripple::terNO_RIPPLE
@ terNO_RIPPLE
Definition: TER.h:217
ripple::test::jtx::AMM
Convenience class to test AMM functionality.
Definition: AMM.h:62
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::tecINCOMPLETE
@ tecINCOMPLETE
Definition: TER.h:315
ripple::test::jtx::Env::trust
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:259
ripple::tecAMM_FAILED
@ tecAMM_FAILED
Definition: TER.h:310
diff --git a/AccountObjects__test_8cpp_source.html b/AccountObjects__test_8cpp_source.html index 9d2ae2eda9..d6edfd57f5 100644 --- a/AccountObjects__test_8cpp_source.html +++ b/AccountObjects__test_8cpp_source.html @@ -1136,14 +1136,14 @@ $(function() {
std::size
T size(T... args)
ripple::SField::fieldName
const std::string fieldName
Definition: SField.h:159
ripple::test::jtx::XChainBridgeObjects::jvb
Json::Value jvb
Definition: xchain_bridge.h:184
-
ripple::test::jtx::port_increment
std::unique_ptr< Config > port_increment(std::unique_ptr< Config >, int)
adjust the default configured server ports by a specified value
Definition: envconfig.cpp:128
+
ripple::test::jtx::port_increment
std::unique_ptr< Config > port_increment(std::unique_ptr< Config >, int)
adjust the default configured server ports by a specified value
Definition: envconfig.cpp:127
ripple::test::jtx::Account::human
std::string const & human() const
Returns the human readable public key.
Definition: Account.h:113
ripple::sfTicketSequence
const SF_UINT32 sfTicketSequence
ripple::tfPassive
constexpr std::uint32_t tfPassive
Definition: TxFlags.h:94
ripple::test::jtx::AMM
Convenience class to test AMM functionality.
Definition: AMM.h:62
ripple::test::jtx::XChainBridgeObjects::mcCarol
const Account mcCarol
Definition: xchain_bridge.h:158
Json::Reader
Unserialize a JSON document into a Value.
Definition: json_reader.h:36
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::SField::getJsonName
Json::StaticString const & getJsonName() const
Definition: SField.h:214
ripple::test::jtx::create_account_attestation
Json::Value create_account_attestation(jtx::Account const &submittingAccount, Json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, jtx::AnyAmount const &rewardAmount, jtx::Account const &rewardAccount, bool wasLockingChainSend, std::uint64_t createCount, jtx::Account const &dst, jtx::signer const &signer)
Definition: xchain_bridge.cpp:251
ripple::sfXChainAccountClaimCount
const SF_UINT64 sfXChainAccountClaimCount
diff --git a/AccountOffers__test_8cpp_source.html b/AccountOffers__test_8cpp_source.html index e618fbe8c8..c8b70d0618 100644 --- a/AccountOffers__test_8cpp_source.html +++ b/AccountOffers__test_8cpp_source.html @@ -410,10 +410,10 @@ $(function() {
ripple::SField::fieldName
const std::string fieldName
Definition: SField.h:159
ripple::test::jtx::Account::human
std::string const & human() const
Returns the human readable public key.
Definition: Account.h:113
Json::Value::toStyledString
std::string toStyledString() const
Definition: json_value.cpp:1039
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::test::jtx::Env::trust
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Definition: Env.cpp:259
ripple::sfExpiration
const SF_UINT32 sfExpiration
-
ripple::test::jtx::no_admin
std::unique_ptr< Config > no_admin(std::unique_ptr< Config >)
adjust config so no admin ports are enabled
Definition: envconfig.cpp:82
+
ripple::test::jtx::no_admin
std::unique_ptr< Config > no_admin(std::unique_ptr< Config >)
adjust config so no admin ports are enabled
Definition: envconfig.cpp:81
ripple::test::AccountOffers_test
Definition: AccountOffers_test.cpp:26
ripple::test::AccountOffers_test::testSequential
void testSequential(bool asAdmin)
Definition: AccountOffers_test.cpp:82
ripple::test::AccountOffers_test::checkMarker
static bool checkMarker(Json::Value const &val)
Definition: AccountOffers_test.cpp:31
diff --git a/AmendmentTable__test_8cpp_source.html b/AmendmentTable__test_8cpp_source.html index 56847bd99a..ce9874cb46 100644 --- a/AmendmentTable__test_8cpp_source.html +++ b/AmendmentTable__test_8cpp_source.html @@ -1394,7 +1394,7 @@ $(function() {
ripple::AmendmentTable_test::testNoOnUnknown
void testNoOnUnknown(FeatureBitset const &feat)
Definition: AmendmentTable_test.cpp:611
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
ripple::AmendmentTable_test::testHasUnsupported
void testHasUnsupported()
Definition: AmendmentTable_test.cpp:1216
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
std::vector::front
T front(T... args)
ripple::base_uint::data
pointer data()
Definition: base_uint.h:122
ripple::STValidation
Definition: STValidation.h:44
diff --git a/Application_8cpp_source.html b/Application_8cpp_source.html index 71c6d6ef64..c58c4e9747 100644 --- a/Application_8cpp_source.html +++ b/Application_8cpp_source.html @@ -2575,7 +2575,7 @@ $(function() {
ripple::ApplicationImp::getShardArchiveHandler
RPC::ShardArchiveHandler * getShardArchiveHandler(bool tryRecovery) override
Definition: Application.cpp:700
ripple::ApplicationImp::m_inboundLedgers
std::unique_ptr< InboundLedgers > m_inboundLedgers
Definition: Application.cpp:203
ripple::ApplicationImp::peerReservations_
std::unique_ptr< PeerReservationTable > peerReservations_
Definition: Application.cpp:209
-
ripple::setup_ServerHandler
ServerHandler::Setup setup_ServerHandler(Config const &config, std::ostream &&log)
Definition: ServerHandler.cpp:1236
+
ripple::setup_ServerHandler
ServerHandler::Setup setup_ServerHandler(Config const &config, std::ostream &&log)
Definition: ServerHandler.cpp:1241
ripple::ApplicationImp::loadLedgerFromFile
std::shared_ptr< Ledger > loadLedgerFromFile(std::string const &ledgerID)
Definition: Application.cpp:1931
ripple::ApplicationImp::checkSigs
bool checkSigs() const override
Definition: Application.cpp:1819
ripple::ApplicationImp::journal
beast::Journal journal(std::string const &name) override
Definition: Application.cpp:2300
@@ -2594,7 +2594,7 @@ $(function() {
ripple::ApplicationImp::m_jobQueue
std::unique_ptr< JobQueue > m_jobQueue
Definition: Application.cpp:180
ripple::ApplicationImp::checkSigs_
std::atomic< bool > checkSigs_
Definition: Application.cpp:237
std::reference_wrapper
-
ripple::make_ServerHandler
std::unique_ptr< ServerHandler > make_ServerHandler(Application &app, boost::asio::io_service &io_service, JobQueue &jobQueue, NetworkOPs &networkOPs, Resource::Manager &resourceManager, CollectorManager &cm)
Definition: ServerHandler.cpp:1248
+
ripple::make_ServerHandler
std::unique_ptr< ServerHandler > make_ServerHandler(Application &app, boost::asio::io_service &io_service, JobQueue &jobQueue, NetworkOPs &networkOPs, Resource::Manager &resourceManager, CollectorManager &cm)
Definition: ServerHandler.cpp:1253
ripple::rand_int
std::enable_if_t< std::is_integral< Integral >::value &&detail::is_engine< Engine >::value, Integral > rand_int(Engine &engine, Integral min, Integral max)
Return a uniformly distributed random integer.
Definition: ripple/basics/random.h:115
ripple::loadByHash
std::shared_ptr< Ledger > loadByHash(uint256 const &ledgerHash, Application &app, bool acquire)
Definition: Ledger.cpp:1136
ripple::InboundLedgers::cacheSize
virtual std::size_t cacheSize()=0
diff --git a/Book__test_8cpp_source.html b/Book__test_8cpp_source.html index 43e6bc9f14..b810d5a2f6 100644 --- a/Book__test_8cpp_source.html +++ b/Book__test_8cpp_source.html @@ -1833,7 +1833,7 @@ $(function() {
ripple::QualityDirection::in
@ in
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
ripple::getQualityNext
uint256 getQualityNext(uint256 const &uBase)
Definition: Indexes.cpp:109
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::RPC::Tuning::bookOffers
static constexpr LimitRange bookOffers
Limits for the book_offers command.
Definition: rpc/impl/Tuning.h:49
ripple::test::Book_test::testCrossingSingleBookOffer
void testCrossingSingleBookOffer()
Definition: Book_test.cpp:1159
ripple::test::Book_test::testOneSideOffersInBook
void testOneSideOffersInBook()
Definition: Book_test.cpp:131
@@ -1841,7 +1841,7 @@ $(function() {
ripple::test::BEAST_DEFINE_TESTSUITE_PRIO
BEAST_DEFINE_TESTSUITE_PRIO(AccountDelete, app, ripple, 2)
ripple::base_uint< 256 >
ripple::test::Book_test::testBookOfferErrors
void testBookOfferErrors()
Definition: Book_test.cpp:1310
-
ripple::test::jtx::no_admin
std::unique_ptr< Config > no_admin(std::unique_ptr< Config >)
adjust config so no admin ports are enabled
Definition: envconfig.cpp:82
+
ripple::test::jtx::no_admin
std::unique_ptr< Config > no_admin(std::unique_ptr< Config >)
adjust config so no admin ports are enabled
Definition: envconfig.cpp:81
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::QualityDirection::out
@ out
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
diff --git a/ClosureCounter__test_8cpp_source.html b/ClosureCounter__test_8cpp_source.html index 6c03957049..55c348aeb7 100644 --- a/ClosureCounter__test_8cpp_source.html +++ b/ClosureCounter__test_8cpp_source.html @@ -425,7 +425,7 @@ $(function() {
ripple::test::ClosureCounter_test::TrackedString::TrackedString
TrackedString()=delete
ripple::test::ClosureCounter_test::testArgs
void testArgs()
Definition: ClosureCounter_test.cpp:164
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::test::ClosureCounter_test::TrackedString::TrackedString
TrackedString(TrackedString const &rhs)
Definition: ClosureCounter_test.cpp:131
ripple::test::ClosureCounter_test::TrackedString::operator+
friend TrackedString operator+(TrackedString const &s, char const *rhs)
Definition: ClosureCounter_test.cpp:155
thread
diff --git a/ConfigSections_8h_source.html b/ConfigSections_8h_source.html index 78361378ee..abba3acdd5 100644 --- a/ConfigSections_8h_source.html +++ b/ConfigSections_8h_source.html @@ -120,61 +120,62 @@ $(function() {
49 // VFALCO TODO Rename and replace these macros with variables.
50 #define SECTION_AMENDMENTS "amendments"
51 #define SECTION_AMENDMENT_MAJORITY_TIME "amendment_majority_time"
-
52 #define SECTION_CLUSTER_NODES "cluster_nodes"
-
53 #define SECTION_COMPRESSION "compression"
-
54 #define SECTION_DEBUG_LOGFILE "debug_logfile"
-
55 #define SECTION_ELB_SUPPORT "elb_support"
-
56 #define SECTION_FEE_DEFAULT "fee_default"
-
57 #define SECTION_FETCH_DEPTH "fetch_depth"
-
58 #define SECTION_HISTORICAL_SHARD_PATHS "historical_shard_paths"
-
59 #define SECTION_INSIGHT "insight"
-
60 #define SECTION_IPS "ips"
-
61 #define SECTION_IPS_FIXED "ips_fixed"
-
62 #define SECTION_LEDGER_HISTORY "ledger_history"
-
63 #define SECTION_MAX_TRANSACTIONS "max_transactions"
-
64 #define SECTION_NETWORK_QUORUM "network_quorum"
-
65 #define SECTION_NODE_SEED "node_seed"
-
66 #define SECTION_NODE_SIZE "node_size"
-
67 #define SECTION_OVERLAY "overlay"
-
68 #define SECTION_PATH_SEARCH_OLD "path_search_old"
-
69 #define SECTION_PATH_SEARCH "path_search"
-
70 #define SECTION_PATH_SEARCH_FAST "path_search_fast"
-
71 #define SECTION_PATH_SEARCH_MAX "path_search_max"
-
72 #define SECTION_PEER_PRIVATE "peer_private"
-
73 #define SECTION_PEERS_MAX "peers_max"
-
74 #define SECTION_PEERS_IN_MAX "peers_in_max"
-
75 #define SECTION_PEERS_OUT_MAX "peers_out_max"
-
76 #define SECTION_REDUCE_RELAY "reduce_relay"
-
77 #define SECTION_RELATIONAL_DB "relational_db"
-
78 #define SECTION_RELAY_PROPOSALS "relay_proposals"
-
79 #define SECTION_RELAY_VALIDATIONS "relay_validations"
-
80 #define SECTION_RPC_STARTUP "rpc_startup"
-
81 #define SECTION_SIGNING_SUPPORT "signing_support"
-
82 #define SECTION_SNTP "sntp_servers"
-
83 #define SECTION_SSL_VERIFY "ssl_verify"
-
84 #define SECTION_SSL_VERIFY_FILE "ssl_verify_file"
-
85 #define SECTION_SSL_VERIFY_DIR "ssl_verify_dir"
-
86 #define SECTION_SERVER_DOMAIN "server_domain"
-
87 #define SECTION_VALIDATORS_FILE "validators_file"
-
88 #define SECTION_VALIDATION_SEED "validation_seed"
-
89 #define SECTION_VALIDATOR_KEYS "validator_keys"
-
90 #define SECTION_VALIDATOR_KEY_REVOCATION "validator_key_revocation"
-
91 #define SECTION_VALIDATOR_LIST_KEYS "validator_list_keys"
-
92 #define SECTION_VALIDATOR_LIST_SITES "validator_list_sites"
-
93 #define SECTION_VALIDATORS "validators"
-
94 #define SECTION_VALIDATOR_TOKEN "validator_token"
-
95 #define SECTION_VETO_AMENDMENTS "veto_amendments"
-
96 #define SECTION_WORKERS "workers"
-
97 #define SECTION_IO_WORKERS "io_workers"
-
98 #define SECTION_PREFETCH_WORKERS "prefetch_workers"
-
99 #define SECTION_LEDGER_REPLAY "ledger_replay"
-
100 #define SECTION_BETA_RPC_API "beta_rpc_api"
-
101 #define SECTION_SWEEP_INTERVAL "sweep_interval"
-
102 #define SECTION_NETWORK_ID "network_id"
-
103 
-
104 } // namespace ripple
-
105 
-
106 #endif
+
52 #define SECTION_BETA_RPC_API "beta_rpc_api"
+
53 #define SECTION_CLUSTER_NODES "cluster_nodes"
+
54 #define SECTION_COMPRESSION "compression"
+
55 #define SECTION_DEBUG_LOGFILE "debug_logfile"
+
56 #define SECTION_ELB_SUPPORT "elb_support"
+
57 #define SECTION_FEE_DEFAULT "fee_default"
+
58 #define SECTION_FETCH_DEPTH "fetch_depth"
+
59 #define SECTION_HISTORICAL_SHARD_PATHS "historical_shard_paths"
+
60 #define SECTION_INSIGHT "insight"
+
61 #define SECTION_IO_WORKERS "io_workers"
+
62 #define SECTION_IPS "ips"
+
63 #define SECTION_IPS_FIXED "ips_fixed"
+
64 #define SECTION_LEDGER_HISTORY "ledger_history"
+
65 #define SECTION_LEDGER_REPLAY "ledger_replay"
+
66 #define SECTION_MAX_TRANSACTIONS "max_transactions"
+
67 #define SECTION_NETWORK_ID "network_id"
+
68 #define SECTION_NETWORK_QUORUM "network_quorum"
+
69 #define SECTION_NODE_SEED "node_seed"
+
70 #define SECTION_NODE_SIZE "node_size"
+
71 #define SECTION_OVERLAY "overlay"
+
72 #define SECTION_PATH_SEARCH_OLD "path_search_old"
+
73 #define SECTION_PATH_SEARCH "path_search"
+
74 #define SECTION_PATH_SEARCH_FAST "path_search_fast"
+
75 #define SECTION_PATH_SEARCH_MAX "path_search_max"
+
76 #define SECTION_PEER_PRIVATE "peer_private"
+
77 #define SECTION_PEERS_MAX "peers_max"
+
78 #define SECTION_PEERS_IN_MAX "peers_in_max"
+
79 #define SECTION_PEERS_OUT_MAX "peers_out_max"
+
80 #define SECTION_PORT_GRPC "port_grpc"
+
81 #define SECTION_PREFETCH_WORKERS "prefetch_workers"
+
82 #define SECTION_REDUCE_RELAY "reduce_relay"
+
83 #define SECTION_RELATIONAL_DB "relational_db"
+
84 #define SECTION_RELAY_PROPOSALS "relay_proposals"
+
85 #define SECTION_RELAY_VALIDATIONS "relay_validations"
+
86 #define SECTION_RPC_STARTUP "rpc_startup"
+
87 #define SECTION_SIGNING_SUPPORT "signing_support"
+
88 #define SECTION_SNTP "sntp_servers"
+
89 #define SECTION_SSL_VERIFY "ssl_verify"
+
90 #define SECTION_SSL_VERIFY_FILE "ssl_verify_file"
+
91 #define SECTION_SSL_VERIFY_DIR "ssl_verify_dir"
+
92 #define SECTION_SERVER_DOMAIN "server_domain"
+
93 #define SECTION_SWEEP_INTERVAL "sweep_interval"
+
94 #define SECTION_VALIDATORS_FILE "validators_file"
+
95 #define SECTION_VALIDATION_SEED "validation_seed"
+
96 #define SECTION_VALIDATOR_KEYS "validator_keys"
+
97 #define SECTION_VALIDATOR_KEY_REVOCATION "validator_key_revocation"
+
98 #define SECTION_VALIDATOR_LIST_KEYS "validator_list_keys"
+
99 #define SECTION_VALIDATOR_LIST_SITES "validator_list_sites"
+
100 #define SECTION_VALIDATORS "validators"
+
101 #define SECTION_VALIDATOR_TOKEN "validator_token"
+
102 #define SECTION_VETO_AMENDMENTS "veto_amendments"
+
103 #define SECTION_WORKERS "workers"
+
104 
+
105 } // namespace ripple
+
106 
+
107 #endif
std::string
STL class.
ripple::ConfigSection::shardDatabase
static std::string shardDatabase()
Definition: ConfigSections.h:38
diff --git a/Coroutine__test_8cpp_source.html b/Coroutine__test_8cpp_source.html index df7b1fcc30..97f14032ba 100644 --- a/Coroutine__test_8cpp_source.html +++ b/Coroutine__test_8cpp_source.html @@ -268,7 +268,7 @@ $(function() {
std::chrono::duration
std::lock_guard
STL class.
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::test::Coroutine_test::incorrect_order
void incorrect_order()
Definition: Coroutine_test.cpp:90
ripple::test::Coroutine_test::gate::signaled_
bool signaled_
Definition: Coroutine_test.cpp:37
chrono
diff --git a/DatabaseDownloader__test_8cpp_source.html b/DatabaseDownloader__test_8cpp_source.html index 60639d40e4..e832c535c0 100644 --- a/DatabaseDownloader__test_8cpp_source.html +++ b/DatabaseDownloader__test_8cpp_source.html @@ -392,7 +392,7 @@ $(function() {
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
std::function
ripple::test::DatabaseDownloader_test::DownloadCompleter::cv
std::condition_variable cv
Definition: DatabaseDownloader_test.cpp:52
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::test::TrustedPublisherServer::ca_cert
static std::string const & ca_cert()
Definition: TrustedPublisherServer.h:400
ripple::test::DatabaseDownloader_test::cb
DownloadCompleter cb
Definition: DatabaseDownloader_test.cpp:77
std::vector::push_back
T push_back(T... args)
diff --git a/Database__test_8cpp_source.html b/Database__test_8cpp_source.html index 59d93609e4..ad6fcac2a2 100644 --- a/Database__test_8cpp_source.html +++ b/Database__test_8cpp_source.html @@ -775,7 +775,7 @@ $(function() {
ripple::NodeStore::Database_test::testNodeStore
void testNodeStore(std::string const &type, bool const testPersistence, std::int64_t const seedValue, int numObjsToTest=2000)
Definition: Database_test.cpp:505
ripple::NodeStore::Database_test::testImport
void testImport(std::string const &destBackendType, std::string const &srcBackendType, std::int64_t seedValue)
Definition: Database_test.cpp:447
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::NodeStore::Database_test::run
void run() override
Definition: Database_test.cpp:656
std::sort
T sort(T... args)
std::unique_ptr::reset
T reset(T... args)
diff --git a/DepositAuthorized__test_8cpp_source.html b/DepositAuthorized__test_8cpp_source.html index bddefc1db4..a27cd11230 100644 --- a/DepositAuthorized__test_8cpp_source.html +++ b/DepositAuthorized__test_8cpp_source.html @@ -366,7 +366,7 @@ $(function() {
ripple::test::jtx::Env::rpc
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:711
ripple::test::jtx::Account::human
std::string const & human() const
Returns the human readable public key.
Definition: Account.h:113
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
-
ripple::authorized
static bool authorized(Port const &port, std::map< std::string, std::string > const &h)
Definition: ServerHandler.cpp:85
+
ripple::authorized
static bool authorized(Port const &port, std::map< std::string, std::string > const &h)
Definition: ServerHandler.cpp:84
ripple::test::DepositAuthorized_test::testValid
void testValid()
Definition: DepositAuthorized_test.cpp:56
ripple::test::jtx::fset
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Definition: flags.cpp:28
ripple::test::DepositAuthorized_test::run
void run() override
Definition: DepositAuthorized_test.cpp:280
diff --git a/Env_8h_source.html b/Env_8h_source.html index 39c5f4e4b8..c7926bd1f5 100644 --- a/Env_8h_source.html +++ b/Env_8h_source.html @@ -671,7 +671,7 @@ $(function() {
ripple::test::jtx::forAllApiVersions
void forAllApiVersions(VersionedTestCallable auto... testCallable)
Definition: Env.h:781
ripple::test::jtx::Env::balance
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition: Env.cpp:183
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::RPC::apiCommandLineVersion
constexpr unsigned int apiCommandLineVersion
Definition: RPCHelpers.h:236
ripple::Application::openLedger
virtual OpenLedger & openLedger()=0
ripple::test::jtx::Env::bundle_
AppBundle bundle_
Definition: Env.h:141
diff --git a/Env__test_8cpp_source.html b/Env__test_8cpp_source.html index a642bda18d..b9e96e9923 100644 --- a/Env__test_8cpp_source.html +++ b/Env__test_8cpp_source.html @@ -1033,7 +1033,7 @@ $(function() {
ripple::test::jtx::Env::balance
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition: Env.cpp:183
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:241
ripple::test::Env_test::run
void run() override
Definition: Env_test.cpp:904
-
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
+
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:54
ripple::test::jtx::memotype
Definition: memo.h:82
ripple::test::jtx::msig
Set a multisignature on a JTx.
Definition: multisign.h:63
ripple::test::jtx::memondata
Definition: memo.h:96
diff --git a/GRPCServer_8cpp_source.html b/GRPCServer_8cpp_source.html index 71240d75ca..01a2c3839c 100644 --- a/GRPCServer_8cpp_source.html +++ b/GRPCServer_8cpp_source.html @@ -94,702 +94,704 @@ $(function() {
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
-
33 std::optional<boost::asio::ip::tcp::endpoint>
-
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 
-
46  std::optional<beast::IP::Endpoint> endpoint =
-
47  beast::IP::Endpoint::from_string_checked(peerClean);
-
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>
-
60 GRPCServerImpl::CallData<Request, Response>::CallData(
-
61  org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService& service,
-
62  grpc::ServerCompletionQueue& cq,
-
63  Application& app,
-
64  BindListener<Request, Response> bindListener,
-
65  Handler<Request, Response> handler,
-
66  Forward<Request, Response> forward,
-
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
-
84  bindListener_(service_, &ctx_, &request_, &responder_, &cq_, &cq_, this);
-
85 }
-
86 
-
87 template <class Request, class Response>
-
88 std::shared_ptr<Processor>
-
89 GRPCServerImpl::CallData<Request, Response>::clone()
-
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_,
-
100  secureGatewayIPs_);
-
101 }
-
102 
-
103 template <class Request, class Response>
-
104 void
-
105 GRPCServerImpl::CallData<Request, Response>::process()
-
106 {
-
107  // sanity check
-
108  BOOST_ASSERT(!finished_);
-
109 
-
110  std::shared_ptr<CallData<Request, Response>> thisShared =
-
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
-
140 GRPCServerImpl::CallData<Request, Response>::process(
-
141  std::shared_ptr<JobQueue::Coro> coro)
-
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 
-
177  RPC::GRPCContext<Request> context{
-
178  {app_.journal("gRPCServer"),
-
179  app_,
-
180  loadType,
-
181  app_.getOPs(),
-
182  app_.getLedgerMaster(),
-
183  usage,
-
184  role,
-
185  coro,
-
186  InfoSub::pointer(),
-
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  {
-
211  std::pair<Response, grpc::Status> result =
-
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
-
233 GRPCServerImpl::CallData<Request, Response>::forwardToP2p(
-
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
-
273 GRPCServerImpl::CallData<Request, Response>::isFinished()
-
274 {
-
275  return finished_;
-
276 }
-
277 
-
278 template <class Request, class Response>
-
279 Resource::Charge
-
280 GRPCServerImpl::CallData<Request, Response>::getLoadType()
-
281 {
-
282  return loadType_;
-
283 }
-
284 
-
285 template <class Request, class Response>
-
286 Role
-
287 GRPCServerImpl::CallData<Request, Response>::getRole(bool isUnlimited)
-
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
-
299 GRPCServerImpl::CallData<Request, Response>::wasForwarded()
-
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>
-
315 std::optional<std::string>
-
316 GRPCServerImpl::CallData<Request, Response>::getUser()
-
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>
-
331 std::optional<boost::asio::ip::address>
-
332 GRPCServerImpl::CallData<Request, Response>::getClientIpAddress()
-
333 {
-
334  auto endpoint = getClientEndpoint();
-
335  if (endpoint)
-
336  return endpoint->address();
-
337  return {};
-
338 }
-
339 
-
340 template <class Request, class Response>
-
341 std::optional<boost::asio::ip::address>
-
342 GRPCServerImpl::CallData<Request, Response>::getProxiedClientIpAddress()
-
343 {
-
344  auto endpoint = getProxiedClientEndpoint();
-
345  if (endpoint)
-
346  return endpoint->address();
-
347  return {};
-
348 }
-
349 
-
350 template <class Request, class Response>
-
351 std::optional<boost::asio::ip::tcp::endpoint>
-
352 GRPCServerImpl::CallData<Request, Response>::getProxiedClientEndpoint()
-
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>
-
370 std::optional<boost::asio::ip::tcp::endpoint>
-
371 GRPCServerImpl::CallData<Request, Response>::getClientEndpoint()
-
372 {
-
373  return getEndpoint(ctx_.peer());
-
374 }
-
375 
-
376 template <class Request, class Response>
-
377 bool
-
378 GRPCServerImpl::CallData<Request, Response>::clientIsUnlimited()
-
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
-
397 GRPCServerImpl::CallData<Request, Response>::setIsUnlimited(
-
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>
-
412 Resource::Consumer
-
413 GRPCServerImpl::CallData<Request, Response>::getUsage()
-
414 {
-
415  auto endpoint = getClientEndpoint();
-
416  auto proxiedEndpoint = getProxiedClientEndpoint();
-
417  if (proxiedEndpoint)
-
418  return app_.getResourceManager().newInboundEndpoint(
-
419  beast::IP::from_asio(proxiedEndpoint.value()));
-
420  else if (endpoint)
-
421  return app_.getResourceManager().newInboundEndpoint(
-
422  beast::IP::from_asio(endpoint.value()));
-
423  Throw<std::runtime_error>("Failed to get client endpoint");
-
424 }
-
425 
-
426 GRPCServerImpl::GRPCServerImpl(Application& app)
-
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  const auto& 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 
-
446  std::stringstream ss;
-
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 
-
477  secureGatewayIPs_.emplace_back(addr);
-
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
-
492 GRPCServerImpl::shutdown()
-
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
-
514 GRPCServerImpl::handleRpcs()
-
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.
-
519  std::vector<std::shared_ptr<Processor>> requests = setupListeners();
-
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
-
584 std::vector<std::shared_ptr<Processor>>
-
585 GRPCServerImpl::setupListeners()
-
586 {
-
587  std::vector<std::shared_ptr<Processor>> requests;
-
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,
-
606  RPC::NO_CONDITION,
-
607  Resource::feeMediumBurdenRPC,
-
608  secureGatewayIPs_));
-
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,
-
621  doLedgerDataGrpc,
-
622  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerData,
-
623  RPC::NO_CONDITION,
-
624  Resource::feeMediumBurdenRPC,
-
625  secureGatewayIPs_));
-
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,
-
638  doLedgerDiffGrpc,
-
639  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerDiff,
-
640  RPC::NO_CONDITION,
-
641  Resource::feeMediumBurdenRPC,
-
642  secureGatewayIPs_));
-
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,
-
655  doLedgerEntryGrpc,
-
656  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerEntry,
-
657  RPC::NO_CONDITION,
-
658  Resource::feeMediumBurdenRPC,
-
659  secureGatewayIPs_));
-
660  }
-
661  return requests;
-
662 };
-
663 
-
664 bool
-
665 GRPCServerImpl::start()
-
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
-
689 GRPCServer::start()
-
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
-
704 GRPCServer::stop()
-
705 {
-
706  if (running_)
-
707  {
-
708  impl_.shutdown();
-
709  thread_.join();
-
710  running_ = false;
-
711  }
-
712 }
-
713 
-
714 GRPCServer::~GRPCServer()
-
715 {
-
716  assert(!running_);
-
717 }
-
718 
-
719 } // namespace ripple
+
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
+
34 std::optional<boost::asio::ip::tcp::endpoint>
+
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 
+
47  std::optional<beast::IP::Endpoint> endpoint =
+
48  beast::IP::Endpoint::from_string_checked(peerClean);
+
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>
+
61 GRPCServerImpl::CallData<Request, Response>::CallData(
+
62  org::xrpl::rpc::v1::XRPLedgerAPIService::AsyncService& service,
+
63  grpc::ServerCompletionQueue& cq,
+
64  Application& app,
+
65  BindListener<Request, Response> bindListener,
+
66  Handler<Request, Response> handler,
+
67  Forward<Request, Response> forward,
+
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
+
85  bindListener_(service_, &ctx_, &request_, &responder_, &cq_, &cq_, this);
+
86 }
+
87 
+
88 template <class Request, class Response>
+
89 std::shared_ptr<Processor>
+
90 GRPCServerImpl::CallData<Request, Response>::clone()
+
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_,
+
101  secureGatewayIPs_);
+
102 }
+
103 
+
104 template <class Request, class Response>
+
105 void
+
106 GRPCServerImpl::CallData<Request, Response>::process()
+
107 {
+
108  // sanity check
+
109  BOOST_ASSERT(!finished_);
+
110 
+
111  std::shared_ptr<CallData<Request, Response>> thisShared =
+
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
+
141 GRPCServerImpl::CallData<Request, Response>::process(
+
142  std::shared_ptr<JobQueue::Coro> coro)
+
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 
+
178  RPC::GRPCContext<Request> context{
+
179  {app_.journal("gRPCServer"),
+
180  app_,
+
181  loadType,
+
182  app_.getOPs(),
+
183  app_.getLedgerMaster(),
+
184  usage,
+
185  role,
+
186  coro,
+
187  InfoSub::pointer(),
+
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  {
+
212  std::pair<Response, grpc::Status> result =
+
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
+
234 GRPCServerImpl::CallData<Request, Response>::forwardToP2p(
+
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
+
274 GRPCServerImpl::CallData<Request, Response>::isFinished()
+
275 {
+
276  return finished_;
+
277 }
+
278 
+
279 template <class Request, class Response>
+
280 Resource::Charge
+
281 GRPCServerImpl::CallData<Request, Response>::getLoadType()
+
282 {
+
283  return loadType_;
+
284 }
+
285 
+
286 template <class Request, class Response>
+
287 Role
+
288 GRPCServerImpl::CallData<Request, Response>::getRole(bool isUnlimited)
+
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
+
300 GRPCServerImpl::CallData<Request, Response>::wasForwarded()
+
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>
+
316 std::optional<std::string>
+
317 GRPCServerImpl::CallData<Request, Response>::getUser()
+
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>
+
332 std::optional<boost::asio::ip::address>
+
333 GRPCServerImpl::CallData<Request, Response>::getClientIpAddress()
+
334 {
+
335  auto endpoint = getClientEndpoint();
+
336  if (endpoint)
+
337  return endpoint->address();
+
338  return {};
+
339 }
+
340 
+
341 template <class Request, class Response>
+
342 std::optional<boost::asio::ip::address>
+
343 GRPCServerImpl::CallData<Request, Response>::getProxiedClientIpAddress()
+
344 {
+
345  auto endpoint = getProxiedClientEndpoint();
+
346  if (endpoint)
+
347  return endpoint->address();
+
348  return {};
+
349 }
+
350 
+
351 template <class Request, class Response>
+
352 std::optional<boost::asio::ip::tcp::endpoint>
+
353 GRPCServerImpl::CallData<Request, Response>::getProxiedClientEndpoint()
+
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>
+
371 std::optional<boost::asio::ip::tcp::endpoint>
+
372 GRPCServerImpl::CallData<Request, Response>::getClientEndpoint()
+
373 {
+
374  return getEndpoint(ctx_.peer());
+
375 }
+
376 
+
377 template <class Request, class Response>
+
378 bool
+
379 GRPCServerImpl::CallData<Request, Response>::clientIsUnlimited()
+
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
+
398 GRPCServerImpl::CallData<Request, Response>::setIsUnlimited(
+
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>
+
413 Resource::Consumer
+
414 GRPCServerImpl::CallData<Request, Response>::getUsage()
+
415 {
+
416  auto endpoint = getClientEndpoint();
+
417  auto proxiedEndpoint = getProxiedClientEndpoint();
+
418  if (proxiedEndpoint)
+
419  return app_.getResourceManager().newInboundEndpoint(
+
420  beast::IP::from_asio(proxiedEndpoint.value()));
+
421  else if (endpoint)
+
422  return app_.getResourceManager().newInboundEndpoint(
+
423  beast::IP::from_asio(endpoint.value()));
+
424  Throw<std::runtime_error>("Failed to get client endpoint");
+
425 }
+
426 
+
427 GRPCServerImpl::GRPCServerImpl(Application& app)
+
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 
+
447  std::stringstream ss;
+
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 
+
478  secureGatewayIPs_.emplace_back(addr);
+
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
+
493 GRPCServerImpl::shutdown()
+
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
+
515 GRPCServerImpl::handleRpcs()
+
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.
+
520  std::vector<std::shared_ptr<Processor>> requests = setupListeners();
+
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
+
585 std::vector<std::shared_ptr<Processor>>
+
586 GRPCServerImpl::setupListeners()
+
587 {
+
588  std::vector<std::shared_ptr<Processor>> requests;
+
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,
+
607  RPC::NO_CONDITION,
+
608  Resource::feeMediumBurdenRPC,
+
609  secureGatewayIPs_));
+
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,
+
622  doLedgerDataGrpc,
+
623  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerData,
+
624  RPC::NO_CONDITION,
+
625  Resource::feeMediumBurdenRPC,
+
626  secureGatewayIPs_));
+
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,
+
639  doLedgerDiffGrpc,
+
640  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerDiff,
+
641  RPC::NO_CONDITION,
+
642  Resource::feeMediumBurdenRPC,
+
643  secureGatewayIPs_));
+
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,
+
656  doLedgerEntryGrpc,
+
657  &org::xrpl::rpc::v1::XRPLedgerAPIService::Stub::GetLedgerEntry,
+
658  RPC::NO_CONDITION,
+
659  Resource::feeMediumBurdenRPC,
+
660  secureGatewayIPs_));
+
661  }
+
662  return requests;
+
663 }
+
664 
+
665 bool
+
666 GRPCServerImpl::start()
+
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
+
690 GRPCServer::start()
+
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
+
705 GRPCServer::stop()
+
706 {
+
707  if (running_)
+
708  {
+
709  impl_.shutdown();
+
710  thread_.join();
+
711  running_ = false;
+
712  }
+
713 }
+
714 
+
715 GRPCServer::~GRPCServer()
+
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.
@@ -798,16 +800,16 @@ $(function() {
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:89
+
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:665
+
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:492
+
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
@@ -819,12 +821,12 @@ $(function() {
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
+
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:273
+
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:60
+
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
@@ -834,7 +836,7 @@ $(function() {
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
+
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
@@ -849,28 +851,28 @@ $(function() {
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:426
+
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:280
+
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: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::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:689
+
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:714
+
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:585
+
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
@@ -882,33 +884,33 @@ $(function() {
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::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:287
+
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:342
-
ripple::GRPCServerImpl::CallData::forwardToP2p
void forwardToP2p(RPC::GRPCContext< Request > &context)
Definition: GRPCServer.cpp:233
+
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:371
+
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:378
+
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:316
+
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:105
+
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:332
+
ripple::GRPCServerImpl::CallData::getClientIpAddress
std::optional< boost::asio::ip::address > getClientIpAddress()
Definition: GRPCServer.cpp:333