mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-19 19:25:53 +00:00
Cleanup, documentation, rename some things, cmake changes
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
set(CMAKE_VERBOSE_MAKEFILE TRUE)
|
set(CMAKE_VERBOSE_MAKEFILE TRUE)
|
||||||
project(reporting)
|
project(clio)
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
set (CMAKE_CXX_STANDARD 20)
|
set (CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Wno-narrowing")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Wno-narrowing")
|
||||||
@@ -30,22 +30,23 @@ FetchContent_MakeAvailable(googletest)
|
|||||||
enable_testing()
|
enable_testing()
|
||||||
include(GoogleTest)
|
include(GoogleTest)
|
||||||
|
|
||||||
add_executable (reporting_main
|
add_executable (clio_server
|
||||||
server/websocket_server_async.cpp
|
src/server/main.cpp
|
||||||
)
|
)
|
||||||
add_executable (reporting_tests
|
add_executable (clio_tests
|
||||||
unittests/main.cpp
|
unittests/main.cpp
|
||||||
)
|
)
|
||||||
add_library(reporting backend/BackendInterface.h)
|
add_library(clio src/backend/BackendInterface.h)
|
||||||
|
include_directories(src)
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps")
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
message(${CMAKE_CURRENT_BINARY_DIR})
|
message(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
message(${CMAKE_MODULE_PATH})
|
message(${CMAKE_MODULE_PATH})
|
||||||
#include(rippled/Builds/CMake/RippledCore.cmake)
|
#include(rippled/Builds/CMake/RippledCore.cmake)
|
||||||
add_subdirectory(rippled)
|
add_subdirectory(rippled)
|
||||||
target_link_libraries(reporting PUBLIC xrpl_core grpc_pbufs)
|
target_link_libraries(clio PUBLIC xrpl_core grpc_pbufs)
|
||||||
add_dependencies(reporting xrpl_core)
|
add_dependencies(clio xrpl_core)
|
||||||
add_dependencies(reporting grpc_pbufs)
|
add_dependencies(clio grpc_pbufs)
|
||||||
get_target_property(grpc_includes grpc_pbufs INCLUDE_DIRECTORIES)
|
get_target_property(grpc_includes grpc_pbufs INCLUDE_DIRECTORIES)
|
||||||
#get_target_property(xrpl_core_includes xrpl_core INCLUDE_DIRECTORIES)
|
#get_target_property(xrpl_core_includes xrpl_core INCLUDE_DIRECTORIES)
|
||||||
# get_target_property(proto_includes protobuf_src INCLUDE_DIRECTORIES)
|
# get_target_property(proto_includes protobuf_src INCLUDE_DIRECTORIES)
|
||||||
@@ -66,43 +67,43 @@ include(cassandra)
|
|||||||
include(Postgres)
|
include(Postgres)
|
||||||
|
|
||||||
|
|
||||||
target_sources(reporting PRIVATE
|
target_sources(clio PRIVATE
|
||||||
backend/CassandraBackend.cpp
|
src/backend/CassandraBackend.cpp
|
||||||
backend/PostgresBackend.cpp
|
src/backend/PostgresBackend.cpp
|
||||||
backend/BackendIndexer.cpp
|
src/backend/BackendIndexer.cpp
|
||||||
backend/BackendInterface.cpp
|
src/backend/BackendInterface.cpp
|
||||||
backend/Pg.cpp
|
src/backend/Pg.cpp
|
||||||
backend/DBHelpers.cpp
|
src/backend/DBHelpers.cpp
|
||||||
etl/ETLSource.cpp
|
src/etl/ETLSource.cpp
|
||||||
etl/ReportingETL.cpp
|
src/etl/ReportingETL.cpp
|
||||||
server/Handlers.cpp
|
src/server/Handlers.cpp
|
||||||
server/SubscriptionManager.cpp
|
src/server/SubscriptionManager.cpp
|
||||||
handlers/AccountInfo.cpp
|
src/handlers/AccountInfo.cpp
|
||||||
handlers/Tx.cpp
|
src/handlers/Tx.cpp
|
||||||
handlers/RPCHelpers.cpp
|
src/handlers/RPCHelpers.cpp
|
||||||
handlers/AccountTx.cpp
|
src/handlers/AccountTx.cpp
|
||||||
handlers/LedgerData.cpp
|
src/handlers/LedgerData.cpp
|
||||||
handlers/BookOffers.cpp
|
src/handlers/BookOffers.cpp
|
||||||
handlers/LedgerRange.cpp
|
src/handlers/LedgerRange.cpp
|
||||||
handlers/Ledger.cpp
|
src/handlers/Ledger.cpp
|
||||||
handlers/LedgerEntry.cpp
|
src/handlers/LedgerEntry.cpp
|
||||||
handlers/AccountChannels.cpp
|
src/handlers/AccountChannels.cpp
|
||||||
handlers/AccountLines.cpp
|
src/handlers/AccountLines.cpp
|
||||||
handlers/AccountCurrencies.cpp
|
src/handlers/AccountCurrencies.cpp
|
||||||
handlers/AccountOffers.cpp
|
src/handlers/AccountOffers.cpp
|
||||||
handlers/AccountObjects.cpp
|
src/handlers/AccountObjects.cpp
|
||||||
handlers/ChannelAuthorize.cpp
|
src/handlers/ChannelAuthorize.cpp
|
||||||
handlers/ChannelVerify.cpp
|
src/handlers/ChannelVerify.cpp
|
||||||
handlers/Subscribe.cpp
|
src/handlers/Subscribe.cpp
|
||||||
handlers/ServerInfo.cpp)
|
src/handlers/ServerInfo.cpp)
|
||||||
|
|
||||||
|
|
||||||
message(${Boost_LIBRARIES})
|
message(${Boost_LIBRARIES})
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${Boost_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${Boost_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
TARGET_LINK_LIBRARIES(reporting PUBLIC ${Boost_LIBRARIES})
|
TARGET_LINK_LIBRARIES(clio PUBLIC ${Boost_LIBRARIES})
|
||||||
TARGET_LINK_LIBRARIES(reporting_main PUBLIC reporting)
|
TARGET_LINK_LIBRARIES(clio_server PUBLIC clio)
|
||||||
TARGET_LINK_LIBRARIES(reporting_tests PUBLIC reporting gtest_main)
|
TARGET_LINK_LIBRARIES(clio_tests PUBLIC clio gtest_main)
|
||||||
|
|
||||||
|
|
||||||
gtest_discover_tests(reporting_tests)
|
gtest_discover_tests(clio_tests)
|
||||||
|
|
||||||
|
|||||||
10
deps/Postgres.cmake
vendored
10
deps/Postgres.cmake
vendored
@@ -45,23 +45,23 @@ if(NOT PostgreSQL_FOUND)
|
|||||||
|
|
||||||
file(TO_CMAKE_PATH "${postgres_src_SOURCE_DIR}" postgres_src_SOURCE_DIR)
|
file(TO_CMAKE_PATH "${postgres_src_SOURCE_DIR}" postgres_src_SOURCE_DIR)
|
||||||
|
|
||||||
target_link_libraries(reporting PUBLIC postgres)
|
target_link_libraries(clio PUBLIC postgres)
|
||||||
else()
|
else()
|
||||||
|
|
||||||
message("Found system installed Postgres via find_libary")
|
message("Found system installed Postgres via find_libary")
|
||||||
|
|
||||||
target_include_directories(reporting INTERFACE ${libpq-fe})
|
target_include_directories(clio INTERFACE ${libpq-fe})
|
||||||
|
|
||||||
target_link_libraries(reporting INTERFACE ${postgres})
|
target_link_libraries(clio INTERFACE ${postgres})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
message("Found system installed Postgres via find_package")
|
message("Found system installed Postgres via find_package")
|
||||||
message("${PostgreSQL_INCLUDE_DIRS}")
|
message("${PostgreSQL_INCLUDE_DIRS}")
|
||||||
|
|
||||||
include_directories(reporting INTERFACE "${PostgreSQL_INCLUDE_DIRS}")
|
include_directories(clio INTERFACE "${PostgreSQL_INCLUDE_DIRS}")
|
||||||
|
|
||||||
target_link_libraries(reporting PUBLIC ${PostgreSQL_LIBRARIES})
|
target_link_libraries(clio PUBLIC ${PostgreSQL_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
7
deps/cassandra.cmake
vendored
7
deps/cassandra.cmake
vendored
@@ -152,13 +152,12 @@ if(NOT cassandra)
|
|||||||
target_link_libraries(cassandra INTERFACE OpenSSL::SSL)
|
target_link_libraries(cassandra INTERFACE OpenSSL::SSL)
|
||||||
|
|
||||||
file(TO_CMAKE_PATH "${cassandra_src_SOURCE_DIR}" cassandra_src_SOURCE_DIR)
|
file(TO_CMAKE_PATH "${cassandra_src_SOURCE_DIR}" cassandra_src_SOURCE_DIR)
|
||||||
target_link_libraries(reporting PUBLIC cassandra)
|
target_link_libraries(clio PUBLIC cassandra)
|
||||||
else()
|
else()
|
||||||
message("Found system installed cassandra cpp driver")
|
message("Found system installed cassandra cpp driver")
|
||||||
message(${cassandra})
|
message(${cassandra})
|
||||||
|
|
||||||
find_path(cassandra_includes NAMES cassandra.h REQUIRED)
|
find_path(cassandra_includes NAMES cassandra.h REQUIRED)
|
||||||
target_link_libraries (reporting PUBLIC ${cassandra})
|
target_link_libraries (clio PUBLIC ${cassandra})
|
||||||
target_include_directories(reporting INTERFACE ${cassandra_includes})
|
target_include_directories(clio INTERFACE ${cassandra_includes})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <backend/PostgresBackend.h>
|
#include <backend/PostgresBackend.h>
|
||||||
|
|
||||||
namespace Backend {
|
namespace Backend {
|
||||||
std::unique_ptr<BackendInterface>
|
std::shared_ptr<BackendInterface>
|
||||||
make_Backend(boost::json::object const& config)
|
make_Backend(boost::json::object const& config)
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(info) << __func__ << ": Constructing BackendInterface";
|
BOOST_LOG_TRIVIAL(info) << __func__ << ": Constructing BackendInterface";
|
||||||
@@ -20,7 +20,7 @@ make_Backend(boost::json::object const& config)
|
|||||||
|
|
||||||
auto type = dbConfig.at("type").as_string();
|
auto type = dbConfig.at("type").as_string();
|
||||||
|
|
||||||
std::unique_ptr<BackendInterface> backend = nullptr;
|
std::shared_ptr<BackendInterface> backend = nullptr;
|
||||||
|
|
||||||
if (boost::iequals(type, "cassandra"))
|
if (boost::iequals(type, "cassandra"))
|
||||||
{
|
{
|
||||||
@@ -28,12 +28,12 @@ make_Backend(boost::json::object const& config)
|
|||||||
dbConfig.at(type).as_object()["ttl"] =
|
dbConfig.at(type).as_object()["ttl"] =
|
||||||
config.at("online_delete").as_int64() * 4;
|
config.at("online_delete").as_int64() * 4;
|
||||||
backend =
|
backend =
|
||||||
std::make_unique<CassandraBackend>(dbConfig.at(type).as_object());
|
std::make_shared<CassandraBackend>(dbConfig.at(type).as_object());
|
||||||
}
|
}
|
||||||
else if (boost::iequals(type, "postgres"))
|
else if (boost::iequals(type, "postgres"))
|
||||||
{
|
{
|
||||||
backend =
|
backend =
|
||||||
std::make_unique<PostgresBackend>(dbConfig.at(type).as_object());
|
std::make_shared<PostgresBackend>(dbConfig.at(type).as_object());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!backend)
|
if (!backend)
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <backend/BackendIndexer.h>
|
||||||
#include <backend/BackendInterface.h>
|
#include <backend/BackendInterface.h>
|
||||||
|
|
||||||
namespace Backend {
|
namespace Backend {
|
||||||
104
src/backend/BackendIndexer.h
Normal file
104
src/backend/BackendIndexer.h
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#ifndef CLIO_BACKEND_INDEXER_H_INCLUDED
|
||||||
|
#define CLIO_BACKEND_INDEXER_H_INCLUDED
|
||||||
|
#include <ripple/basics/base_uint.h>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/json.hpp>
|
||||||
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
|
#include <thread>
|
||||||
|
namespace std {
|
||||||
|
template <>
|
||||||
|
struct hash<ripple::uint256>
|
||||||
|
{
|
||||||
|
std::size_t
|
||||||
|
operator()(const ripple::uint256& k) const noexcept
|
||||||
|
{
|
||||||
|
return boost::hash_range(k.begin(), k.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace std
|
||||||
|
namespace Backend {
|
||||||
|
// The below two structs exist to prevent developers from accidentally mixing up
|
||||||
|
// the two indexes.
|
||||||
|
struct BookIndex
|
||||||
|
{
|
||||||
|
uint32_t bookIndex;
|
||||||
|
explicit BookIndex(uint32_t v) : bookIndex(v){};
|
||||||
|
};
|
||||||
|
struct KeyIndex
|
||||||
|
{
|
||||||
|
uint32_t keyIndex;
|
||||||
|
explicit KeyIndex(uint32_t v) : keyIndex(v){};
|
||||||
|
};
|
||||||
|
class BackendInterface;
|
||||||
|
class BackendIndexer
|
||||||
|
{
|
||||||
|
boost::asio::io_context ioc_;
|
||||||
|
boost::asio::io_context::strand strand_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
std::optional<boost::asio::io_context::work> work_;
|
||||||
|
std::thread ioThread_;
|
||||||
|
|
||||||
|
std::atomic_uint32_t indexing_ = 0;
|
||||||
|
|
||||||
|
uint32_t keyShift_ = 20;
|
||||||
|
std::unordered_set<ripple::uint256> keys;
|
||||||
|
|
||||||
|
mutable bool isFirst_ = true;
|
||||||
|
void
|
||||||
|
doKeysRepair(
|
||||||
|
BackendInterface const& backend,
|
||||||
|
std::optional<uint32_t> sequence);
|
||||||
|
void
|
||||||
|
writeKeyFlagLedger(
|
||||||
|
uint32_t ledgerSequence,
|
||||||
|
BackendInterface const& backend);
|
||||||
|
|
||||||
|
public:
|
||||||
|
BackendIndexer(boost::json::object const& config);
|
||||||
|
~BackendIndexer();
|
||||||
|
|
||||||
|
void
|
||||||
|
addKey(ripple::uint256&& key);
|
||||||
|
|
||||||
|
void
|
||||||
|
finish(uint32_t ledgerSequence, BackendInterface const& backend);
|
||||||
|
void
|
||||||
|
writeKeyFlagLedgerAsync(
|
||||||
|
uint32_t ledgerSequence,
|
||||||
|
BackendInterface const& backend);
|
||||||
|
void
|
||||||
|
doKeysRepairAsync(
|
||||||
|
BackendInterface const& backend,
|
||||||
|
std::optional<uint32_t> sequence);
|
||||||
|
uint32_t
|
||||||
|
getKeyShift()
|
||||||
|
{
|
||||||
|
return keyShift_;
|
||||||
|
}
|
||||||
|
std::optional<uint32_t>
|
||||||
|
getCurrentlyIndexing()
|
||||||
|
{
|
||||||
|
uint32_t cur = indexing_.load();
|
||||||
|
if (cur != 0)
|
||||||
|
return cur;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
KeyIndex
|
||||||
|
getKeyIndexOfSeq(uint32_t seq) const
|
||||||
|
{
|
||||||
|
if (isKeyFlagLedger(seq))
|
||||||
|
return KeyIndex{seq};
|
||||||
|
auto incr = (1 << keyShift_);
|
||||||
|
KeyIndex index{(seq >> keyShift_ << keyShift_) + incr};
|
||||||
|
assert(isKeyFlagLedger(index.keyIndex));
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
bool
|
||||||
|
isKeyFlagLedger(uint32_t ledgerSequence) const
|
||||||
|
{
|
||||||
|
return (ledgerSequence % (1 << keyShift_)) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace Backend
|
||||||
|
#endif
|
||||||
@@ -2,20 +2,17 @@
|
|||||||
#define RIPPLE_APP_REPORTING_BACKENDINTERFACE_H_INCLUDED
|
#define RIPPLE_APP_REPORTING_BACKENDINTERFACE_H_INCLUDED
|
||||||
#include <ripple/ledger/ReadView.h>
|
#include <ripple/ledger/ReadView.h>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
#include <backend/BackendIndexer.h>
|
||||||
#include <backend/DBHelpers.h>
|
#include <backend/DBHelpers.h>
|
||||||
namespace std {
|
class ReportingETL;
|
||||||
template <>
|
class AsyncCallData;
|
||||||
struct hash<ripple::uint256>
|
class BackendTest_Basic_Test;
|
||||||
{
|
|
||||||
std::size_t
|
|
||||||
operator()(const ripple::uint256& k) const noexcept
|
|
||||||
{
|
|
||||||
return boost::hash_range(k.begin(), k.end());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace std
|
|
||||||
namespace Backend {
|
namespace Backend {
|
||||||
|
|
||||||
|
// *** return types
|
||||||
|
|
||||||
using Blob = std::vector<unsigned char>;
|
using Blob = std::vector<unsigned char>;
|
||||||
|
|
||||||
struct LedgerObject
|
struct LedgerObject
|
||||||
{
|
{
|
||||||
ripple::uint256 key;
|
ripple::uint256 key;
|
||||||
@@ -55,19 +52,6 @@ struct LedgerRange
|
|||||||
uint32_t maxSequence;
|
uint32_t maxSequence;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The below two structs exist to prevent developers from accidentally mixing up
|
|
||||||
// the two indexes.
|
|
||||||
struct BookIndex
|
|
||||||
{
|
|
||||||
uint32_t bookIndex;
|
|
||||||
explicit BookIndex(uint32_t v) : bookIndex(v){};
|
|
||||||
};
|
|
||||||
struct KeyIndex
|
|
||||||
{
|
|
||||||
uint32_t keyIndex;
|
|
||||||
explicit KeyIndex(uint32_t v) : keyIndex(v){};
|
|
||||||
};
|
|
||||||
|
|
||||||
class DatabaseTimeout : public std::exception
|
class DatabaseTimeout : public std::exception
|
||||||
{
|
{
|
||||||
const char*
|
const char*
|
||||||
@@ -76,76 +60,6 @@ class DatabaseTimeout : public std::exception
|
|||||||
return "Database read timed out. Please retry the request";
|
return "Database read timed out. Please retry the request";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class BackendInterface;
|
|
||||||
class BackendIndexer
|
|
||||||
{
|
|
||||||
boost::asio::io_context ioc_;
|
|
||||||
boost::asio::io_context::strand strand_;
|
|
||||||
std::mutex mutex_;
|
|
||||||
std::optional<boost::asio::io_context::work> work_;
|
|
||||||
std::thread ioThread_;
|
|
||||||
|
|
||||||
std::atomic_uint32_t indexing_ = 0;
|
|
||||||
|
|
||||||
uint32_t keyShift_ = 20;
|
|
||||||
std::unordered_set<ripple::uint256> keys;
|
|
||||||
|
|
||||||
mutable bool isFirst_ = true;
|
|
||||||
void
|
|
||||||
doKeysRepair(
|
|
||||||
BackendInterface const& backend,
|
|
||||||
std::optional<uint32_t> sequence);
|
|
||||||
void
|
|
||||||
writeKeyFlagLedger(
|
|
||||||
uint32_t ledgerSequence,
|
|
||||||
BackendInterface const& backend);
|
|
||||||
|
|
||||||
public:
|
|
||||||
BackendIndexer(boost::json::object const& config);
|
|
||||||
~BackendIndexer();
|
|
||||||
|
|
||||||
void
|
|
||||||
addKey(ripple::uint256&& key);
|
|
||||||
|
|
||||||
void
|
|
||||||
finish(uint32_t ledgerSequence, BackendInterface const& backend);
|
|
||||||
void
|
|
||||||
writeKeyFlagLedgerAsync(
|
|
||||||
uint32_t ledgerSequence,
|
|
||||||
BackendInterface const& backend);
|
|
||||||
void
|
|
||||||
doKeysRepairAsync(
|
|
||||||
BackendInterface const& backend,
|
|
||||||
std::optional<uint32_t> sequence);
|
|
||||||
uint32_t
|
|
||||||
getKeyShift()
|
|
||||||
{
|
|
||||||
return keyShift_;
|
|
||||||
}
|
|
||||||
std::optional<uint32_t>
|
|
||||||
getCurrentlyIndexing()
|
|
||||||
{
|
|
||||||
uint32_t cur = indexing_.load();
|
|
||||||
if (cur != 0)
|
|
||||||
return cur;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
KeyIndex
|
|
||||||
getKeyIndexOfSeq(uint32_t seq) const
|
|
||||||
{
|
|
||||||
if (isKeyFlagLedger(seq))
|
|
||||||
return KeyIndex{seq};
|
|
||||||
auto incr = (1 << keyShift_);
|
|
||||||
KeyIndex index{(seq >> keyShift_ << keyShift_) + incr};
|
|
||||||
assert(isKeyFlagLedger(index.keyIndex));
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
bool
|
|
||||||
isKeyFlagLedger(uint32_t ledgerSequence) const
|
|
||||||
{
|
|
||||||
return (ledgerSequence % (1 << keyShift_)) == 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BackendInterface
|
class BackendInterface
|
||||||
{
|
{
|
||||||
@@ -154,10 +68,12 @@ protected:
|
|||||||
mutable bool isFirst_ = true;
|
mutable bool isFirst_ = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// read methods
|
|
||||||
BackendInterface(boost::json::object const& config) : indexer_(config)
|
BackendInterface(boost::json::object const& config) : indexer_(config)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
virtual ~BackendInterface()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
BackendIndexer&
|
BackendIndexer&
|
||||||
getIndexer() const
|
getIndexer() const
|
||||||
@@ -165,75 +81,34 @@ public:
|
|||||||
return indexer_;
|
return indexer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// *** public read methods ***
|
||||||
checkFlagLedgers() const;
|
// All of these reads methods can throw DatabaseTimeout. When writing code
|
||||||
|
// in an RPC handler, this exception does not need to be caught: when an RPC
|
||||||
std::optional<KeyIndex>
|
// results in a timeout, an error is returned to the client
|
||||||
getKeyIndexOfSeq(uint32_t seq) const;
|
public:
|
||||||
|
// *** ledger methods
|
||||||
bool
|
|
||||||
finishWrites(uint32_t ledgerSequence) const;
|
|
||||||
|
|
||||||
virtual std::optional<uint32_t>
|
|
||||||
fetchLatestLedgerSequence() const = 0;
|
|
||||||
|
|
||||||
virtual std::optional<ripple::LedgerInfo>
|
virtual std::optional<ripple::LedgerInfo>
|
||||||
fetchLedgerBySequence(uint32_t sequence) const = 0;
|
fetchLedgerBySequence(uint32_t sequence) const = 0;
|
||||||
|
|
||||||
|
virtual std::optional<uint32_t>
|
||||||
|
fetchLatestLedgerSequence() const = 0;
|
||||||
|
|
||||||
virtual std::optional<LedgerRange>
|
virtual std::optional<LedgerRange>
|
||||||
fetchLedgerRange() const = 0;
|
fetchLedgerRange() const = 0;
|
||||||
|
|
||||||
|
// Doesn't throw DatabaseTimeout. Should be used with care.
|
||||||
std::optional<LedgerRange>
|
std::optional<LedgerRange>
|
||||||
fetchLedgerRangeNoThrow() const;
|
fetchLedgerRangeNoThrow() const;
|
||||||
|
|
||||||
virtual std::optional<Blob>
|
// *** transaction methods
|
||||||
fetchLedgerObject(ripple::uint256 const& key, uint32_t sequence) const = 0;
|
|
||||||
|
|
||||||
// returns a transaction, metadata pair
|
|
||||||
virtual std::optional<TransactionAndMetadata>
|
virtual std::optional<TransactionAndMetadata>
|
||||||
fetchTransaction(ripple::uint256 const& hash) const = 0;
|
fetchTransaction(ripple::uint256 const& hash) const = 0;
|
||||||
|
|
||||||
virtual std::vector<TransactionAndMetadata>
|
|
||||||
fetchAllTransactionsInLedger(uint32_t ledgerSequence) const = 0;
|
|
||||||
|
|
||||||
virtual std::vector<ripple::uint256>
|
|
||||||
fetchAllTransactionHashesInLedger(uint32_t ledgerSequence) const = 0;
|
|
||||||
|
|
||||||
LedgerPage
|
|
||||||
fetchLedgerPage(
|
|
||||||
std::optional<ripple::uint256> const& cursor,
|
|
||||||
std::uint32_t ledgerSequence,
|
|
||||||
std::uint32_t limit,
|
|
||||||
std::uint32_t limitHint = 0) const;
|
|
||||||
|
|
||||||
bool
|
|
||||||
isLedgerIndexed(std::uint32_t ledgerSequence) const;
|
|
||||||
|
|
||||||
std::optional<LedgerObject>
|
|
||||||
fetchSuccessor(ripple::uint256 key, uint32_t ledgerSequence) const;
|
|
||||||
|
|
||||||
virtual LedgerPage
|
|
||||||
doFetchLedgerPage(
|
|
||||||
std::optional<ripple::uint256> const& cursor,
|
|
||||||
std::uint32_t ledgerSequence,
|
|
||||||
std::uint32_t limit) const = 0;
|
|
||||||
|
|
||||||
// TODO add warning for incomplete data
|
|
||||||
BookOffersPage
|
|
||||||
fetchBookOffers(
|
|
||||||
ripple::uint256 const& book,
|
|
||||||
uint32_t ledgerSequence,
|
|
||||||
std::uint32_t limit,
|
|
||||||
std::optional<ripple::uint256> const& cursor = {}) const;
|
|
||||||
|
|
||||||
virtual std::vector<TransactionAndMetadata>
|
virtual std::vector<TransactionAndMetadata>
|
||||||
fetchTransactions(std::vector<ripple::uint256> const& hashes) const = 0;
|
fetchTransactions(std::vector<ripple::uint256> const& hashes) const = 0;
|
||||||
|
|
||||||
virtual std::vector<Blob>
|
|
||||||
fetchLedgerObjects(
|
|
||||||
std::vector<ripple::uint256> const& keys,
|
|
||||||
uint32_t sequence) const = 0;
|
|
||||||
|
|
||||||
virtual std::pair<
|
virtual std::pair<
|
||||||
std::vector<TransactionAndMetadata>,
|
std::vector<TransactionAndMetadata>,
|
||||||
std::optional<AccountTransactionsCursor>>
|
std::optional<AccountTransactionsCursor>>
|
||||||
@@ -242,7 +117,58 @@ public:
|
|||||||
std::uint32_t limit,
|
std::uint32_t limit,
|
||||||
std::optional<AccountTransactionsCursor> const& cursor = {}) const = 0;
|
std::optional<AccountTransactionsCursor> const& cursor = {}) const = 0;
|
||||||
|
|
||||||
// write methods
|
virtual std::vector<TransactionAndMetadata>
|
||||||
|
fetchAllTransactionsInLedger(uint32_t ledgerSequence) const = 0;
|
||||||
|
|
||||||
|
virtual std::vector<ripple::uint256>
|
||||||
|
fetchAllTransactionHashesInLedger(uint32_t ledgerSequence) const = 0;
|
||||||
|
|
||||||
|
// *** state data methods
|
||||||
|
|
||||||
|
virtual std::optional<Blob>
|
||||||
|
fetchLedgerObject(ripple::uint256 const& key, uint32_t sequence) const = 0;
|
||||||
|
|
||||||
|
virtual std::vector<Blob>
|
||||||
|
fetchLedgerObjects(
|
||||||
|
std::vector<ripple::uint256> const& keys,
|
||||||
|
uint32_t sequence) const = 0;
|
||||||
|
|
||||||
|
// Fetches a page of ledger objects, ordered by key/index.
|
||||||
|
// Used by ledger_data
|
||||||
|
LedgerPage
|
||||||
|
fetchLedgerPage(
|
||||||
|
std::optional<ripple::uint256> const& cursor,
|
||||||
|
std::uint32_t ledgerSequence,
|
||||||
|
std::uint32_t limit,
|
||||||
|
std::uint32_t limitHint = 0) const;
|
||||||
|
|
||||||
|
// Fetches the successor to key/index. key need not actually be a valid
|
||||||
|
// key/index.
|
||||||
|
std::optional<LedgerObject>
|
||||||
|
fetchSuccessor(ripple::uint256 key, uint32_t ledgerSequence) const;
|
||||||
|
|
||||||
|
BookOffersPage
|
||||||
|
fetchBookOffers(
|
||||||
|
ripple::uint256 const& book,
|
||||||
|
uint32_t ledgerSequence,
|
||||||
|
std::uint32_t limit,
|
||||||
|
std::optional<ripple::uint256> const& cursor = {}) const;
|
||||||
|
|
||||||
|
// Methods related to the indexer
|
||||||
|
bool
|
||||||
|
isLedgerIndexed(std::uint32_t ledgerSequence) const;
|
||||||
|
|
||||||
|
std::optional<KeyIndex>
|
||||||
|
getKeyIndexOfSeq(uint32_t seq) const;
|
||||||
|
|
||||||
|
// *** protected write methods
|
||||||
|
protected:
|
||||||
|
friend class ::ReportingETL;
|
||||||
|
friend class BackendIndexer;
|
||||||
|
friend class ::AsyncCallData;
|
||||||
|
friend std::shared_ptr<BackendInterface>
|
||||||
|
make_Backend(boost::json::object const& config);
|
||||||
|
friend class ::BackendTest_Basic_Test;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
writeLedger(
|
writeLedger(
|
||||||
@@ -259,15 +185,6 @@ public:
|
|||||||
bool isDeleted,
|
bool isDeleted,
|
||||||
std::optional<ripple::uint256>&& book) const;
|
std::optional<ripple::uint256>&& book) const;
|
||||||
|
|
||||||
virtual void
|
|
||||||
doWriteLedgerObject(
|
|
||||||
std::string&& key,
|
|
||||||
uint32_t seq,
|
|
||||||
std::string&& blob,
|
|
||||||
bool isCreated,
|
|
||||||
bool isDeleted,
|
|
||||||
std::optional<ripple::uint256>&& book) const = 0;
|
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
writeTransaction(
|
writeTransaction(
|
||||||
std::string&& hash,
|
std::string&& hash,
|
||||||
@@ -279,7 +196,26 @@ public:
|
|||||||
writeAccountTransactions(
|
writeAccountTransactions(
|
||||||
std::vector<AccountTransactionsData>&& data) const = 0;
|
std::vector<AccountTransactionsData>&& data) const = 0;
|
||||||
|
|
||||||
// other database methods
|
// TODO: this function, or something similar, could be called internally by
|
||||||
|
// writeLedgerObject
|
||||||
|
virtual bool
|
||||||
|
writeKeys(
|
||||||
|
std::unordered_set<ripple::uint256> const& keys,
|
||||||
|
KeyIndex const& index,
|
||||||
|
bool isAsync = false) const = 0;
|
||||||
|
|
||||||
|
// Tell the database we are about to begin writing data for a particular
|
||||||
|
// ledger.
|
||||||
|
virtual void
|
||||||
|
startWrites() const = 0;
|
||||||
|
|
||||||
|
// Tell the database we have finished writing all data for a particular
|
||||||
|
// ledger
|
||||||
|
bool
|
||||||
|
finishWrites(uint32_t ledgerSequence) const;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
doOnlineDelete(uint32_t numLedgersToKeep) const = 0;
|
||||||
|
|
||||||
// Open the database. Set up all of the necessary objects and
|
// Open the database. Set up all of the necessary objects and
|
||||||
// datastructures. After this call completes, the database is ready for
|
// datastructures. After this call completes, the database is ready for
|
||||||
@@ -291,23 +227,28 @@ public:
|
|||||||
virtual void
|
virtual void
|
||||||
close() = 0;
|
close() = 0;
|
||||||
|
|
||||||
|
// *** private helper methods
|
||||||
|
private:
|
||||||
|
virtual LedgerPage
|
||||||
|
doFetchLedgerPage(
|
||||||
|
std::optional<ripple::uint256> const& cursor,
|
||||||
|
std::uint32_t ledgerSequence,
|
||||||
|
std::uint32_t limit) const = 0;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
startWrites() const = 0;
|
doWriteLedgerObject(
|
||||||
|
std::string&& key,
|
||||||
|
uint32_t seq,
|
||||||
|
std::string&& blob,
|
||||||
|
bool isCreated,
|
||||||
|
bool isDeleted,
|
||||||
|
std::optional<ripple::uint256>&& book) const = 0;
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
doFinishWrites() const = 0;
|
doFinishWrites() const = 0;
|
||||||
|
|
||||||
virtual bool
|
void
|
||||||
doOnlineDelete(uint32_t numLedgersToKeep) const = 0;
|
checkFlagLedgers() const;
|
||||||
virtual bool
|
|
||||||
writeKeys(
|
|
||||||
std::unordered_set<ripple::uint256> const& keys,
|
|
||||||
KeyIndex const& index,
|
|
||||||
bool isAsync = false) const = 0;
|
|
||||||
|
|
||||||
virtual ~BackendInterface()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Backend
|
} // namespace Backend
|
||||||
@@ -119,7 +119,7 @@ main(int argc, char* argv[])
|
|||||||
auto const config = parse_config(argv[1]);
|
auto const config = parse_config(argv[1]);
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
std::cerr << "Ccouldnt parse config. Exiting..." << std::endl;
|
std::cerr << "Couldnt parse config. Exiting..." << std::endl;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
initLogLevel(*config);
|
initLogLevel(*config);
|
||||||
@@ -133,24 +133,39 @@ main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(info) << "Number of workers = " << threads;
|
BOOST_LOG_TRIVIAL(info) << "Number of workers = " << threads;
|
||||||
|
|
||||||
|
// io context to handle all incoming requests, as well as other things
|
||||||
|
// This is not the only io context in the application
|
||||||
boost::asio::io_context ioc{threads};
|
boost::asio::io_context ioc{threads};
|
||||||
|
|
||||||
|
// Rate limiter, to prevent abuse
|
||||||
DOSGuard dosGuard{config.value(), ioc};
|
DOSGuard dosGuard{config.value(), ioc};
|
||||||
|
|
||||||
|
// Interface to the database
|
||||||
std::shared_ptr<BackendInterface> backend{Backend::make_Backend(*config)};
|
std::shared_ptr<BackendInterface> backend{Backend::make_Backend(*config)};
|
||||||
|
|
||||||
|
// Manages clients subscribed to streams
|
||||||
std::shared_ptr<SubscriptionManager> subscriptions{
|
std::shared_ptr<SubscriptionManager> subscriptions{
|
||||||
SubscriptionManager::make_SubscriptionManager()};
|
SubscriptionManager::make_SubscriptionManager()};
|
||||||
|
|
||||||
|
// Tracks which ledgers have been validated by the
|
||||||
|
// network
|
||||||
std::shared_ptr<NetworkValidatedLedgers> ledgers{
|
std::shared_ptr<NetworkValidatedLedgers> ledgers{
|
||||||
NetworkValidatedLedgers::make_ValidatedLedgers()};
|
NetworkValidatedLedgers::make_ValidatedLedgers()};
|
||||||
|
|
||||||
|
// Handles the connection to one or more rippled nodes.
|
||||||
|
// ETL uses the balancer to extract data.
|
||||||
|
// The server uses the balancer to forward RPCs to a rippled node.
|
||||||
|
// The balancer itself publishes to streams (transactions_proposed and
|
||||||
|
// accounts_proposed)
|
||||||
auto balancer = ETLLoadBalancer::make_ETLLoadBalancer(
|
auto balancer = ETLLoadBalancer::make_ETLLoadBalancer(
|
||||||
*config, ioc, backend, subscriptions, ledgers);
|
*config, ioc, backend, subscriptions, ledgers);
|
||||||
|
|
||||||
|
// ETL is responsible for writing and publishing to streams. In read-only
|
||||||
|
// mode, ETL only publishes
|
||||||
auto etl = ReportingETL::make_ReportingETL(
|
auto etl = ReportingETL::make_ReportingETL(
|
||||||
*config, ioc, backend, subscriptions, balancer, ledgers);
|
*config, ioc, backend, subscriptions, balancer, ledgers);
|
||||||
|
|
||||||
|
// The server handles incoming RPCs
|
||||||
auto httpServer = Server::make_HttpServer(
|
auto httpServer = Server::make_HttpServer(
|
||||||
*config, ioc, backend, subscriptions, balancer, dosGuard);
|
*config, ioc, backend, subscriptions, balancer, dosGuard);
|
||||||
|
|
||||||
4
test.py
4
test.py
@@ -681,7 +681,7 @@ import pathlib
|
|||||||
numCalls = 0
|
numCalls = 0
|
||||||
async def ledgers(ip, port, minLedger, maxLedger, transactions, expand, maxCalls):
|
async def ledgers(ip, port, minLedger, maxLedger, transactions, expand, maxCalls):
|
||||||
global numCalls
|
global numCalls
|
||||||
address = 'ws://' + str(ip) + ':' + str(port)
|
address = 'wss://' + str(ip) + ':' + str(port)
|
||||||
random.seed()
|
random.seed()
|
||||||
ledger = 0
|
ledger = 0
|
||||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||||
@@ -690,7 +690,7 @@ async def ledgers(ip, port, minLedger, maxLedger, transactions, expand, maxCalls
|
|||||||
ssl_context.check_hostname = False
|
ssl_context.check_hostname = False
|
||||||
ssl_context.verify_mode = ssl.CERT_NONE
|
ssl_context.verify_mode = ssl.CERT_NONE
|
||||||
try:
|
try:
|
||||||
async with websockets.connect(address,max_size=1000000000) as ws:
|
async with websockets.connect(address,max_size=1000000000,ssl=ssl_context) as ws:
|
||||||
global numCalls
|
global numCalls
|
||||||
for i in range(0, maxCalls):
|
for i in range(0, maxCalls):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user