예제 #1
0
TER
CancelTicket::doApply ()
{
    uint256 const ticketId = ctx_.tx.getFieldH256 (sfTicketID);

    // VFALCO This is highly suspicious, we're requiring that the
    //        transaction provide the return value of getTicketIndex?
    SLE::pointer sleTicket = view().peek (keylet::ticket(ticketId));

    if (!sleTicket)
        return tecNO_ENTRY;

    auto const ticket_owner =
        sleTicket->getAccountID (sfAccount);

    bool authorized =
        account_ == ticket_owner;

    // The target can also always remove a ticket
    if (!authorized && sleTicket->isFieldPresent (sfTarget))
        authorized = (account_ == sleTicket->getAccountID (sfTarget));

    // And finally, anyone can remove an expired ticket
    if (!authorized && sleTicket->isFieldPresent (sfExpiration))
    {
        using tp = NetClock::time_point;
        using d = tp::duration;
        auto const expiration = tp{d{sleTicket->getFieldU32(sfExpiration)}};

        if (view().parentCloseTime() >= expiration)
            authorized = true;
    }

    if (!authorized)
        return tecNO_PERMISSION;

    std::uint64_t const hint (sleTicket->getFieldU64 (sfOwnerNode));

    if (! ctx_.view().dirRemove(
            keylet::ownerDir(ticket_owner), hint, ticketId, false))
    {
        return tefBAD_LEDGER;
    }

    auto viewJ = ctx_.app.journal ("View");
    adjustOwnerCount(view(), view().peek(
        keylet::account(ticket_owner)), -1, viewJ);
    ctx_.view ().erase (sleTicket);

    return tesSUCCESS;
}
예제 #2
0
static
std::uint32_t
rippleQuality (
    LedgerEntrySet& ledger,
    AccountID const& destination,
    AccountID const& source,
    Currency const& currency,
    SField const& sfLow,
    SField const& sfHigh)
{
    std::uint32_t uQuality (QUALITY_ONE);

    if (destination != source)
    {
        SLE::pointer sleRippleState (ledger.entryCache (ltRIPPLE_STATE,
            getRippleStateIndex (destination, source, currency)));

        // we should be able to assert(sleRippleState) here

        if (sleRippleState)
        {
            auto const& sfField = destination < source ? sfLow : sfHigh;

            uQuality = sleRippleState->isFieldPresent (sfField)
                ? sleRippleState->getFieldU32 (sfField)
                : QUALITY_ONE;

            if (!uQuality)
                uQuality = 1; // Avoid divide by zero.
        }
    }

    return uQuality;
}
예제 #3
0
    TER doApply () override
    {
        assert (mTxnAccount);

        uint256 const ticketId = mTxn.getFieldH256 (sfTicketID);

        SLE::pointer sleTicket = mEngine->view ().entryCache (ltTICKET, ticketId);

        if (!sleTicket)
            return tecNO_ENTRY;

        Account const ticket_owner (sleTicket->getFieldAccount160 (sfAccount));

        bool authorized (mTxnAccountID == ticket_owner);

        // The target can also always remove a ticket
        if (!authorized && sleTicket->isFieldPresent (sfTarget))
            authorized = (mTxnAccountID == sleTicket->getFieldAccount160 (sfTarget));

        // And finally, anyone can remove an expired ticket
        if (!authorized && sleTicket->isFieldPresent (sfExpiration))
        {
            std::uint32_t const expiration = sleTicket->getFieldU32 (sfExpiration);

            if (mEngine->getLedger ()->getParentCloseTimeNC () >= expiration)
                authorized = true;
        }

        if (!authorized)
            return tecNO_PERMISSION;

        std::uint64_t const hint (sleTicket->getFieldU64 (sfOwnerNode));

        TER const result = mEngine->view ().dirDelete (false, hint,
            getOwnerDirIndex (ticket_owner), ticketId, false, (hint == 0));

        mEngine->view ().decrementOwnerCount (mTxnAccount);
        mEngine->view ().entryDelete (sleTicket);

        return result;
    }
예제 #4
0
TER
SetSignerList::destroySignerList ()
{
    auto const accountKeylet = keylet::account (account_);
    // Destroying the signer list is only allowed if either the master key
    // is enabled or there is a regular key.
    SLE::pointer ledgerEntry = view().peek (accountKeylet);
    if ((ledgerEntry->isFlag (lsfDisableMaster)) &&
        (!ledgerEntry->isFieldPresent (sfRegularKey)))
            return tecNO_ALTERNATIVE_KEY;

    auto const ownerDirKeylet = keylet::ownerDir (account_);
    auto const signerListKeylet = keylet::signers (account_);
    return removeSignersFromLedger(
        accountKeylet, ownerDirKeylet, signerListKeylet);
}