void PeerRecord::resetBackOff(VirtualClock& clock) { mNumFailures = 0; mNextAttempt = mIsPreferred ? VirtualClock::time_point() : clock.now(); CLOG(DEBUG, "Overlay") << "PeerRecord: " << toString() << " backoff reset"; }
std::chrono::seconds PeerRecord::computeBackoff(VirtualClock& clock) { int32 backoffCount = std::min<int32>(MAX_BACKOFF_EXPONENT, mNumFailures); auto nsecs = std::chrono::seconds( std::rand() % int(std::pow(2, backoffCount) * SECONDS_PER_BACKOFF) + 1); mNextAttempt = clock.now() + nsecs; return nsecs; }
// under the Apache License, Version 2.0. See the COPYING file at the root // of this distribution or at http://www.apache.org/licenses/LICENSE-2.0 #include "overlay/OverlayManager.h" #include "overlay/test/LoopbackPeer.h" #include "test/TestUtils.h" #include "test/test.h" #include "util/Timer.h" #include <lib/catch.hpp> #include <medida/metrics_registry.h> using namespace stellar; TEST_CASE("disconnect peer when overloaded", "[overlay][LoadManager]") { VirtualClock clock; auto const& cfg1 = getTestConfig(0); auto cfg2 = getTestConfig(1); auto const& cfg3 = getTestConfig(2); cfg2.RUN_STANDALONE = false; cfg2.MINIMUM_IDLE_PERCENT = 90; cfg2.TARGET_PEER_CONNECTIONS = 0; cfg2.MAX_ADDITIONAL_PEER_CONNECTIONS = 3; auto app1 = createTestApplication(clock, cfg1); auto app2 = createTestApplication(clock, cfg2); auto app3 = createTestApplication(clock, cfg3); LoopbackPeerConnection conn(*app1, *app2); LoopbackPeerConnection conn2(*app3, *app2);
ApplicationImpl::ApplicationImpl(VirtualClock& clock, Config const& cfg) : mVirtualClock(clock) , mConfig(cfg) , mWorkerIOService(std::thread::hardware_concurrency()) , mWork(make_unique<asio::io_service::work>(mWorkerIOService)) , mWorkerThreads() , mStopSignals(clock.getIOService(), SIGINT) , mStopping(false) , mStoppingTimer(*this) , mMetrics(make_unique<medida::MetricsRegistry>()) , mAppStateCurrent(mMetrics->NewCounter({"app", "state", "current"})) , mAppStateChanges(mMetrics->NewTimer({"app", "state", "changes"})) , mLastStateChange(clock.now()) { #ifdef SIGQUIT mStopSignals.add(SIGQUIT); #endif #ifdef SIGTERM mStopSignals.add(SIGTERM); #endif std::srand(static_cast<uint32>(clock.now().time_since_epoch().count())); mNetworkID = sha256(mConfig.NETWORK_PASSPHRASE); unsigned t = std::thread::hardware_concurrency(); LOG(DEBUG) << "Application constructing " << "(worker threads: " << t << ")"; mStopSignals.async_wait([this](asio::error_code const& ec, int sig) { if (!ec) { LOG(INFO) << "got signal " << sig << ", shutting down"; this->gracefulStop(); } }); // These must be constructed _after_ because they frequently call back // into App.getFoo() to get information / start up. mDatabase = make_unique<Database>(*this); mPersistentState = make_unique<PersistentState>(*this); mTmpDirManager = make_unique<TmpDirManager>(cfg.TMP_DIR_PATH); mOverlayManager = OverlayManager::create(*this); mLedgerManager = LedgerManager::create(*this); mHerder = Herder::create(*this); mBucketManager = BucketManager::create(*this); mHistoryManager = HistoryManager::create(*this); mProcessManager = ProcessManager::create(*this); mCommandHandler = make_unique<CommandHandler>(*this); mWorkManager = WorkManager::create(*this); while (t--) { mWorkerThreads.emplace_back([this, t]() { this->runWorkerThread(t); }); } LOG(DEBUG) << "Application constructed"; }
ApplicationImpl::ApplicationImpl(VirtualClock& clock, Config const& cfg) : mState(Application::State::BOOTING_STATE) , mVirtualClock(clock) , mConfig(cfg) , mWorkerIOService(std::thread::hardware_concurrency()) , mWork(make_unique<asio::io_service::work>(mWorkerIOService)) , mWorkerThreads() , mStopSignals(clock.getIOService(), SIGINT) { #ifdef SIGQUIT mStopSignals.add(SIGQUIT); #endif #ifdef SIGTERM mStopSignals.add(SIGTERM); #endif unsigned t = std::thread::hardware_concurrency(); LOG(INFO) << "Application constructing " << "(worker threads: " << t << ")"; mStopSignals.async_wait([this](asio::error_code const& ec, int sig) { LOG(INFO) << "got signal " << sig << ", shutting down"; this->gracefulStop(); }); // These must be constructed _after_ because they frequently call back // into App.getFoo() to get information / start up. mMetrics = make_unique<medida::MetricsRegistry>(); mDatabase = make_unique<Database>(*this); mPersistentState = make_unique<PersistentState>(*this); if (mPersistentState->getState(PersistentState::kForceSCPOnNextLaunch) == "true") { mConfig.START_NEW_NETWORK = true; } // Initialize the db as early as possible, namely as soon as metrics, // database and persistentState are instantiated. if (mConfig.REBUILD_DB || mConfig.DATABASE == "sqlite3://:memory:") { mDatabase->initialize(); } mTmpDirManager = make_unique<TmpDirManager>(cfg.TMP_DIR_PATH); mOverlayManager = OverlayManager::create(*this); mLedgerManager = LedgerManager::create(*this); mHerder = Herder::create(*this); mBucketManager = BucketManager::create(*this); mHistoryManager = HistoryManager::create(*this); mProcessManager = ProcessManager::create(*this); mCommandHandler = make_unique<CommandHandler>(*this); while (t--) { mWorkerThreads.emplace_back([this, t]() { this->runWorkerThread(t); }); } LOG(INFO) << "Application constructed"; }
void fuzz(std::string const& filename, el::Level logLevel, std::vector<std::string> const& metrics) { Logging::setFmt("<fuzz>", false); Logging::setLogLevel(logLevel, nullptr); LOG(INFO) << "Fuzzing stellar-core " << STELLAR_CORE_VERSION; LOG(INFO) << "Fuzz input is in " << filename; Config cfg1, cfg2; cfg1.RUN_STANDALONE = true; cfg1.ARTIFICIALLY_ACCELERATE_TIME_FOR_TESTING = true; cfg1.LOG_FILE_PATH = "fuzz-app-1.log"; cfg1.TMP_DIR_PATH = "fuzz-tmp-1"; cfg1.BUCKET_DIR_PATH = "fuzz-buckets-1"; cfg2.RUN_STANDALONE = true; cfg2.ARTIFICIALLY_ACCELERATE_TIME_FOR_TESTING = true; cfg1.LOG_FILE_PATH = "fuzz-app-2.log"; cfg2.TMP_DIR_PATH = "fuzz-tmp-2"; cfg2.BUCKET_DIR_PATH = "fuzz-buckets-2"; CfgDirGuard g1(cfg1); CfgDirGuard g2(cfg2); restart: { VirtualClock clock; Application::pointer app1 = Application::create(clock, cfg1); Application::pointer app2 = Application::create(clock, cfg2); LoopbackPeerConnection loop(*app1, *app2); while (clock.crank(false) > 0) ; XDRInputFileStream in; in.open(filename); StellarMessage msg; size_t i = 0; while (tryRead(in, msg)) { ++i; if (msg.type() != HELLO) { LOG(INFO) << "Fuzzer injecting message " << i << ": " << msgSummary(msg); loop.getAcceptor()->Peer::sendMessage(msg); } size_t iter = 20; while (clock.crank(false) > 0 && iter-- > 0) ; } } if (getenv("AFL_PERSISTENT") && persist_cnt++ < PERSIST_MAX) { #ifndef _WIN32 raise(SIGSTOP); #endif goto restart; } }