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))
    {
        std::uint32_t const expiration = sleTicket->getFieldU32 (sfExpiration);

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

    if (!authorized)
        return tecNO_PERMISSION;

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

    auto viewJ = ctx_.app.journal ("View");
    TER const result = dirDelete (ctx_.view (), false, hint,
        getOwnerDirIndex (ticket_owner), ticketId, false, (hint == 0), viewJ);

    adjustOwnerCount(view(), view().peek(
        keylet::account(ticket_owner)), -1, viewJ);
    ctx_.view ().erase (sleTicket);

    return result;
}
Exemple #2
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;
    }