Esempio n. 1
0
std::shared_ptr<Ledger>
buildLedgerImpl(
    std::shared_ptr<Ledger const> const& parent,
    NetClock::time_point closeTime,
    const bool closeTimeCorrect,
    NetClock::duration closeResolution,
    Application& app,
    beast::Journal j,
    ApplyTxs&& applyTxs)
{
    auto buildLCL = std::make_shared<Ledger>(*parent, closeTime);

    if (buildLCL->rules().enabled(featureSHAMapV2) &&
        !buildLCL->stateMap().is_v2())
    {
        buildLCL->make_v2();
    }

    // Set up to write SHAMap changes to our database,
    //   perform updates, extract changes

    {
        OpenView accum(&*buildLCL);
        assert(!accum.open());
        applyTxs(accum, buildLCL);
        accum.apply(*buildLCL);
    }

    buildLCL->updateSkipList();

    {
        // Write the final version of all modified SHAMap
        // nodes to the node store to preserve the new LCL

        int const asf = buildLCL->stateMap().flushDirty(
            hotACCOUNT_NODE, buildLCL->info().seq);
        int const tmf = buildLCL->txMap().flushDirty(
            hotTRANSACTION_NODE, buildLCL->info().seq);
        JLOG(j.debug()) << "Flushed " << asf << " accounts and " << tmf
                        << " transaction nodes";
    }
    buildLCL->unshare();

    // Accept ledger
    buildLCL->setAccepted(
        closeTime, closeResolution, closeTimeCorrect, app.config());

    return buildLCL;
}
Esempio n. 2
0
    void
    testSkipList()
    {
        beast::Journal const j;
        std::vector<std::shared_ptr<Ledger>> history;
        {
            jtx::Env env(*this);
            Config config;
            auto prev =
                std::make_shared<Ledger>(create_genesis, config, env.app().family());
            history.push_back(prev);
            for (auto i = 0; i < 1023; ++i)
            {
                auto next = std::make_shared<Ledger>(
                    *prev,
                    env.app().timeKeeper().closeTime());
                next->updateSkipList();
                history.push_back(next);
                prev = next;
            }
        }

        {
            auto l = *(std::next(std::begin(history)));
            expect((*std::begin(history))->info().seq <
                l->info().seq);
            expect(hashOfSeq(*l, l->info().seq + 1,
                j) == boost::none);
            expect(hashOfSeq(*l, l->info().seq,
                j) == l->info().hash);
            expect(hashOfSeq(*l, l->info().seq - 1,
                j) == l->info().parentHash);
            expect(hashOfSeq(*history.back(),
                l->info().seq, j) == boost::none);
        }

        // ledger skip lists store up to the previous 256 hashes
        for (auto i = history.crbegin();
            i != history.crend(); i += 256)
        {
            for (auto n = i;
                n != std::next(i,
                    (*i)->info().seq - 256 > 1 ? 257 : 256);
                ++n)
            {
                expect(hashOfSeq(**i,
                    (*n)->info().seq, j) ==
                        (*n)->info().hash);
            }

            // edge case accessing beyond 256
            expect(hashOfSeq(**i,
                (*i)->info().seq - 258, j) ==
                    boost::none);
        }

        // every 256th hash beyond the first 256 is stored
        for (auto i = history.crbegin();
            i != std::next(history.crend(), -512);
            i += 256)
        {
            for (auto n = std::next(i, 512);
                n != history.crend();
                n += 256)
            {
                expect(hashOfSeq(**i,
                    (*n)->info().seq, j) ==
                        (*n)->info().hash);
            }
        }
    }