diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ea2cfc2..ea71781c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,46 +61,44 @@ include(Postgres) target_sources(clio PRIVATE -## Backend + ## Backend src/backend/CassandraBackend.cpp src/backend/PostgresBackend.cpp src/backend/BackendIndexer.cpp src/backend/BackendInterface.cpp src/backend/Pg.cpp src/backend/DBHelpers.cpp -## Reporting + ## ETL src/etl/ETLSource.cpp src/etl/ReportingETL.cpp -## Server + ## Server src/webserver/SubscriptionManager.cpp -## Handlers - src/handlers/Status.cpp - src/handlers/RPCHelpers.cpp - src/handlers/Handlers.cpp - src/handlers/Context.cpp -## Methods + ## RPC + src/rpc/RPC.cpp + src/rpc/RPCHelpers.cpp + ## RPC Methods # Account - src/handlers/methods/impl/AccountChannels.cpp - src/handlers/methods/impl/AccountCurrencies.cpp - src/handlers/methods/impl/AccountInfo.cpp - src/handlers/methods/impl/AccountLines.cpp - src/handlers/methods/impl/AccountOffers.cpp - src/handlers/methods/impl/AccountObjects.cpp + src/rpc/handlers/AccountChannels.cpp + src/rpc/handlers/AccountCurrencies.cpp + src/rpc/handlers/AccountInfo.cpp + src/rpc/handlers/AccountLines.cpp + src/rpc/handlers/AccountOffers.cpp + src/rpc/handlers/AccountObjects.cpp # Ledger - src/handlers/methods/impl/Ledger.cpp - src/handlers/methods/impl/LedgerData.cpp - src/handlers/methods/impl/LedgerEntry.cpp - src/handlers/methods/impl/LedgerRange.cpp + src/rpc/handlers/Ledger.cpp + src/rpc/handlers/LedgerData.cpp + src/rpc/handlers/LedgerEntry.cpp + src/rpc/handlers/LedgerRange.cpp # Transaction - src/handlers/methods/impl/Tx.cpp - src/handlers/methods/impl/AccountTx.cpp + src/rpc/handlers/Tx.cpp + src/rpc/handlers/AccountTx.cpp # Dex - src/handlers/methods/impl/BookOffers.cpp + src/rpc/handlers/BookOffers.cpp # Payment Channel - src/handlers/methods/impl/ChannelAuthorize.cpp - src/handlers/methods/impl/ChannelVerify.cpp + src/rpc/handlers/ChannelAuthorize.cpp + src/rpc/handlers/ChannelVerify.cpp # Subscribe - src/handlers/methods/impl/Subscribe.cpp) + src/rpc/handlers/Subscribe.cpp) message(${Boost_LIBRARIES}) diff --git a/example-config.json b/example-config.json index 81922497..0cd4cc40 100644 --- a/example-config.json +++ b/example-config.json @@ -7,6 +7,7 @@ "contact_points":"127.0.0.1", "port":9042, "keyspace":"clio", + "replication_factor":1, "table_prefix":"", "max_requests_outstanding":25000, "threads":8 @@ -22,7 +23,7 @@ [ { "ip":"127.0.0.1", - "ws_port":"6005", + "ws_port":"6006", "grpc_port":"50051" } ], @@ -37,5 +38,5 @@ "log_level":"debug", "online_delete":0, "extractor_threads":8, - "read_only":false + "read_only":true } diff --git a/src/backend/CassandraBackend.cpp b/src/backend/CassandraBackend.cpp index 2666fc23..2cd13b7b 100644 --- a/src/backend/CassandraBackend.cpp +++ b/src/backend/CassandraBackend.cpp @@ -15,7 +15,7 @@ processAsyncWriteResponse(T& requestParams, CassFuture* fut, F func) auto wait = std::chrono::milliseconds( lround(std::pow(2, std::min(10u, requestParams.currentRetries)))); BOOST_LOG_TRIVIAL(error) - << "ERROR!!! Cassandra ETL insert error: " << rc << ", " + << "ERROR!!! Cassandra write error: " << rc << ", " << cass_error_desc(rc) << ", retrying in " << wait.count() << " milliseconds"; ++requestParams.currentRetries; diff --git a/src/backend/CassandraBackend.h b/src/backend/CassandraBackend.h index a9c124da..b15a1938 100644 --- a/src/backend/CassandraBackend.h +++ b/src/backend/CassandraBackend.h @@ -1051,9 +1051,8 @@ public: { std::stringstream ss; ss << "Cassandra executeSyncRead error"; - ss << ", retrying"; ss << ": " << cass_error_desc(rc); - BOOST_LOG_TRIVIAL(warning) << ss.str(); + BOOST_LOG_TRIVIAL(error) << ss.str(); } if (isTimeout(rc)) { diff --git a/src/handlers/Context.cpp b/src/handlers/Context.cpp deleted file mode 100644 index cca0e492..00000000 --- a/src/handlers/Context.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include - -namespace RPC -{ - -std::optional -make_WsContext( - boost::json::object const& request, - std::shared_ptr const& backend, - std::shared_ptr const& subscriptions, - std::shared_ptr const& balancer, - std::shared_ptr const& session, - Backend::LedgerRange const& range) -{ - if (!request.contains("command")) - return {}; - - std::string command = request.at("command").as_string().c_str(); - - return Context{ - command, - 1, - request, - backend, - subscriptions, - balancer, - session, - range - }; -} - -std::optional -make_HttpContext( - boost::json::object const& request, - std::shared_ptr const& backend, - std::shared_ptr const& subscriptions, - std::shared_ptr const& balancer, - Backend::LedgerRange const& range) -{ - if (!request.contains("method") || !request.at("method").is_string()) - return {}; - - std::string const& command = request.at("method").as_string().c_str(); - - if (command == "subscribe" || command == "unsubscribe") - return {}; - - if (!request.contains("params") || !request.at("params").is_array()) - return {}; - - boost::json::array const& array = request.at("params").as_array(); - - if (array.size() != 1) - return {}; - - if (!array.at(0).is_object()) - return {}; - - return Context{ - command, - 1, - array.at(0).as_object(), - backend, - subscriptions, - balancer, - nullptr, - range - }; -} - -} // namespace RPC \ No newline at end of file diff --git a/src/handlers/Handlers.cpp b/src/handlers/Handlers.cpp deleted file mode 100644 index 9fc3cf8b..00000000 --- a/src/handlers/Handlers.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -namespace RPC { - -static std::unordered_map> - handlerTable{ - {"account_channels", &doAccountChannels}, - {"account_currencies", &doAccountCurrencies}, - {"account_info", &doAccountInfo}, - {"account_lines", &doAccountLines}, - {"account_objects", &doAccountObjects}, - {"account_offers", &doAccountOffers}, - {"account_tx", &doAccountTx}, - {"book_offers", &doBookOffers}, - {"channel_authorize", &doChannelAuthorize}, - {"channel_verify", &doChannelVerify}, - {"ledger", &doLedger}, - {"ledger_data", &doLedgerData}, - {"ledger_entry", &doLedgerEntry}, - {"ledger_range", &doLedgerRange}, - {"ledger_data", &doLedgerData}, - {"subscribe", &doSubscribe}, - {"unsubscribe", &doUnsubscribe}, - {"tx", &doTx}, - }; - -static std::unordered_set forwardCommands{ - "submit", - "submit_multisigned", - "fee", - "path_find", - "ripple_path_find", - "manifest"}; - -bool -shouldForwardToRippled(Context const& ctx) -{ - auto request = ctx.params; - - if (forwardCommands.find(ctx.method) != forwardCommands.end()) - return true; - - if (request.contains("ledger_index")) - { - auto indexValue = request.at("ledger_index"); - if (indexValue.is_string()) - { - std::string index = indexValue.as_string().c_str(); - return index == "current" || index == "closed"; - } - } - - return false; -} - -Result -buildResponse(Context const& ctx) -{ - if (shouldForwardToRippled(ctx)) - return ctx.balancer->forwardToRippled(ctx.params); - - if (handlerTable.find(ctx.method) == handlerTable.end()) - return Status{Error::rpcUNKNOWN_COMMAND}; - - auto method = handlerTable[ctx.method]; - - return method(ctx); -} - -} // namespace RPC diff --git a/src/handlers/Handlers.h b/src/handlers/Handlers.h deleted file mode 100644 index 25d6993c..00000000 --- a/src/handlers/Handlers.h +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -#include -#include -#include - -#ifndef RIPPLE_REPORTING_HANDLERS_H -#define RIPPLE_REPORTING_HANDLERS_H - -namespace RPC -{ - -// Maximum and minimum supported API versions -// Defaults to APIVersionIfUnspecified -constexpr unsigned int APIVersionIfUnspecified = 1; -constexpr unsigned int ApiMinimumSupportedVersion = 1; -constexpr unsigned int ApiMaximumSupportedVersion = 1; -constexpr unsigned int APINumberVersionSupported = - ApiMaximumSupportedVersion - ApiMinimumSupportedVersion + 1; - -static_assert(ApiMinimumSupportedVersion >= APIVersionIfUnspecified); -static_assert(ApiMaximumSupportedVersion >= ApiMinimumSupportedVersion); - -Result -buildResponse(Context const& ctx); - -} // namespace RPC -#endif // RIPPLE_REPORTING_HANDLERS_H diff --git a/src/handlers/README.md b/src/handlers/README.md deleted file mode 100644 index 3e8f0e9e..00000000 --- a/src/handlers/README.md +++ /dev/null @@ -1,10 +0,0 @@ -This folder contains all of the RPC handlers. - -Generally, handlers parse the request and call the appropriate method of `BackendInterface` -to read from the database. - -Certain RPCs, such as `fee` and `submit`, are just forwarded to `rippled`, and the response -is propagated back to the client. - -If the database returns a timeout, an error is returned to the client. -This automatically happens, and is caught at a higher level, outside of the handler. diff --git a/src/handlers/Status.cpp b/src/handlers/Status.cpp deleted file mode 100644 index 217af122..00000000 --- a/src/handlers/Status.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#include -#include -#include - -namespace RPC -{ - -void -inject_error(Error err, boost::json::object& json) -{ - ripple::RPC::ErrorInfo const& info(ripple::RPC::get_error_info(err)); - json["error"] = info.token; - json["error_code"] = static_cast(err); - json["error_message"] = info.message; - json["status"] = "error"; - json["type"] = "response"; -} - -void -inject_error(Error err, std::string const& message, boost::json::object& json) -{ - ripple::RPC::ErrorInfo const& info(ripple::RPC::get_error_info(err)); - json["error"] = info.token; - json["error_code"] = static_cast(err); - json["error_message"] = message; - json["status"] = "error"; - json["type"] = "response"; -} - -boost::json::object -make_error(Error err) -{ - boost::json::object json{}; - inject_error(err, json); - return json; -} - -boost::json::object -make_error(Error err, std::string const& message) -{ - boost::json::object json{}; - inject_error(err, message, json); - return json; -} -} \ No newline at end of file diff --git a/src/handlers/Status.h b/src/handlers/Status.h deleted file mode 100644 index dd028a69..00000000 --- a/src/handlers/Status.h +++ /dev/null @@ -1,72 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef RPC_ERRORCODES_H_INCLUDED -#define RPC_ERRORCODES_H_INCLUDED - -#include -#include -#include -#include - -namespace RPC -{ - -using Error = ripple::error_code_i; - -struct Status -{ - Error error = Error::rpcSUCCESS; - std::string message = ""; - - Status() {}; - - Status(Error error_) : error(error_) {}; - - Status(Error error_, std::string message_) - : error(error_) - , message(message_) - {} - - /** Returns true if the Status is *not* OK. */ - operator bool() const - { - return error != Error::rpcSUCCESS; - } -}; - -static Status OK; - -using Result = std::variant; - -void -inject_error(Error err, boost::json::object& json); - -void -inject_error(Error err, std::string const& message, boost::json::object& json); - -boost::json::object -make_error(Error err); - -boost::json::object -make_error(Error err, std::string const& message); - -} // namespace RPC - -#endif // RPC_ERRORCODES_H_INCLUDED \ No newline at end of file diff --git a/src/handlers/methods/Account.h b/src/handlers/methods/Account.h deleted file mode 100644 index fc3fe4b2..00000000 --- a/src/handlers/methods/Account.h +++ /dev/null @@ -1,51 +0,0 @@ - -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - - -#ifndef REPORTING_ACCOUNT_HANDLER_H_INCLUDED -#define REPORTING_ACCOUNT_HANDLER_H_INCLUDED - -#include -#include -#include -#include - -namespace RPC -{ - -Result -doAccountInfo(Context const& context); - -Result -doAccountChannels(Context const& context); - -Result -doAccountCurrencies(Context const& context); - -Result -doAccountLines(Context const& context); - -Result -doAccountObjects(Context const& context); - -Result -doAccountOffers(Context const& context); - -} // namespace RPC - -#endif // REPORTING_ACCOUNT_HANDLER_H_INCLUDED \ No newline at end of file diff --git a/src/handlers/methods/Channel.h b/src/handlers/methods/Channel.h deleted file mode 100644 index ad9bf70f..00000000 --- a/src/handlers/methods/Channel.h +++ /dev/null @@ -1,38 +0,0 @@ - -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - - -#ifndef REPORTING_CHANNEL_HANDLER_H_INCLUDED -#define REPORTING_CHANNEL_HANDLER_H_INCLUDED - -#include -#include -#include - -namespace RPC -{ - -Result -doChannelAuthorize(Context const& context); - -Result -doChannelVerify(Context const& context); - -} // namespace RPC - -#endif // REPORTING_CHANNEL_HANDLER_H_INCLUDED \ No newline at end of file diff --git a/src/handlers/methods/Exchange.h b/src/handlers/methods/Exchange.h deleted file mode 100644 index 61b6ef82..00000000 --- a/src/handlers/methods/Exchange.h +++ /dev/null @@ -1,36 +0,0 @@ - -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - - -#ifndef REPORTING_EXCHANGE_HANDLER_H_INCLUDED -#define REPORTING_EXCHANGE_HANDLER_H_INCLUDED - -#include -#include -#include -#include - -namespace RPC -{ - -Result -doBookOffers(Context const& context); - -} // namespace RPC - -#endif // REPORTING_CHANNEL_HANDLER_H_INCLUDED \ No newline at end of file diff --git a/src/handlers/methods/Ledger.h b/src/handlers/methods/Ledger.h deleted file mode 100644 index 1ea159eb..00000000 --- a/src/handlers/methods/Ledger.h +++ /dev/null @@ -1,45 +0,0 @@ - -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - - -#ifndef REPORTING_LEDGER_HANDLER_H_INCLUDED -#define REPORTING_LEDGER_HANDLER_H_INCLUDED - -#include -#include -#include -#include - -namespace RPC -{ - -Result -doLedger(Context const& context); - -Result -doLedgerEntry(Context const& context); - -Result -doLedgerData(Context const& context); - -Result -doLedgerRange(Context const& context); - -} // namespace RPC - -#endif // REPORTING_LEDGER_HANDLER_H_INCLUDED \ No newline at end of file diff --git a/src/handlers/methods/Subscribe.h b/src/handlers/methods/Subscribe.h deleted file mode 100644 index b1baa207..00000000 --- a/src/handlers/methods/Subscribe.h +++ /dev/null @@ -1,39 +0,0 @@ - -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - - -#ifndef REPORTING_SUBSCRIBE_HANDLER_H_INCLUDED -#define REPORTING_SUBSCRIBE_HANDLER_H_INCLUDED - -#include -#include -#include -#include - -namespace RPC -{ - -Result -doSubscribe(Context const& context); - -Result -doUnsubscribe(Context const& context); - -} // namespace RPC - -#endif // REPORTING_SUBSCRIBE_HANDLER_H_INCLUDED \ No newline at end of file diff --git a/src/handlers/methods/Transaction.h b/src/handlers/methods/Transaction.h deleted file mode 100644 index 198a7951..00000000 --- a/src/handlers/methods/Transaction.h +++ /dev/null @@ -1,39 +0,0 @@ - -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - - -#ifndef REPORTING_TRANSACTION_HANDLER_H_INCLUDED -#define REPORTING_TRANSACTION_HANDLER_H_INCLUDED - -#include -#include -#include -#include - -namespace RPC -{ - -Result -doTx(Context const& context); - -Result -doAccountTx(Context const& context); - -} // namespace RPC - -#endif // REPORTING_TRANSACTION_HANDLER_H_INCLUDED \ No newline at end of file diff --git a/src/rpc/Handlers.h b/src/rpc/Handlers.h new file mode 100644 index 00000000..f52c4b4e --- /dev/null +++ b/src/rpc/Handlers.h @@ -0,0 +1,71 @@ +#ifndef REPORTING_HANDLERS_H_INCLUDED +#define REPORTING_HANDLERS_H_INCLUDED + +#include + +namespace RPC +{ + /* + * This file just contains declarations for all of the handlers + */ + +// account state methods +Result +doAccountInfo(Context const& context); + +Result +doAccountChannels(Context const& context); + +Result +doAccountCurrencies(Context const& context); + +Result +doAccountLines(Context const& context); + +Result +doAccountObjects(Context const& context); + +Result +doAccountOffers(Context const& context); + +// channels methods + +Result +doChannelAuthorize(Context const& context); + +Result +doChannelVerify(Context const& context); + +// offers methods +Result +doBookOffers(Context const& context); + +// ledger methods +Result +doLedger(Context const& context); + +Result +doLedgerEntry(Context const& context); + +Result +doLedgerData(Context const& context); + +Result +doLedgerRange(Context const& context); + +// transaction methods +Result +doTx(Context const& context); + +Result +doAccountTx(Context const& context); + +// subscriptions +Result +doSubscribe(Context const& context); + +Result +doUnsubscribe(Context const& context); + +} // namespace RPC +#endif diff --git a/src/rpc/RPC.cpp b/src/rpc/RPC.cpp new file mode 100644 index 00000000..477b72c6 --- /dev/null +++ b/src/rpc/RPC.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +namespace RPC +{ + +std::optional +make_WsContext( + boost::json::object const& request, + std::shared_ptr const& backend, + std::shared_ptr const& subscriptions, + std::shared_ptr const& balancer, + std::shared_ptr const& session, + Backend::LedgerRange const& range) +{ + if (!request.contains("command")) + return {}; + + std::string command = request.at("command").as_string().c_str(); + + return Context{ + command, + 1, + request, + backend, + subscriptions, + balancer, + session, + range + }; +} + +std::optional +make_HttpContext( + boost::json::object const& request, + std::shared_ptr const& backend, + std::shared_ptr const& subscriptions, + std::shared_ptr const& balancer, + Backend::LedgerRange const& range) +{ + if (!request.contains("method") || !request.at("method").is_string()) + return {}; + + std::string const& command = request.at("method").as_string().c_str(); + + if (command == "subscribe" || command == "unsubscribe") + return {}; + + if (!request.contains("params") || !request.at("params").is_array()) + return {}; + + boost::json::array const& array = request.at("params").as_array(); + + if (array.size() != 1) + return {}; + + if (!array.at(0).is_object()) + return {}; + + return Context{ + command, + 1, + array.at(0).as_object(), + backend, + subscriptions, + balancer, + nullptr, + range + }; +} + + + +void +inject_error(Error err, boost::json::object& json) +{ + ripple::RPC::ErrorInfo const& info(ripple::RPC::get_error_info(err)); + json["error"] = info.token; + json["error_code"] = static_cast(err); + json["error_message"] = info.message; + json["status"] = "error"; + json["type"] = "response"; +} + +void +inject_error(Error err, std::string const& message, boost::json::object& json) +{ + ripple::RPC::ErrorInfo const& info(ripple::RPC::get_error_info(err)); + json["error"] = info.token; + json["error_code"] = static_cast(err); + json["error_message"] = message; + json["status"] = "error"; + json["type"] = "response"; +} + +boost::json::object +make_error(Error err) +{ + boost::json::object json{}; + inject_error(err, json); + return json; +} + +boost::json::object +make_error(Error err, std::string const& message) +{ + boost::json::object json{}; + inject_error(err, message, json); + return json; +} +static std::unordered_map> + handlerTable{ + {"account_channels", &doAccountChannels}, + {"account_currencies", &doAccountCurrencies}, + {"account_info", &doAccountInfo}, + {"account_lines", &doAccountLines}, + {"account_objects", &doAccountObjects}, + {"account_offers", &doAccountOffers}, + {"account_tx", &doAccountTx}, + {"book_offers", &doBookOffers}, + {"channel_authorize", &doChannelAuthorize}, + {"channel_verify", &doChannelVerify}, + {"ledger", &doLedger}, + {"ledger_data", &doLedgerData}, + {"ledger_entry", &doLedgerEntry}, + {"ledger_range", &doLedgerRange}, + {"ledger_data", &doLedgerData}, + {"subscribe", &doSubscribe}, + {"unsubscribe", &doUnsubscribe}, + {"tx", &doTx}, + }; + +static std::unordered_set forwardCommands{ + "submit", + "submit_multisigned", + "fee", + "path_find", + "ripple_path_find", + "manifest"}; + +bool +shouldForwardToRippled(Context const& ctx) +{ + auto request = ctx.params; + + if (forwardCommands.find(ctx.method) != forwardCommands.end()) + return true; + + if (request.contains("ledger_index")) + { + auto indexValue = request.at("ledger_index"); + if (indexValue.is_string()) + { + std::string index = indexValue.as_string().c_str(); + return index == "current" || index == "closed"; + } + } + + return false; +} + +Result +buildResponse(Context const& ctx) +{ + if (shouldForwardToRippled(ctx)) + return ctx.balancer->forwardToRippled(ctx.params); + + if (handlerTable.find(ctx.method) == handlerTable.end()) + return Status{Error::rpcUNKNOWN_COMMAND}; + + auto method = handlerTable[ctx.method]; + + return method(ctx); +} +} diff --git a/src/handlers/Context.h b/src/rpc/RPC.h similarity index 55% rename from src/handlers/Context.h rename to src/rpc/RPC.h index 9deaed0f..832066e2 100644 --- a/src/handlers/Context.h +++ b/src/rpc/RPC.h @@ -1,28 +1,22 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2021 Ripple Labs Inc. - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef REPORTING_CONTEXT_H_INCLUDED -#define REPORTING_CONTEXT_H_INCLUDED - -#include +#ifndef REPORTING_RPC_H_INCLUDED +#define REPORTING_RPC_H_INCLUDED #include - +#include +#include +#include +#include #include +/* + * This file contains various classes necessary for executing RPC handlers. + * Context gives the handlers access to various other parts of the application + * Status is used to report errors. + * And lastly, there are various functions for making Contexts, Statuses and + * serializing Status to JSON. + * This file is meant to contain any class or function that code outside of the + * rpc folder needs to use. For helper functions or classes used within the rpc + * folder, use RPCHelpers.h. + */ class WsBase; class SubscriptionManager; @@ -61,6 +55,44 @@ struct Context , range(range_) {} }; +using Error = ripple::error_code_i; + +struct Status +{ + Error error = Error::rpcSUCCESS; + std::string message = ""; + + Status() {}; + + Status(Error error_) : error(error_) {}; + + Status(Error error_, std::string message_) + : error(error_) + , message(message_) + {} + + /** Returns true if the Status is *not* OK. */ + operator bool() const + { + return error != Error::rpcSUCCESS; + } +}; + +static Status OK; + +using Result = std::variant; + +void +inject_error(Error err, boost::json::object& json); + +void +inject_error(Error err, std::string const& message, boost::json::object& json); + +boost::json::object +make_error(Error err); + +boost::json::object +make_error(Error err, std::string const& message); std::optional @@ -79,7 +111,10 @@ make_HttpContext( std::shared_ptr const& subscriptions, std::shared_ptr const& balancer, Backend::LedgerRange const& range); + +Result +buildResponse(Context const& ctx); } // namespace RPC -#endif //REPORTING_CONTEXT_H_INCLUDED \ No newline at end of file +#endif //REPORTING_RPC_H_INCLUDED diff --git a/src/handlers/RPCHelpers.cpp b/src/rpc/RPCHelpers.cpp similarity index 99% rename from src/handlers/RPCHelpers.cpp rename to src/rpc/RPCHelpers.cpp index 5050aa76..82830da1 100644 --- a/src/handlers/RPCHelpers.cpp +++ b/src/rpc/RPCHelpers.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include std::optional getDeliveredAmount( diff --git a/src/handlers/RPCHelpers.h b/src/rpc/RPCHelpers.h similarity index 89% rename from src/handlers/RPCHelpers.h rename to src/rpc/RPCHelpers.h index 647a477b..c381411a 100644 --- a/src/handlers/RPCHelpers.h +++ b/src/rpc/RPCHelpers.h @@ -1,16 +1,18 @@ #ifndef XRPL_REPORTING_RPCHELPERS_H_INCLUDED #define XRPL_REPORTING_RPCHELPERS_H_INCLUDED +/* + * This file contains a variety of utility functions used when executing + * the handlers + */ #include #include #include #include #include -#include #include -#include -#include +#include std::optional accountFromStringStrict(std::string const& account); @@ -46,6 +48,13 @@ using RippledJson = Json::Value; boost::json::value toBoostJson(RippledJson const& value); + +boost::json::object +generatePubLedgerMessage(ripple::LedgerInfo const& lgrInfo, + ripple::Fees const& fees, + std::string const& ledgerRange, + uint32_t txnCount); + std::variant ledgerInfoFromRequest(RPC::Context const& ctx); diff --git a/src/handlers/methods/impl/AccountChannels.cpp b/src/rpc/handlers/AccountChannels.cpp similarity index 98% rename from src/handlers/methods/impl/AccountChannels.cpp rename to src/rpc/handlers/AccountChannels.cpp index 5ccf87e4..79de210e 100644 --- a/src/handlers/methods/impl/AccountChannels.cpp +++ b/src/rpc/handlers/AccountChannels.cpp @@ -6,8 +6,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -138,4 +137,4 @@ doAccountChannels(Context const& context) return response; } -} // namespace RPC \ No newline at end of file +} // namespace RPC diff --git a/src/handlers/methods/impl/AccountCurrencies.cpp b/src/rpc/handlers/AccountCurrencies.cpp similarity index 97% rename from src/handlers/methods/impl/AccountCurrencies.cpp rename to src/rpc/handlers/AccountCurrencies.cpp index cdcc1160..1e5f5949 100644 --- a/src/handlers/methods/impl/AccountCurrencies.cpp +++ b/src/rpc/handlers/AccountCurrencies.cpp @@ -6,8 +6,8 @@ #include #include #include -#include -#include + +#include #include #include #include diff --git a/src/handlers/methods/impl/AccountInfo.cpp b/src/rpc/handlers/AccountInfo.cpp similarity index 98% rename from src/handlers/methods/impl/AccountInfo.cpp rename to src/rpc/handlers/AccountInfo.cpp index d7cb80d5..36e1ed2a 100644 --- a/src/handlers/methods/impl/AccountInfo.cpp +++ b/src/rpc/handlers/AccountInfo.cpp @@ -20,8 +20,8 @@ #include #include #include -#include -#include + +#include #include // { diff --git a/src/handlers/methods/impl/AccountLines.cpp b/src/rpc/handlers/AccountLines.cpp similarity index 98% rename from src/handlers/methods/impl/AccountLines.cpp rename to src/rpc/handlers/AccountLines.cpp index 4b513770..1ab9ab23 100644 --- a/src/handlers/methods/impl/AccountLines.cpp +++ b/src/rpc/handlers/AccountLines.cpp @@ -6,9 +6,9 @@ #include #include #include -#include + #include -#include +#include #include #include diff --git a/src/handlers/methods/impl/AccountObjects.cpp b/src/rpc/handlers/AccountObjects.cpp similarity index 97% rename from src/handlers/methods/impl/AccountObjects.cpp rename to src/rpc/handlers/AccountObjects.cpp index fc61110c..1120df1d 100644 --- a/src/handlers/methods/impl/AccountObjects.cpp +++ b/src/rpc/handlers/AccountObjects.cpp @@ -7,8 +7,8 @@ #include #include #include -#include -#include +#include + #include #include diff --git a/src/handlers/methods/impl/AccountOffers.cpp b/src/rpc/handlers/AccountOffers.cpp similarity index 97% rename from src/handlers/methods/impl/AccountOffers.cpp rename to src/rpc/handlers/AccountOffers.cpp index ce533fca..a479c4e6 100644 --- a/src/handlers/methods/impl/AccountOffers.cpp +++ b/src/rpc/handlers/AccountOffers.cpp @@ -7,8 +7,8 @@ #include #include #include -#include -#include +#include + #include #include diff --git a/src/handlers/methods/impl/AccountTx.cpp b/src/rpc/handlers/AccountTx.cpp similarity index 99% rename from src/handlers/methods/impl/AccountTx.cpp rename to src/rpc/handlers/AccountTx.cpp index 10f7c606..da9e2654 100644 --- a/src/handlers/methods/impl/AccountTx.cpp +++ b/src/rpc/handlers/AccountTx.cpp @@ -19,8 +19,8 @@ #include #include -#include -#include +#include + namespace RPC { diff --git a/src/handlers/methods/impl/BookOffers.cpp b/src/rpc/handlers/BookOffers.cpp similarity index 99% rename from src/handlers/methods/impl/BookOffers.cpp rename to src/rpc/handlers/BookOffers.cpp index 73d045a2..12b9fa27 100644 --- a/src/handlers/methods/impl/BookOffers.cpp +++ b/src/rpc/handlers/BookOffers.cpp @@ -6,8 +6,8 @@ #include #include #include -#include -#include +#include + #include #include #include diff --git a/src/handlers/methods/impl/ChannelAuthorize.cpp b/src/rpc/handlers/ChannelAuthorize.cpp similarity index 97% rename from src/handlers/methods/impl/ChannelAuthorize.cpp rename to src/rpc/handlers/ChannelAuthorize.cpp index c23bcbfe..8ec4a65a 100644 --- a/src/handlers/methods/impl/ChannelAuthorize.cpp +++ b/src/rpc/handlers/ChannelAuthorize.cpp @@ -23,8 +23,8 @@ #include #include #include -#include -#include + +#include #include namespace RPC diff --git a/src/handlers/methods/impl/ChannelVerify.cpp b/src/rpc/handlers/ChannelVerify.cpp similarity index 98% rename from src/handlers/methods/impl/ChannelVerify.cpp rename to src/rpc/handlers/ChannelVerify.cpp index 2258fccc..e4a8be1c 100644 --- a/src/handlers/methods/impl/ChannelVerify.cpp +++ b/src/rpc/handlers/ChannelVerify.cpp @@ -23,8 +23,8 @@ #include #include #include -#include -#include + +#include #include namespace RPC diff --git a/src/handlers/methods/impl/Ledger.cpp b/src/rpc/handlers/Ledger.cpp similarity index 98% rename from src/handlers/methods/impl/Ledger.cpp rename to src/rpc/handlers/Ledger.cpp index a33290b9..c24ab683 100644 --- a/src/handlers/methods/impl/Ledger.cpp +++ b/src/rpc/handlers/Ledger.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include + namespace RPC { diff --git a/src/handlers/methods/impl/LedgerData.cpp b/src/rpc/handlers/LedgerData.cpp similarity index 98% rename from src/handlers/methods/impl/LedgerData.cpp rename to src/rpc/handlers/LedgerData.cpp index 5456f6e3..2663e2bf 100644 --- a/src/handlers/methods/impl/LedgerData.cpp +++ b/src/rpc/handlers/LedgerData.cpp @@ -20,8 +20,8 @@ #include #include #include -#include -#include + +#include #include // Get state nodes from a ledger // Inputs: diff --git a/src/handlers/methods/impl/LedgerEntry.cpp b/src/rpc/handlers/LedgerEntry.cpp similarity index 99% rename from src/handlers/methods/impl/LedgerEntry.cpp rename to src/rpc/handlers/LedgerEntry.cpp index 87a001d5..160fa954 100644 --- a/src/handlers/methods/impl/LedgerEntry.cpp +++ b/src/rpc/handlers/LedgerEntry.cpp @@ -1,8 +1,8 @@ #include #include #include -#include -#include + +#include #include // { // ledger_hash : diff --git a/src/handlers/methods/impl/LedgerRange.cpp b/src/rpc/handlers/LedgerRange.cpp similarity index 86% rename from src/handlers/methods/impl/LedgerRange.cpp rename to src/rpc/handlers/LedgerRange.cpp index ac2fbf48..458b8976 100644 --- a/src/handlers/methods/impl/LedgerRange.cpp +++ b/src/rpc/handlers/LedgerRange.cpp @@ -1,5 +1,5 @@ -#include -#include + +#include #include namespace RPC diff --git a/src/handlers/methods/impl/Subscribe.cpp b/src/rpc/handlers/Subscribe.cpp similarity index 98% rename from src/handlers/methods/impl/Subscribe.cpp rename to src/rpc/handlers/Subscribe.cpp index 824d72d7..ff9b3437 100644 --- a/src/handlers/methods/impl/Subscribe.cpp +++ b/src/rpc/handlers/Subscribe.cpp @@ -1,8 +1,8 @@ #include #include #include -#include -#include + +#include namespace RPC { diff --git a/src/handlers/methods/impl/Tx.cpp b/src/rpc/handlers/Tx.cpp similarity index 97% rename from src/handlers/methods/impl/Tx.cpp rename to src/rpc/handlers/Tx.cpp index 6a46a91d..bf1d5ab5 100644 --- a/src/handlers/methods/impl/Tx.cpp +++ b/src/rpc/handlers/Tx.cpp @@ -19,8 +19,8 @@ #include #include -#include -#include +#include + namespace RPC { diff --git a/src/webserver/HttpBase.h b/src/webserver/HttpBase.h index c6619fc7..daffe7d2 100644 --- a/src/webserver/HttpBase.h +++ b/src/webserver/HttpBase.h @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include diff --git a/src/webserver/PlainWsSession.h b/src/webserver/PlainWsSession.h index fef5ec71..824d9d64 100644 --- a/src/webserver/PlainWsSession.h +++ b/src/webserver/PlainWsSession.h @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include diff --git a/src/webserver/SubscriptionManager.cpp b/src/webserver/SubscriptionManager.cpp index 854c4f02..3aa76920 100644 --- a/src/webserver/SubscriptionManager.cpp +++ b/src/webserver/SubscriptionManager.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/webserver/WsBase.h b/src/webserver/WsBase.h index 7764c573..6626f643 100644 --- a/src/webserver/WsBase.h +++ b/src/webserver/WsBase.h @@ -28,8 +28,7 @@ #include #include -#include -#include +#include #include #include diff --git a/unittests/main.cpp b/unittests/main.cpp index 3a2d01f4..a55f778f 100644 --- a/unittests/main.cpp +++ b/unittests/main.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include