Beispiel #1
0
void
PeerRecord::resetBackOff(VirtualClock& clock)
{
    mNumFailures = 0;
    mNextAttempt = mIsPreferred ? VirtualClock::time_point() : clock.now();
    CLOG(DEBUG, "Overlay") << "PeerRecord: " << toString() << " backoff reset";
}
Beispiel #2
0
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";
}
Beispiel #6
0
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;
    }
}