예제 #1
0
STValidation::STValidation(
    uint256 const& ledgerHash,
    std::uint32_t ledgerSeq,
    uint256 const& consensusHash,
    NetClock::time_point signTime,
    PublicKey const& publicKey,
    SecretKey const& secretKey,
    NodeID const& nodeID,
    bool isFull,
    FeeSettings const& fees,
    std::vector<uint256> const& amendments)
    : STObject(getFormat(), sfValidation), mNodeID(nodeID), mSeen(signTime)
{
    // This is our own public key and it should always be valid.
    if (!publicKeyType(publicKey))
        LogicError("Invalid validation public key");
    assert(mNodeID.isNonZero());
    setFieldH256(sfLedgerHash, ledgerHash);
    setFieldH256(sfConsensusHash, consensusHash);
    setFieldU32(sfSigningTime, signTime.time_since_epoch().count());

    setFieldVL(sfSigningPubKey, publicKey.slice());
    if (isFull)
        setFlag(kFullFlag);

    setFieldU32(sfLedgerSequence, ledgerSeq);

    if (fees.loadFee)
        setFieldU32(sfLoadFee, *fees.loadFee);

    if (fees.baseFee)
        setFieldU64(sfBaseFee, *fees.baseFee);

    if (fees.reserveBase)
        setFieldU32(sfReserveBase, *fees.reserveBase);

    if (fees.reserveIncrement)
        setFieldU32(sfReserveIncrement, *fees.reserveIncrement);

    if (!amendments.empty())
        setFieldV256(sfAmendments, STVector256(sfAmendments, amendments));

    setFlag(vfFullyCanonicalSig);

    auto const signingHash = getSigningHash();
    setFieldVL(
        sfSignature, signDigest(getSignerPublic(), secretKey, signingHash));

    setTrusted();
}
예제 #2
0
// Handle the case where a directory item with no corresponding ledger entry
// is found. This shouldn't happen but if it does we clean it up.
void
OfferStream::erase (LedgerView& view)
{
    // NIKB NOTE This should be using LedgerView::dirDelete, which would
    //           correctly remove the directory if its the last entry.
    //           Unfortunately this is a protocol breaking change.

    auto p (view.entryCache (ltDIR_NODE, m_tip.dir()));

    if (p == nullptr)
    {
        if (m_journal.error) m_journal.error <<
                                                 "Missing directory " << m_tip.dir() <<
                                                 " for offer " << m_tip.index();
        return;
    }

    auto v (p->getFieldV256 (sfIndexes));
    auto& x (v.peekValue());
    auto it (std::find (x.begin(), x.end(), m_tip.index()));

    if (it == x.end())
    {
        if (m_journal.error) m_journal.error <<
                                                 "Missing offer " << m_tip.index() <<
                                                 " for directory " << m_tip.dir();
        return;
    }

    x.erase (it);
    p->setFieldV256 (sfIndexes, v);
    view.entryModify (p);

    if (m_journal.trace) m_journal.trace <<
                                             "Missing offer " << m_tip.index() <<
                                             " removed from directory " << m_tip.dir();
}
예제 #3
0
// Handle the case where a directory item with no corresponding ledger entry
// is found. This shouldn't happen but if it does we clean it up.
void
OfferStream::erase (ApplyView& view)
{
    // NIKB NOTE This should be using ApplyView::dirDelete, which would
    //           correctly remove the directory if its the last entry.
    //           Unfortunately this is a protocol breaking change.

    auto p = view.peek (keylet::page(tip_.dir()));

    if (p == nullptr)
    {
        JLOG(j_.error) <<
            "Missing directory " << tip_.dir() <<
            " for offer " << tip_.index();
        return;
    }

    auto v (p->getFieldV256 (sfIndexes));
    auto it (std::find (v.begin(), v.end(), tip_.index()));

    if (it == v.end())
    {
        JLOG(j_.error) <<
            "Missing offer " << tip_.index() <<
            " for directory " << tip_.dir();
        return;
    }

    v.erase (it);
    p->setFieldV256 (sfIndexes, v);
    view.update (p);

    JLOG(j_.trace) <<
        "Missing offer " << tip_.index() <<
        " removed from directory " << tip_.dir();
}
예제 #4
0
// update the skip list with the information from our previous ledger
// VFALCO TODO Document this skip list concept
void Ledger::updateSkipList ()
{
    if (info_.seq == 0) // genesis ledger has no previous ledger
        return;

    std::uint32_t prevIndex = info_.seq - 1;

    // update record of every 256th ledger
    if ((prevIndex & 0xff) == 0)
    {
        auto const k = keylet::skip(prevIndex);
        auto sle = peek(k);
        std::vector<uint256> hashes;

        bool created;
        if (! sle)
        {
            sle = std::make_shared<SLE>(k);
            created = true;
        }
        else
        {
            hashes = static_cast<decltype(hashes)>(
                sle->getFieldV256(sfHashes));
            created = false;
        }

        assert (hashes.size () <= 256);
        hashes.push_back (info_.parentHash);
        sle->setFieldV256 (sfHashes, STVector256 (hashes));
        sle->setFieldU32 (sfLastLedgerSequence, prevIndex);
        if (created)
            rawInsert(sle);
        else
            rawReplace(sle);
    }

    // update record of past 256 ledger
    auto const k = keylet::skip();
    auto sle = peek(k);
    std::vector <uint256> hashes;
    bool created;
    if (! sle)
    {
        sle = std::make_shared<SLE>(k);
        created = true;
    }
    else
    {
        hashes = static_cast<decltype(hashes)>(
            sle->getFieldV256 (sfHashes));
        created = false;
    }
    assert (hashes.size () <= 256);
    if (hashes.size () == 256)
        hashes.erase (hashes.begin ());
    hashes.push_back (info_.parentHash);
    sle->setFieldV256 (sfHashes, STVector256 (hashes));
    sle->setFieldU32 (sfLastLedgerSequence, prevIndex);
    if (created)
        rawInsert(sle);
    else
        rawReplace(sle);
}