diff --git a/src/test/app/ValidatorSite_test.cpp b/src/test/app/ValidatorSite_test.cpp index 9ed0d994c9..9fc80c5a1f 100644 --- a/src/test/app/ValidatorSite_test.cpp +++ b/src/test/app/ValidatorSite_test.cpp @@ -164,7 +164,7 @@ private: publisher(FetchListConfig const& c) : cfg{c} { } - std::unique_ptr server; + std::shared_ptr server; std::vector list; std::string uri; FetchListConfig const& cfg; @@ -184,7 +184,7 @@ private: while (item.list.size() < listSize) item.list.push_back(TrustedPublisherServer::randomValidator()); - item.server = std::make_unique( + item.server = make_TrustedPublisherServer( env.app().getIOService(), item.list, env.timeKeeper().now() + cfg.expiresFromNow, diff --git a/src/test/jtx/TrustedPublisherServer.h b/src/test/jtx/TrustedPublisherServer.h index 6d6e27ff3f..ada2bb53ee 100644 --- a/src/test/jtx/TrustedPublisherServer.h +++ b/src/test/jtx/TrustedPublisherServer.h @@ -34,12 +34,15 @@ #include #include #include + +#include #include namespace ripple { namespace test { class TrustedPublisherServer + : public std::enable_shared_from_this { using endpoint_type = boost::asio::ip::tcp::endpoint; using address_type = boost::asio::ip::address; @@ -141,6 +144,10 @@ public: 1)}; } + // TrustedPublisherServer must be accessed through a shared_ptr + // This constructor is only public so std::make_shared has access. + // The function`make_TrustedPublisherServer` should be used to create + // instances. TrustedPublisherServer( boost::asio::io_context& ioc, std::vector const& validators, @@ -192,9 +199,6 @@ public: // This holds the self-signed certificate used by the server load_server_certificate(); } - - if (immediateStart) - start(); } void @@ -208,10 +212,13 @@ public: acceptor_.listen(boost::asio::socket_base::max_connections); acceptor_.async_accept( sock_, - std::bind( - &TrustedPublisherServer::on_accept, - this, - std::placeholders::_1)); + [wp = std::weak_ptr{shared_from_this()}]( + error_code ec) { + if (auto p = wp.lock()) + { + p->on_accept(ec); + } + }); } void @@ -442,8 +449,6 @@ private: void on_accept(error_code ec) { - // ec must be checked before `acceptor_` or the member variable may be - // accessed after the destructor has completed if (ec || !acceptor_.is_open()) return; @@ -451,10 +456,13 @@ private: std::thread{lambda{++id_, *this, std::move(sock_), useSSL_}}.detach(); acceptor_.async_accept( sock_, - std::bind( - &TrustedPublisherServer::on_accept, - this, - std::placeholders::_1)); + [wp = std::weak_ptr{shared_from_this()}]( + error_code ec) { + if (auto p = wp.lock()) + { + p->on_accept(ec); + } + }); } void @@ -606,6 +614,23 @@ private: } }; +inline std::shared_ptr +make_TrustedPublisherServer( + boost::asio::io_context& ioc, + std::vector const& validators, + NetClock::time_point expiration, + bool useSSL = false, + int version = 1, + bool immediateStart = true, + int sequence = 1) +{ + auto const r = std::make_shared( + ioc, validators, expiration, useSSL, version, sequence); + if (immediateStart) + r->start(); + return r; +} + } // namespace test } // namespace ripple #endif diff --git a/src/test/net/DatabaseDownloader_test.cpp b/src/test/net/DatabaseDownloader_test.cpp index b81485a228..6333add3fe 100644 --- a/src/test/net/DatabaseDownloader_test.cpp +++ b/src/test/net/DatabaseDownloader_test.cpp @@ -31,16 +31,16 @@ namespace test { class DatabaseDownloader_test : public beast::unit_test::suite { - TrustedPublisherServer + std::shared_ptr createServer(jtx::Env& env, bool ssl = true) { std::vector list; list.push_back(TrustedPublisherServer::randomValidator()); - return TrustedPublisherServer{ + return make_TrustedPublisherServer( env.app().getIOService(), list, env.timeKeeper().now() + std::chrono::seconds{3600}, - ssl}; + ssl); } struct DownloadCompleter @@ -129,8 +129,8 @@ class DatabaseDownloader_test : public beast::unit_test::suite // initiate the download and wait for the callback // to be invoked auto stat = downloader->download( - server.local_endpoint().address().to_string(), - std::to_string(server.local_endpoint().port()), + server->local_endpoint().address().to_string(), + std::to_string(server->local_endpoint().port()), "/textfile", 11, data.file(), @@ -196,9 +196,9 @@ class DatabaseDownloader_test : public beast::unit_test::suite ripple::test::detail::FileDirGuard const datafile{ *this, "downloads", "data", "", false, false}; auto server = createServer(env); - auto host = server.local_endpoint().address().to_string(); - auto port = std::to_string(server.local_endpoint().port()); - server.stop(); + auto host = server->local_endpoint().address().to_string(); + auto port = std::to_string(server->local_endpoint().port()); + server->stop(); BEAST_EXPECT(dl->download( host, port, @@ -220,8 +220,8 @@ class DatabaseDownloader_test : public beast::unit_test::suite *this, "downloads", "data", "", false, false}; auto server = createServer(env, false); BEAST_EXPECT(dl->download( - server.local_endpoint().address().to_string(), - std::to_string(server.local_endpoint().port()), + server->local_endpoint().address().to_string(), + std::to_string(server->local_endpoint().port()), "", 11, datafile.file(), @@ -240,8 +240,8 @@ class DatabaseDownloader_test : public beast::unit_test::suite *this, "downloads", "data", "", false, false}; auto server = createServer(env); BEAST_EXPECT(dl->download( - server.local_endpoint().address().to_string(), - std::to_string(server.local_endpoint().port()), + server->local_endpoint().address().to_string(), + std::to_string(server->local_endpoint().port()), "/textfile/huge", 11, datafile.file(), diff --git a/src/test/rpc/ShardArchiveHandler_test.cpp b/src/test/rpc/ShardArchiveHandler_test.cpp index a25fb70c8f..48ef971b96 100644 --- a/src/test/rpc/ShardArchiveHandler_test.cpp +++ b/src/test/rpc/ShardArchiveHandler_test.cpp @@ -36,16 +36,16 @@ class ShardArchiveHandler_test : public beast::unit_test::suite { using Downloads = std::vector>; - TrustedPublisherServer + std::shared_ptr createServer(jtx::Env& env, bool ssl = true) { std::vector list; list.push_back(TrustedPublisherServer::randomValidator()); - return TrustedPublisherServer{ + return make_TrustedPublisherServer( env.app().getIOService(), list, env.timeKeeper().now() + std::chrono::seconds{3600}, - ssl}; + ssl); } public: @@ -191,9 +191,9 @@ public: BEAST_EXPECT(dynamic_cast(handler) == nullptr); auto server = createServer(env); - auto host = server.local_endpoint().address().to_string(); - auto port = std::to_string(server.local_endpoint().port()); - server.stop(); + auto host = server->local_endpoint().address().to_string(); + auto port = std::to_string(server->local_endpoint().port()); + server->stop(); Downloads const dl = [count = numberOfDownloads, &host, &port] { Downloads ret; @@ -290,9 +290,9 @@ public: dynamic_cast(handler) == nullptr); auto server = createServer(env); - auto host = server.local_endpoint().address().to_string(); - auto port = std::to_string(server.local_endpoint().port()); - server.stop(); + auto host = server->local_endpoint().address().to_string(); + auto port = std::to_string(server->local_endpoint().port()); + server->stop(); Downloads const dl = [count = numberOfDownloads, &host, &port] { Downloads ret; diff --git a/src/test/rpc/ValidatorRPC_test.cpp b/src/test/rpc/ValidatorRPC_test.cpp index a43eba2932..7a4b4907c9 100644 --- a/src/test/rpc/ValidatorRPC_test.cpp +++ b/src/test/rpc/ValidatorRPC_test.cpp @@ -190,8 +190,8 @@ public: BasicApp worker{1}; using namespace std::chrono_literals; NetClock::time_point const expiration{3600s}; - TrustedPublisherServer server{ - worker.get_io_service(), validators, expiration, false, 1, false}; + auto server = make_TrustedPublisherServer( + worker.get_io_service(), validators, expiration, false, 1, false); //---------------------------------------------------------------------- // Publisher list site unavailable @@ -206,7 +206,7 @@ public: envconfig([&](std::unique_ptr cfg) { cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI); cfg->section(SECTION_VALIDATOR_LIST_KEYS) - .append(strHex(server.publisherPublic())); + .append(strHex(server->publisherPublic())); return cfg; }), }; @@ -245,7 +245,7 @@ public: BEAST_EXPECT(!jp.isMember(jss::version)); BEAST_EXPECT( jp[jss::pubkey_publisher] == - strHex(server.publisherPublic())); + strHex(server->publisherPublic())); } BEAST_EXPECT(jrr[jss::signing_keys].size() == 0); } @@ -264,10 +264,10 @@ public: //---------------------------------------------------------------------- // Publisher list site available { - server.start(); + server->start(); std::stringstream uri; - uri << "http://" << server.local_endpoint() << "/validators"; + uri << "http://" << server->local_endpoint() << "/validators"; auto siteURI = uri.str(); Env env{ @@ -275,7 +275,7 @@ public: envconfig([&](std::unique_ptr cfg) { cfg->section(SECTION_VALIDATOR_LIST_SITES).append(siteURI); cfg->section(SECTION_VALIDATOR_LIST_KEYS) - .append(strHex(server.publisherPublic())); + .append(strHex(server->publisherPublic())); return cfg; }), }; @@ -333,7 +333,7 @@ public: BEAST_EXPECT(jp[jss::seq].asUInt() == 1); BEAST_EXPECT( jp[jss::pubkey_publisher] == - strHex(server.publisherPublic())); + strHex(server->publisherPublic())); BEAST_EXPECT(jp[jss::expiration] == to_string(expiration)); BEAST_EXPECT(jp[jss::version] == 1); }