mirror of
https://github.com/XRPLF/rippled.git
synced 2026-01-20 22:55:28 +00:00
Compare commits
5 Commits
develop
...
a1q123456/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea60898f6d | ||
|
|
a219e071f8 | ||
|
|
34b515e449 | ||
|
|
5ff7222230 | ||
|
|
1156fa261d |
@@ -65,6 +65,7 @@ test.core > test.toplevel
|
||||
test.core > test.unit_test
|
||||
test.core > xrpl.basics
|
||||
test.core > xrpl.core
|
||||
test.core > xrpld.app
|
||||
test.core > xrpld.core
|
||||
test.core > xrpl.json
|
||||
test.core > xrpl.server
|
||||
@@ -152,6 +153,8 @@ tests.libxrpl > xrpl.json
|
||||
tests.libxrpl > xrpl.net
|
||||
xrpl.core > xrpl.basics
|
||||
xrpl.core > xrpl.json
|
||||
xrpl.core > xrpl.ledger
|
||||
xrpl.core > xrpl.protocol
|
||||
xrpl.json > xrpl.basics
|
||||
xrpl.ledger > xrpl.basics
|
||||
xrpl.ledger > xrpl.protocol
|
||||
|
||||
207
include/xrpl/core/ServiceRegistry.h
Normal file
207
include/xrpl/core/ServiceRegistry.h
Normal file
@@ -0,0 +1,207 @@
|
||||
#ifndef XRPL_CORE_SERVICEREGISTRY_H_INCLUDED
|
||||
#define XRPL_CORE_SERVICEREGISTRY_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Blob.h>
|
||||
#include <xrpl/basics/SHAMapHash.h>
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/ledger/CachedSLEs.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Forward declarations
|
||||
namespace NodeStore {
|
||||
class Database;
|
||||
}
|
||||
namespace Resource {
|
||||
class Manager;
|
||||
}
|
||||
namespace perf {
|
||||
class PerfLog;
|
||||
}
|
||||
|
||||
class AcceptedLedger;
|
||||
class AmendmentTable;
|
||||
class Cluster;
|
||||
class CollectorManager;
|
||||
class DatabaseCon;
|
||||
class Family;
|
||||
class HashRouter;
|
||||
class InboundLedgers;
|
||||
class InboundTransactions;
|
||||
class JobQueue;
|
||||
class LedgerCleaner;
|
||||
class LedgerMaster;
|
||||
class LedgerReplayer;
|
||||
class LoadFeeTrack;
|
||||
class LoadManager;
|
||||
class ManifestCache;
|
||||
class NetworkOPs;
|
||||
class OpenLedger;
|
||||
class OrderBookDB;
|
||||
class Overlay;
|
||||
class PathRequests;
|
||||
class PeerReservationTable;
|
||||
class PendingSaves;
|
||||
class RelationalDatabase;
|
||||
class ServerHandler;
|
||||
class SHAMapStore;
|
||||
class TimeKeeper;
|
||||
class TransactionMaster;
|
||||
class TxQ;
|
||||
class ValidatorList;
|
||||
class ValidatorSite;
|
||||
|
||||
template <class Adaptor>
|
||||
class Validations;
|
||||
class RCLValidationsAdaptor;
|
||||
using RCLValidations = Validations<RCLValidationsAdaptor>;
|
||||
|
||||
using NodeCache = TaggedCache<SHAMapHash, Blob>;
|
||||
|
||||
/** Service registry for dependency injection.
|
||||
|
||||
This abstract interface provides access to various services and components
|
||||
used throughout the application. It separates the service locator pattern
|
||||
from the Application lifecycle management.
|
||||
|
||||
Components that need access to services can hold a reference to
|
||||
ServiceRegistry rather than Application when they only need service
|
||||
access and not lifecycle management.
|
||||
|
||||
The implementation (ServiceRegistryImpl) is provided in xrpld.
|
||||
*/
|
||||
class ServiceRegistry
|
||||
{
|
||||
public:
|
||||
ServiceRegistry() = default;
|
||||
virtual ~ServiceRegistry() = default;
|
||||
|
||||
// Core infrastructure services
|
||||
virtual CollectorManager&
|
||||
getCollectorManager() = 0;
|
||||
|
||||
virtual Family&
|
||||
getNodeFamily() = 0;
|
||||
|
||||
virtual TimeKeeper&
|
||||
timeKeeper() = 0;
|
||||
|
||||
virtual JobQueue&
|
||||
getJobQueue() = 0;
|
||||
|
||||
virtual NodeCache&
|
||||
getTempNodeCache() = 0;
|
||||
|
||||
virtual CachedSLEs&
|
||||
cachedSLEs() = 0;
|
||||
|
||||
// Protocol and validation services
|
||||
virtual AmendmentTable&
|
||||
getAmendmentTable() = 0;
|
||||
|
||||
virtual HashRouter&
|
||||
getHashRouter() = 0;
|
||||
|
||||
virtual LoadFeeTrack&
|
||||
getFeeTrack() = 0;
|
||||
|
||||
virtual LoadManager&
|
||||
getLoadManager() = 0;
|
||||
|
||||
virtual RCLValidations&
|
||||
getValidations() = 0;
|
||||
|
||||
virtual ValidatorList&
|
||||
validators() = 0;
|
||||
|
||||
virtual ValidatorSite&
|
||||
validatorSites() = 0;
|
||||
|
||||
virtual ManifestCache&
|
||||
validatorManifests() = 0;
|
||||
|
||||
virtual ManifestCache&
|
||||
publisherManifests() = 0;
|
||||
|
||||
// Network services
|
||||
virtual Overlay&
|
||||
overlay() = 0;
|
||||
|
||||
virtual Cluster&
|
||||
cluster() = 0;
|
||||
|
||||
virtual PeerReservationTable&
|
||||
peerReservations() = 0;
|
||||
|
||||
virtual Resource::Manager&
|
||||
getResourceManager() = 0;
|
||||
|
||||
// Storage services
|
||||
virtual NodeStore::Database&
|
||||
getNodeStore() = 0;
|
||||
|
||||
virtual SHAMapStore&
|
||||
getSHAMapStore() = 0;
|
||||
|
||||
virtual RelationalDatabase&
|
||||
getRelationalDatabase() = 0;
|
||||
|
||||
// Ledger services
|
||||
virtual InboundLedgers&
|
||||
getInboundLedgers() = 0;
|
||||
|
||||
virtual InboundTransactions&
|
||||
getInboundTransactions() = 0;
|
||||
|
||||
virtual TaggedCache<uint256, AcceptedLedger>&
|
||||
getAcceptedLedgerCache() = 0;
|
||||
|
||||
virtual LedgerMaster&
|
||||
getLedgerMaster() = 0;
|
||||
|
||||
virtual LedgerCleaner&
|
||||
getLedgerCleaner() = 0;
|
||||
|
||||
virtual LedgerReplayer&
|
||||
getLedgerReplayer() = 0;
|
||||
|
||||
virtual PendingSaves&
|
||||
pendingSaves() = 0;
|
||||
|
||||
virtual OpenLedger&
|
||||
openLedger() = 0;
|
||||
|
||||
virtual OpenLedger const&
|
||||
openLedger() const = 0;
|
||||
|
||||
// Transaction and operation services
|
||||
virtual NetworkOPs&
|
||||
getOPs() = 0;
|
||||
|
||||
virtual OrderBookDB&
|
||||
getOrderBookDB() = 0;
|
||||
|
||||
virtual TransactionMaster&
|
||||
getMasterTransaction() = 0;
|
||||
|
||||
virtual TxQ&
|
||||
getTxQ() = 0;
|
||||
|
||||
virtual PathRequests&
|
||||
getPathRequests() = 0;
|
||||
|
||||
// Server services
|
||||
virtual ServerHandler&
|
||||
getServerHandler() = 0;
|
||||
|
||||
virtual perf::PerfLog&
|
||||
getPerfLog() = 0;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
#endif
|
||||
704
src/test/core/ServiceRegistry_test.cpp
Normal file
704
src/test/core/ServiceRegistry_test.cpp
Normal file
@@ -0,0 +1,704 @@
|
||||
#include <test/jtx/Env.h>
|
||||
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/core/ServiceRegistryImpl.h>
|
||||
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
namespace xrpl {
|
||||
namespace test {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Mock Application that tracks which methods are called.
|
||||
|
||||
This class wraps a real Application instance and forwards all calls to it,
|
||||
while tracking which methods were invoked. This is useful for testing that
|
||||
ServiceRegistryImpl correctly delegates to the Application.
|
||||
*/
|
||||
class MockApplication : public Application
|
||||
{
|
||||
public:
|
||||
explicit MockApplication(Application& app) : app_(app)
|
||||
{
|
||||
}
|
||||
|
||||
// Tracking flags for methods called by ServiceRegistryImpl
|
||||
// They need to be mutable to allow modification from const methods
|
||||
mutable std::atomic<bool> getCollectorManagerCalled{false};
|
||||
mutable std::atomic<bool> getNodeFamilyCalled{false};
|
||||
mutable std::atomic<bool> timeKeeperCalled{false};
|
||||
mutable std::atomic<bool> getJobQueueCalled{false};
|
||||
mutable std::atomic<bool> getTempNodeCacheCalled{false};
|
||||
mutable std::atomic<bool> cachedSLEsCalled{false};
|
||||
mutable std::atomic<bool> getAmendmentTableCalled{false};
|
||||
mutable std::atomic<bool> getHashRouterCalled{false};
|
||||
mutable std::atomic<bool> getFeeTrackCalled{false};
|
||||
mutable std::atomic<bool> getLoadManagerCalled{false};
|
||||
mutable std::atomic<bool> getValidationsCalled{false};
|
||||
mutable std::atomic<bool> validatorsCalled{false};
|
||||
mutable std::atomic<bool> validatorSitesCalled{false};
|
||||
mutable std::atomic<bool> validatorManifestsCalled{false};
|
||||
mutable std::atomic<bool> publisherManifestsCalled{false};
|
||||
mutable std::atomic<bool> overlayCalled{false};
|
||||
mutable std::atomic<bool> clusterCalled{false};
|
||||
mutable std::atomic<bool> peerReservationsCalled{false};
|
||||
mutable std::atomic<bool> getResourceManagerCalled{false};
|
||||
mutable std::atomic<bool> getNodeStoreCalled{false};
|
||||
mutable std::atomic<bool> getSHAMapStoreCalled{false};
|
||||
mutable std::atomic<bool> getRelationalDatabaseCalled{false};
|
||||
mutable std::atomic<bool> getInboundLedgersCalled{false};
|
||||
mutable std::atomic<bool> getInboundTransactionsCalled{false};
|
||||
mutable std::atomic<bool> getAcceptedLedgerCacheCalled{false};
|
||||
mutable std::atomic<bool> getLedgerMasterCalled{false};
|
||||
mutable std::atomic<bool> getLedgerCleanerCalled{false};
|
||||
mutable std::atomic<bool> getLedgerReplayerCalled{false};
|
||||
mutable std::atomic<bool> pendingSavesCalled{false};
|
||||
mutable std::atomic<bool> openLedgerCalled{false};
|
||||
mutable std::atomic<bool> openLedgerConstCalled{false};
|
||||
mutable std::atomic<bool> getOPsCalled{false};
|
||||
mutable std::atomic<bool> getOrderBookDBCalled{false};
|
||||
mutable std::atomic<bool> getMasterTransactionCalled{false};
|
||||
mutable std::atomic<bool> getTxQCalled{false};
|
||||
mutable std::atomic<bool> getPathRequestsCalled{false};
|
||||
mutable std::atomic<bool> getServerHandlerCalled{false};
|
||||
mutable std::atomic<bool> getPerfLogCalled{false};
|
||||
|
||||
// Forward all Application methods to the real application
|
||||
MutexType&
|
||||
getMasterMutex() override
|
||||
{
|
||||
return app_.getMasterMutex();
|
||||
}
|
||||
|
||||
bool
|
||||
setup(boost::program_options::variables_map const& options) override
|
||||
{
|
||||
return app_.setup(options);
|
||||
}
|
||||
|
||||
void
|
||||
start(bool withTimers) override
|
||||
{
|
||||
app_.start(withTimers);
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
app_.run();
|
||||
}
|
||||
|
||||
void
|
||||
signalStop(std::string msg) override
|
||||
{
|
||||
app_.signalStop(std::move(msg));
|
||||
}
|
||||
|
||||
bool
|
||||
checkSigs() const override
|
||||
{
|
||||
return app_.checkSigs();
|
||||
}
|
||||
|
||||
void
|
||||
checkSigs(bool b) override
|
||||
{
|
||||
app_.checkSigs(b);
|
||||
}
|
||||
|
||||
bool
|
||||
isStopping() const override
|
||||
{
|
||||
return app_.isStopping();
|
||||
}
|
||||
|
||||
std::uint64_t
|
||||
instanceID() const override
|
||||
{
|
||||
return app_.instanceID();
|
||||
}
|
||||
|
||||
Logs&
|
||||
logs() override
|
||||
{
|
||||
return app_.logs();
|
||||
}
|
||||
|
||||
Config&
|
||||
config() override
|
||||
{
|
||||
return app_.config();
|
||||
}
|
||||
|
||||
boost::asio::io_context&
|
||||
getIOContext() override
|
||||
{
|
||||
return app_.getIOContext();
|
||||
}
|
||||
|
||||
CollectorManager&
|
||||
getCollectorManager() override
|
||||
{
|
||||
getCollectorManagerCalled = true;
|
||||
return app_.getCollectorManager();
|
||||
}
|
||||
|
||||
Family&
|
||||
getNodeFamily() override
|
||||
{
|
||||
getNodeFamilyCalled = true;
|
||||
return app_.getNodeFamily();
|
||||
}
|
||||
|
||||
TimeKeeper&
|
||||
timeKeeper() override
|
||||
{
|
||||
timeKeeperCalled = true;
|
||||
return app_.timeKeeper();
|
||||
}
|
||||
|
||||
JobQueue&
|
||||
getJobQueue() override
|
||||
{
|
||||
getJobQueueCalled = true;
|
||||
return app_.getJobQueue();
|
||||
}
|
||||
|
||||
NodeCache&
|
||||
getTempNodeCache() override
|
||||
{
|
||||
getTempNodeCacheCalled = true;
|
||||
return app_.getTempNodeCache();
|
||||
}
|
||||
|
||||
CachedSLEs&
|
||||
cachedSLEs() override
|
||||
{
|
||||
cachedSLEsCalled = true;
|
||||
return app_.cachedSLEs();
|
||||
}
|
||||
|
||||
AmendmentTable&
|
||||
getAmendmentTable() override
|
||||
{
|
||||
getAmendmentTableCalled = true;
|
||||
return app_.getAmendmentTable();
|
||||
}
|
||||
|
||||
HashRouter&
|
||||
getHashRouter() override
|
||||
{
|
||||
getHashRouterCalled = true;
|
||||
return app_.getHashRouter();
|
||||
}
|
||||
|
||||
LoadFeeTrack&
|
||||
getFeeTrack() override
|
||||
{
|
||||
getFeeTrackCalled = true;
|
||||
return app_.getFeeTrack();
|
||||
}
|
||||
|
||||
LoadManager&
|
||||
getLoadManager() override
|
||||
{
|
||||
getLoadManagerCalled = true;
|
||||
return app_.getLoadManager();
|
||||
}
|
||||
|
||||
Overlay&
|
||||
overlay() override
|
||||
{
|
||||
overlayCalled = true;
|
||||
return app_.overlay();
|
||||
}
|
||||
|
||||
TxQ&
|
||||
getTxQ() override
|
||||
{
|
||||
getTxQCalled = true;
|
||||
return app_.getTxQ();
|
||||
}
|
||||
|
||||
ValidatorList&
|
||||
validators() override
|
||||
{
|
||||
validatorsCalled = true;
|
||||
return app_.validators();
|
||||
}
|
||||
|
||||
ValidatorSite&
|
||||
validatorSites() override
|
||||
{
|
||||
validatorSitesCalled = true;
|
||||
return app_.validatorSites();
|
||||
}
|
||||
|
||||
ManifestCache&
|
||||
validatorManifests() override
|
||||
{
|
||||
validatorManifestsCalled = true;
|
||||
return app_.validatorManifests();
|
||||
}
|
||||
|
||||
ManifestCache&
|
||||
publisherManifests() override
|
||||
{
|
||||
publisherManifestsCalled = true;
|
||||
return app_.publisherManifests();
|
||||
}
|
||||
|
||||
Cluster&
|
||||
cluster() override
|
||||
{
|
||||
clusterCalled = true;
|
||||
return app_.cluster();
|
||||
}
|
||||
|
||||
PeerReservationTable&
|
||||
peerReservations() override
|
||||
{
|
||||
peerReservationsCalled = true;
|
||||
return app_.peerReservations();
|
||||
}
|
||||
|
||||
RCLValidations&
|
||||
getValidations() override
|
||||
{
|
||||
getValidationsCalled = true;
|
||||
return app_.getValidations();
|
||||
}
|
||||
|
||||
NodeStore::Database&
|
||||
getNodeStore() override
|
||||
{
|
||||
getNodeStoreCalled = true;
|
||||
return app_.getNodeStore();
|
||||
}
|
||||
|
||||
InboundLedgers&
|
||||
getInboundLedgers() override
|
||||
{
|
||||
getInboundLedgersCalled = true;
|
||||
return app_.getInboundLedgers();
|
||||
}
|
||||
|
||||
InboundTransactions&
|
||||
getInboundTransactions() override
|
||||
{
|
||||
getInboundTransactionsCalled = true;
|
||||
return app_.getInboundTransactions();
|
||||
}
|
||||
|
||||
TaggedCache<uint256, AcceptedLedger>&
|
||||
getAcceptedLedgerCache() override
|
||||
{
|
||||
getAcceptedLedgerCacheCalled = true;
|
||||
return app_.getAcceptedLedgerCache();
|
||||
}
|
||||
|
||||
LedgerMaster&
|
||||
getLedgerMaster() override
|
||||
{
|
||||
getLedgerMasterCalled = true;
|
||||
return app_.getLedgerMaster();
|
||||
}
|
||||
|
||||
LedgerCleaner&
|
||||
getLedgerCleaner() override
|
||||
{
|
||||
getLedgerCleanerCalled = true;
|
||||
return app_.getLedgerCleaner();
|
||||
}
|
||||
|
||||
LedgerReplayer&
|
||||
getLedgerReplayer() override
|
||||
{
|
||||
getLedgerReplayerCalled = true;
|
||||
return app_.getLedgerReplayer();
|
||||
}
|
||||
|
||||
NetworkOPs&
|
||||
getOPs() override
|
||||
{
|
||||
getOPsCalled = true;
|
||||
return app_.getOPs();
|
||||
}
|
||||
|
||||
OrderBookDB&
|
||||
getOrderBookDB() override
|
||||
{
|
||||
getOrderBookDBCalled = true;
|
||||
return app_.getOrderBookDB();
|
||||
}
|
||||
|
||||
ServerHandler&
|
||||
getServerHandler() override
|
||||
{
|
||||
getServerHandlerCalled = true;
|
||||
return app_.getServerHandler();
|
||||
}
|
||||
|
||||
TransactionMaster&
|
||||
getMasterTransaction() override
|
||||
{
|
||||
getMasterTransactionCalled = true;
|
||||
return app_.getMasterTransaction();
|
||||
}
|
||||
|
||||
perf::PerfLog&
|
||||
getPerfLog() override
|
||||
{
|
||||
getPerfLogCalled = true;
|
||||
return app_.getPerfLog();
|
||||
}
|
||||
|
||||
std::pair<PublicKey, SecretKey> const&
|
||||
nodeIdentity() override
|
||||
{
|
||||
return app_.nodeIdentity();
|
||||
}
|
||||
|
||||
std::optional<PublicKey const>
|
||||
getValidationPublicKey() const override
|
||||
{
|
||||
return app_.getValidationPublicKey();
|
||||
}
|
||||
|
||||
Resource::Manager&
|
||||
getResourceManager() override
|
||||
{
|
||||
getResourceManagerCalled = true;
|
||||
return app_.getResourceManager();
|
||||
}
|
||||
|
||||
PathRequests&
|
||||
getPathRequests() override
|
||||
{
|
||||
getPathRequestsCalled = true;
|
||||
return app_.getPathRequests();
|
||||
}
|
||||
|
||||
SHAMapStore&
|
||||
getSHAMapStore() override
|
||||
{
|
||||
getSHAMapStoreCalled = true;
|
||||
return app_.getSHAMapStore();
|
||||
}
|
||||
|
||||
PendingSaves&
|
||||
pendingSaves() override
|
||||
{
|
||||
pendingSavesCalled = true;
|
||||
return app_.pendingSaves();
|
||||
}
|
||||
|
||||
OpenLedger&
|
||||
openLedger() override
|
||||
{
|
||||
openLedgerCalled = true;
|
||||
return app_.openLedger();
|
||||
}
|
||||
|
||||
OpenLedger const&
|
||||
openLedger() const override
|
||||
{
|
||||
openLedgerConstCalled = true;
|
||||
return app_.openLedger();
|
||||
}
|
||||
|
||||
RelationalDatabase&
|
||||
getRelationalDatabase() override
|
||||
{
|
||||
getRelationalDatabaseCalled = true;
|
||||
return app_.getRelationalDatabase();
|
||||
}
|
||||
|
||||
std::chrono::milliseconds
|
||||
getIOLatency() override
|
||||
{
|
||||
return app_.getIOLatency();
|
||||
}
|
||||
|
||||
bool
|
||||
serverOkay(std::string& reason) override
|
||||
{
|
||||
return app_.serverOkay(reason);
|
||||
}
|
||||
|
||||
beast::Journal
|
||||
journal(std::string const& name) override
|
||||
{
|
||||
return app_.journal(name);
|
||||
}
|
||||
|
||||
int
|
||||
fdRequired() const override
|
||||
{
|
||||
return app_.fdRequired();
|
||||
}
|
||||
|
||||
DatabaseCon&
|
||||
getWalletDB() override
|
||||
{
|
||||
return app_.getWalletDB();
|
||||
}
|
||||
|
||||
LedgerIndex
|
||||
getMaxDisallowedLedger() override
|
||||
{
|
||||
return app_.getMaxDisallowedLedger();
|
||||
}
|
||||
|
||||
std::optional<uint256> const&
|
||||
trapTxID() const override
|
||||
{
|
||||
return app_.trapTxID();
|
||||
}
|
||||
|
||||
ServiceRegistry&
|
||||
getServiceRegistry() override
|
||||
{
|
||||
return app_.getServiceRegistry();
|
||||
}
|
||||
|
||||
void
|
||||
onWrite(beast::PropertyStream::Map& stream) override
|
||||
{
|
||||
app_.onWrite(stream);
|
||||
}
|
||||
|
||||
private:
|
||||
Application& app_;
|
||||
};
|
||||
|
||||
class ServiceRegistry_test : public beast::unit_test::suite
|
||||
{
|
||||
void
|
||||
testGetServices()
|
||||
{
|
||||
testcase("Get Services");
|
||||
|
||||
jtx::Env env{*this};
|
||||
MockApplication mockApp{env.app()};
|
||||
ServiceRegistryImpl registry(mockApp);
|
||||
|
||||
// Test core infrastructure services
|
||||
registry.getCollectorManager();
|
||||
BEAST_EXPECT(mockApp.getCollectorManagerCalled);
|
||||
|
||||
registry.getNodeFamily();
|
||||
BEAST_EXPECT(mockApp.getNodeFamilyCalled);
|
||||
|
||||
registry.timeKeeper();
|
||||
BEAST_EXPECT(mockApp.timeKeeperCalled);
|
||||
|
||||
registry.getJobQueue();
|
||||
BEAST_EXPECT(mockApp.getJobQueueCalled);
|
||||
|
||||
registry.getTempNodeCache();
|
||||
BEAST_EXPECT(mockApp.getTempNodeCacheCalled);
|
||||
|
||||
registry.cachedSLEs();
|
||||
BEAST_EXPECT(mockApp.cachedSLEsCalled);
|
||||
|
||||
// Test protocol and validation services
|
||||
registry.getAmendmentTable();
|
||||
BEAST_EXPECT(mockApp.getAmendmentTableCalled);
|
||||
|
||||
registry.getHashRouter();
|
||||
BEAST_EXPECT(mockApp.getHashRouterCalled);
|
||||
|
||||
registry.getFeeTrack();
|
||||
BEAST_EXPECT(mockApp.getFeeTrackCalled);
|
||||
|
||||
registry.getLoadManager();
|
||||
BEAST_EXPECT(mockApp.getLoadManagerCalled);
|
||||
|
||||
registry.getValidations();
|
||||
BEAST_EXPECT(mockApp.getValidationsCalled);
|
||||
|
||||
registry.validators();
|
||||
BEAST_EXPECT(mockApp.validatorsCalled);
|
||||
|
||||
registry.validatorSites();
|
||||
BEAST_EXPECT(mockApp.validatorSitesCalled);
|
||||
|
||||
registry.validatorManifests();
|
||||
BEAST_EXPECT(mockApp.validatorManifestsCalled);
|
||||
|
||||
registry.publisherManifests();
|
||||
BEAST_EXPECT(mockApp.publisherManifestsCalled);
|
||||
|
||||
// Test network services
|
||||
registry.overlay();
|
||||
BEAST_EXPECT(mockApp.overlayCalled);
|
||||
|
||||
registry.cluster();
|
||||
BEAST_EXPECT(mockApp.clusterCalled);
|
||||
|
||||
registry.peerReservations();
|
||||
BEAST_EXPECT(mockApp.peerReservationsCalled);
|
||||
|
||||
registry.getResourceManager();
|
||||
BEAST_EXPECT(mockApp.getResourceManagerCalled);
|
||||
|
||||
// Test storage services
|
||||
registry.getNodeStore();
|
||||
BEAST_EXPECT(mockApp.getNodeStoreCalled);
|
||||
|
||||
registry.getSHAMapStore();
|
||||
BEAST_EXPECT(mockApp.getSHAMapStoreCalled);
|
||||
|
||||
registry.getRelationalDatabase();
|
||||
BEAST_EXPECT(mockApp.getRelationalDatabaseCalled);
|
||||
|
||||
// Test ledger services
|
||||
registry.getInboundLedgers();
|
||||
BEAST_EXPECT(mockApp.getInboundLedgersCalled);
|
||||
|
||||
registry.getInboundTransactions();
|
||||
BEAST_EXPECT(mockApp.getInboundTransactionsCalled);
|
||||
|
||||
registry.getAcceptedLedgerCache();
|
||||
BEAST_EXPECT(mockApp.getAcceptedLedgerCacheCalled);
|
||||
|
||||
registry.getLedgerMaster();
|
||||
BEAST_EXPECT(mockApp.getLedgerMasterCalled);
|
||||
|
||||
registry.getLedgerCleaner();
|
||||
BEAST_EXPECT(mockApp.getLedgerCleanerCalled);
|
||||
|
||||
registry.getLedgerReplayer();
|
||||
BEAST_EXPECT(mockApp.getLedgerReplayerCalled);
|
||||
|
||||
registry.pendingSaves();
|
||||
BEAST_EXPECT(mockApp.pendingSavesCalled);
|
||||
|
||||
registry.openLedger();
|
||||
BEAST_EXPECT(mockApp.openLedgerCalled);
|
||||
|
||||
// Test const version of openLedger
|
||||
ServiceRegistryImpl const& constRegistry = registry;
|
||||
constRegistry.openLedger();
|
||||
BEAST_EXPECT(mockApp.openLedgerConstCalled);
|
||||
|
||||
// Test transaction and operation services
|
||||
registry.getOPs();
|
||||
BEAST_EXPECT(mockApp.getOPsCalled);
|
||||
|
||||
registry.getOrderBookDB();
|
||||
BEAST_EXPECT(mockApp.getOrderBookDBCalled);
|
||||
|
||||
registry.getMasterTransaction();
|
||||
BEAST_EXPECT(mockApp.getMasterTransactionCalled);
|
||||
|
||||
registry.getTxQ();
|
||||
BEAST_EXPECT(mockApp.getTxQCalled);
|
||||
|
||||
registry.getPathRequests();
|
||||
BEAST_EXPECT(mockApp.getPathRequestsCalled);
|
||||
|
||||
// Test server services
|
||||
registry.getServerHandler();
|
||||
BEAST_EXPECT(mockApp.getServerHandlerCalled);
|
||||
|
||||
registry.getPerfLog();
|
||||
BEAST_EXPECT(mockApp.getPerfLogCalled);
|
||||
}
|
||||
|
||||
void
|
||||
testServicesIdentical()
|
||||
{
|
||||
testcase("Services Identical");
|
||||
|
||||
jtx::Env env{*this};
|
||||
auto& app = env.app();
|
||||
auto& registry = app.getServiceRegistry();
|
||||
|
||||
// Test core infrastructure services
|
||||
BEAST_EXPECT(
|
||||
&app.getCollectorManager() == ®istry.getCollectorManager());
|
||||
BEAST_EXPECT(&app.getNodeFamily() == ®istry.getNodeFamily());
|
||||
BEAST_EXPECT(&app.timeKeeper() == ®istry.timeKeeper());
|
||||
BEAST_EXPECT(&app.getJobQueue() == ®istry.getJobQueue());
|
||||
BEAST_EXPECT(&app.getTempNodeCache() == ®istry.getTempNodeCache());
|
||||
BEAST_EXPECT(&app.cachedSLEs() == ®istry.cachedSLEs());
|
||||
|
||||
// Test protocol and validation services
|
||||
BEAST_EXPECT(&app.getAmendmentTable() == ®istry.getAmendmentTable());
|
||||
BEAST_EXPECT(&app.getHashRouter() == ®istry.getHashRouter());
|
||||
BEAST_EXPECT(&app.getFeeTrack() == ®istry.getFeeTrack());
|
||||
BEAST_EXPECT(&app.getLoadManager() == ®istry.getLoadManager());
|
||||
BEAST_EXPECT(&app.getValidations() == ®istry.getValidations());
|
||||
BEAST_EXPECT(&app.validators() == ®istry.validators());
|
||||
BEAST_EXPECT(&app.validatorSites() == ®istry.validatorSites());
|
||||
BEAST_EXPECT(
|
||||
&app.validatorManifests() == ®istry.validatorManifests());
|
||||
BEAST_EXPECT(
|
||||
&app.publisherManifests() == ®istry.publisherManifests());
|
||||
|
||||
// Test network services
|
||||
BEAST_EXPECT(&app.overlay() == ®istry.overlay());
|
||||
BEAST_EXPECT(&app.cluster() == ®istry.cluster());
|
||||
BEAST_EXPECT(&app.peerReservations() == ®istry.peerReservations());
|
||||
BEAST_EXPECT(
|
||||
&app.getResourceManager() == ®istry.getResourceManager());
|
||||
|
||||
// Test storage services
|
||||
BEAST_EXPECT(&app.getNodeStore() == ®istry.getNodeStore());
|
||||
BEAST_EXPECT(&app.getSHAMapStore() == ®istry.getSHAMapStore());
|
||||
BEAST_EXPECT(
|
||||
&app.getRelationalDatabase() == ®istry.getRelationalDatabase());
|
||||
|
||||
// Test ledger services
|
||||
BEAST_EXPECT(&app.getInboundLedgers() == ®istry.getInboundLedgers());
|
||||
BEAST_EXPECT(
|
||||
&app.getInboundTransactions() ==
|
||||
®istry.getInboundTransactions());
|
||||
BEAST_EXPECT(
|
||||
&app.getAcceptedLedgerCache() ==
|
||||
®istry.getAcceptedLedgerCache());
|
||||
BEAST_EXPECT(&app.getLedgerMaster() == ®istry.getLedgerMaster());
|
||||
BEAST_EXPECT(&app.getLedgerCleaner() == ®istry.getLedgerCleaner());
|
||||
BEAST_EXPECT(&app.getLedgerReplayer() == ®istry.getLedgerReplayer());
|
||||
BEAST_EXPECT(&app.pendingSaves() == ®istry.pendingSaves());
|
||||
BEAST_EXPECT(&app.openLedger() == ®istry.openLedger());
|
||||
|
||||
// Test const version of openLedger
|
||||
auto const& constApp = app;
|
||||
auto const& constRegistry = registry;
|
||||
BEAST_EXPECT(&constApp.openLedger() == &constRegistry.openLedger());
|
||||
|
||||
// Test transaction and operation services
|
||||
BEAST_EXPECT(&app.getOPs() == ®istry.getOPs());
|
||||
BEAST_EXPECT(&app.getOrderBookDB() == ®istry.getOrderBookDB());
|
||||
BEAST_EXPECT(
|
||||
&app.getMasterTransaction() == ®istry.getMasterTransaction());
|
||||
BEAST_EXPECT(&app.getTxQ() == ®istry.getTxQ());
|
||||
BEAST_EXPECT(&app.getPathRequests() == ®istry.getPathRequests());
|
||||
|
||||
// Test server services
|
||||
BEAST_EXPECT(&app.getServerHandler() == ®istry.getServerHandler());
|
||||
BEAST_EXPECT(&app.getPerfLog() == ®istry.getPerfLog());
|
||||
}
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
{
|
||||
testGetServices();
|
||||
testServicesIdentical();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(ServiceRegistry, core, xrpl);
|
||||
|
||||
} // namespace test
|
||||
} // namespace xrpl
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
#include <xrpld/app/tx/apply.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/core/ServiceRegistryImpl.h>
|
||||
#include <xrpld/overlay/Cluster.h>
|
||||
#include <xrpld/overlay/PeerReservationTable.h>
|
||||
#include <xrpld/overlay/PeerSet.h>
|
||||
@@ -217,6 +218,9 @@ public:
|
||||
|
||||
std::unique_ptr<GRPCServer> grpcServer_;
|
||||
|
||||
// ServiceRegistry implementation that delegates to this Application
|
||||
std::unique_ptr<ServiceRegistryImpl> serviceRegistry_;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
static std::size_t
|
||||
@@ -453,6 +457,7 @@ public:
|
||||
std::chrono::milliseconds(100),
|
||||
get_io_context())
|
||||
, grpcServer_(std::make_unique<GRPCServer>(*this))
|
||||
, serviceRegistry_(std::make_unique<ServiceRegistryImpl>(*this))
|
||||
{
|
||||
initAccountIdCache(config_->getValueFor(SizedItem::accountIdCacheSize));
|
||||
|
||||
@@ -808,6 +813,16 @@ public:
|
||||
return *mWalletDB;
|
||||
}
|
||||
|
||||
ServiceRegistry&
|
||||
getServiceRegistry() override
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
serviceRegistry_,
|
||||
"xrpl::ApplicationImp::getServiceRegistry : non-null service "
|
||||
"registry");
|
||||
return *serviceRegistry_;
|
||||
}
|
||||
|
||||
bool
|
||||
serverOkay(std::string& reason) override;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/beast/utility/PropertyStream.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/shamap/TreeNodeCache.h>
|
||||
|
||||
@@ -256,6 +257,9 @@ public:
|
||||
|
||||
virtual std::optional<uint256> const&
|
||||
trapTxID() const = 0;
|
||||
|
||||
virtual ServiceRegistry&
|
||||
getServiceRegistry() = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<Application>
|
||||
|
||||
157
src/xrpld/core/ServiceRegistryImpl.h
Normal file
157
src/xrpld/core/ServiceRegistryImpl.h
Normal file
@@ -0,0 +1,157 @@
|
||||
#ifndef XRPLD_CORE_SERVICEREGISTRYIMPL_H_INCLUDED
|
||||
#define XRPLD_CORE_SERVICEREGISTRYIMPL_H_INCLUDED
|
||||
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Forward declaration
|
||||
class Application;
|
||||
|
||||
/** Implementation of ServiceRegistry that delegates to Application.
|
||||
|
||||
This class provides a ServiceRegistry interface that wraps an Application
|
||||
reference. It allows components to depend on ServiceRegistry instead of
|
||||
Application, enabling gradual migration and better separation of concerns.
|
||||
|
||||
Usage:
|
||||
Application& app = ...;
|
||||
ServiceRegistry& registry = app.getServiceRegistry();
|
||||
// or
|
||||
ServiceRegistryImpl registry(app);
|
||||
*/
|
||||
class ServiceRegistryImpl : public ServiceRegistry
|
||||
{
|
||||
public:
|
||||
explicit ServiceRegistryImpl(Application& app);
|
||||
|
||||
~ServiceRegistryImpl() override = default;
|
||||
|
||||
// Core infrastructure services
|
||||
CollectorManager&
|
||||
getCollectorManager() override;
|
||||
|
||||
Family&
|
||||
getNodeFamily() override;
|
||||
|
||||
TimeKeeper&
|
||||
timeKeeper() override;
|
||||
|
||||
JobQueue&
|
||||
getJobQueue() override;
|
||||
|
||||
NodeCache&
|
||||
getTempNodeCache() override;
|
||||
|
||||
CachedSLEs&
|
||||
cachedSLEs() override;
|
||||
|
||||
// Protocol and validation services
|
||||
AmendmentTable&
|
||||
getAmendmentTable() override;
|
||||
|
||||
HashRouter&
|
||||
getHashRouter() override;
|
||||
|
||||
LoadFeeTrack&
|
||||
getFeeTrack() override;
|
||||
|
||||
LoadManager&
|
||||
getLoadManager() override;
|
||||
|
||||
RCLValidations&
|
||||
getValidations() override;
|
||||
|
||||
ValidatorList&
|
||||
validators() override;
|
||||
|
||||
ValidatorSite&
|
||||
validatorSites() override;
|
||||
|
||||
ManifestCache&
|
||||
validatorManifests() override;
|
||||
|
||||
ManifestCache&
|
||||
publisherManifests() override;
|
||||
|
||||
// Network services
|
||||
Overlay&
|
||||
overlay() override;
|
||||
|
||||
Cluster&
|
||||
cluster() override;
|
||||
|
||||
PeerReservationTable&
|
||||
peerReservations() override;
|
||||
|
||||
Resource::Manager&
|
||||
getResourceManager() override;
|
||||
|
||||
// Storage services
|
||||
NodeStore::Database&
|
||||
getNodeStore() override;
|
||||
|
||||
SHAMapStore&
|
||||
getSHAMapStore() override;
|
||||
|
||||
RelationalDatabase&
|
||||
getRelationalDatabase() override;
|
||||
|
||||
// Ledger services
|
||||
InboundLedgers&
|
||||
getInboundLedgers() override;
|
||||
|
||||
InboundTransactions&
|
||||
getInboundTransactions() override;
|
||||
|
||||
TaggedCache<uint256, AcceptedLedger>&
|
||||
getAcceptedLedgerCache() override;
|
||||
|
||||
LedgerMaster&
|
||||
getLedgerMaster() override;
|
||||
|
||||
LedgerCleaner&
|
||||
getLedgerCleaner() override;
|
||||
|
||||
LedgerReplayer&
|
||||
getLedgerReplayer() override;
|
||||
|
||||
PendingSaves&
|
||||
pendingSaves() override;
|
||||
|
||||
OpenLedger&
|
||||
openLedger() override;
|
||||
|
||||
OpenLedger const&
|
||||
openLedger() const override;
|
||||
|
||||
// Transaction and operation services
|
||||
NetworkOPs&
|
||||
getOPs() override;
|
||||
|
||||
OrderBookDB&
|
||||
getOrderBookDB() override;
|
||||
|
||||
TransactionMaster&
|
||||
getMasterTransaction() override;
|
||||
|
||||
TxQ&
|
||||
getTxQ() override;
|
||||
|
||||
PathRequests&
|
||||
getPathRequests() override;
|
||||
|
||||
// Server services
|
||||
ServerHandler&
|
||||
getServerHandler() override;
|
||||
|
||||
perf::PerfLog&
|
||||
getPerfLog() override;
|
||||
|
||||
private:
|
||||
Application& app_;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
#endif
|
||||
246
src/xrpld/core/detail/ServiceRegistryImpl.cpp
Normal file
246
src/xrpld/core/detail/ServiceRegistryImpl.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/core/ServiceRegistryImpl.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
ServiceRegistryImpl::ServiceRegistryImpl(Application& app) : app_(app)
|
||||
{
|
||||
}
|
||||
|
||||
// Core infrastructure services
|
||||
CollectorManager&
|
||||
ServiceRegistryImpl::getCollectorManager()
|
||||
{
|
||||
return app_.getCollectorManager();
|
||||
}
|
||||
|
||||
Family&
|
||||
ServiceRegistryImpl::getNodeFamily()
|
||||
{
|
||||
return app_.getNodeFamily();
|
||||
}
|
||||
|
||||
TimeKeeper&
|
||||
ServiceRegistryImpl::timeKeeper()
|
||||
{
|
||||
return app_.timeKeeper();
|
||||
}
|
||||
|
||||
JobQueue&
|
||||
ServiceRegistryImpl::getJobQueue()
|
||||
{
|
||||
return app_.getJobQueue();
|
||||
}
|
||||
|
||||
NodeCache&
|
||||
ServiceRegistryImpl::getTempNodeCache()
|
||||
{
|
||||
return app_.getTempNodeCache();
|
||||
}
|
||||
|
||||
CachedSLEs&
|
||||
ServiceRegistryImpl::cachedSLEs()
|
||||
{
|
||||
return app_.cachedSLEs();
|
||||
}
|
||||
|
||||
// Protocol and validation services
|
||||
AmendmentTable&
|
||||
ServiceRegistryImpl::getAmendmentTable()
|
||||
{
|
||||
return app_.getAmendmentTable();
|
||||
}
|
||||
|
||||
HashRouter&
|
||||
ServiceRegistryImpl::getHashRouter()
|
||||
{
|
||||
return app_.getHashRouter();
|
||||
}
|
||||
|
||||
LoadFeeTrack&
|
||||
ServiceRegistryImpl::getFeeTrack()
|
||||
{
|
||||
return app_.getFeeTrack();
|
||||
}
|
||||
|
||||
LoadManager&
|
||||
ServiceRegistryImpl::getLoadManager()
|
||||
{
|
||||
return app_.getLoadManager();
|
||||
}
|
||||
|
||||
RCLValidations&
|
||||
ServiceRegistryImpl::getValidations()
|
||||
{
|
||||
return app_.getValidations();
|
||||
}
|
||||
|
||||
ValidatorList&
|
||||
ServiceRegistryImpl::validators()
|
||||
{
|
||||
return app_.validators();
|
||||
}
|
||||
|
||||
ValidatorSite&
|
||||
ServiceRegistryImpl::validatorSites()
|
||||
{
|
||||
return app_.validatorSites();
|
||||
}
|
||||
|
||||
ManifestCache&
|
||||
ServiceRegistryImpl::validatorManifests()
|
||||
{
|
||||
return app_.validatorManifests();
|
||||
}
|
||||
|
||||
ManifestCache&
|
||||
ServiceRegistryImpl::publisherManifests()
|
||||
{
|
||||
return app_.publisherManifests();
|
||||
}
|
||||
|
||||
// Network services
|
||||
Overlay&
|
||||
ServiceRegistryImpl::overlay()
|
||||
{
|
||||
return app_.overlay();
|
||||
}
|
||||
|
||||
Cluster&
|
||||
ServiceRegistryImpl::cluster()
|
||||
{
|
||||
return app_.cluster();
|
||||
}
|
||||
|
||||
PeerReservationTable&
|
||||
ServiceRegistryImpl::peerReservations()
|
||||
{
|
||||
return app_.peerReservations();
|
||||
}
|
||||
|
||||
Resource::Manager&
|
||||
ServiceRegistryImpl::getResourceManager()
|
||||
{
|
||||
return app_.getResourceManager();
|
||||
}
|
||||
|
||||
// Storage services
|
||||
NodeStore::Database&
|
||||
ServiceRegistryImpl::getNodeStore()
|
||||
{
|
||||
return app_.getNodeStore();
|
||||
}
|
||||
|
||||
SHAMapStore&
|
||||
ServiceRegistryImpl::getSHAMapStore()
|
||||
{
|
||||
return app_.getSHAMapStore();
|
||||
}
|
||||
|
||||
RelationalDatabase&
|
||||
ServiceRegistryImpl::getRelationalDatabase()
|
||||
{
|
||||
return app_.getRelationalDatabase();
|
||||
}
|
||||
|
||||
// Ledger services
|
||||
InboundLedgers&
|
||||
ServiceRegistryImpl::getInboundLedgers()
|
||||
{
|
||||
return app_.getInboundLedgers();
|
||||
}
|
||||
|
||||
InboundTransactions&
|
||||
ServiceRegistryImpl::getInboundTransactions()
|
||||
{
|
||||
return app_.getInboundTransactions();
|
||||
}
|
||||
|
||||
TaggedCache<uint256, AcceptedLedger>&
|
||||
ServiceRegistryImpl::getAcceptedLedgerCache()
|
||||
{
|
||||
return app_.getAcceptedLedgerCache();
|
||||
}
|
||||
|
||||
LedgerMaster&
|
||||
ServiceRegistryImpl::getLedgerMaster()
|
||||
{
|
||||
return app_.getLedgerMaster();
|
||||
}
|
||||
|
||||
LedgerCleaner&
|
||||
ServiceRegistryImpl::getLedgerCleaner()
|
||||
{
|
||||
return app_.getLedgerCleaner();
|
||||
}
|
||||
|
||||
LedgerReplayer&
|
||||
ServiceRegistryImpl::getLedgerReplayer()
|
||||
{
|
||||
return app_.getLedgerReplayer();
|
||||
}
|
||||
|
||||
PendingSaves&
|
||||
ServiceRegistryImpl::pendingSaves()
|
||||
{
|
||||
return app_.pendingSaves();
|
||||
}
|
||||
|
||||
OpenLedger&
|
||||
ServiceRegistryImpl::openLedger()
|
||||
{
|
||||
return app_.openLedger();
|
||||
}
|
||||
|
||||
OpenLedger const&
|
||||
ServiceRegistryImpl::openLedger() const
|
||||
{
|
||||
// We lose const-ness here because app_ is a reference.
|
||||
return const_cast<Application const&>(app_).openLedger();
|
||||
}
|
||||
|
||||
// Transaction and operation services
|
||||
NetworkOPs&
|
||||
ServiceRegistryImpl::getOPs()
|
||||
{
|
||||
return app_.getOPs();
|
||||
}
|
||||
|
||||
OrderBookDB&
|
||||
ServiceRegistryImpl::getOrderBookDB()
|
||||
{
|
||||
return app_.getOrderBookDB();
|
||||
}
|
||||
|
||||
TransactionMaster&
|
||||
ServiceRegistryImpl::getMasterTransaction()
|
||||
{
|
||||
return app_.getMasterTransaction();
|
||||
}
|
||||
|
||||
TxQ&
|
||||
ServiceRegistryImpl::getTxQ()
|
||||
{
|
||||
return app_.getTxQ();
|
||||
}
|
||||
|
||||
PathRequests&
|
||||
ServiceRegistryImpl::getPathRequests()
|
||||
{
|
||||
return app_.getPathRequests();
|
||||
}
|
||||
|
||||
// Server services
|
||||
ServerHandler&
|
||||
ServiceRegistryImpl::getServerHandler()
|
||||
{
|
||||
return app_.getServerHandler();
|
||||
}
|
||||
|
||||
perf::PerfLog&
|
||||
ServiceRegistryImpl::getPerfLog()
|
||||
{
|
||||
return app_.getPerfLog();
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
Reference in New Issue
Block a user