Exemplo n.º 1
0
boost::container::flat_set<AccountID>
TxMeta::getAffectedAccounts() const
{
    boost::container::flat_set<AccountID> list;
    list.reserve (10);

    // This code should match the behavior of the JS method:
    // Meta#getAffectedAccounts
    for (auto const& it : mNodes)
    {
        int index = it.getFieldIndex ((it.getFName () == sfCreatedNode) ? sfNewFields : sfFinalFields);

        if (index != -1)
        {
            const STObject* inner = dynamic_cast<const STObject*> (&it.peekAtIndex (index));
            assert(inner);
            if (inner)
            {
                for (auto const& field : *inner)
                {
                    STAccount const* sa =
                        dynamic_cast<STAccount const*> (&field);

                    if (sa)
                    {
                        AccountID id;
                        assert(sa->isValueH160());
                        if (sa->getValueH160(id))
                            list.insert(id);
                    }
                    else if ((field.getFName () == sfLowLimit) || (field.getFName () == sfHighLimit) ||
                             (field.getFName () == sfTakerPays) || (field.getFName () == sfTakerGets))
                    {
                        const STAmount* lim = dynamic_cast<const STAmount*> (&field);

                        if (lim != nullptr)
                        {
                            auto issuer = lim->getIssuer ();

                            if (issuer.isNonZero ())
                                list.insert(issuer);
                        }
                        else
                        {
                            JLOG (j_.fatal) << "limit is not amount " << field.getJson (0);
                        }
                    }
                }
            }
        }
    }

    return list;
}
Exemplo n.º 2
0
std::vector<RippleAddress> TransactionMetaSet::getAffectedAccounts ()
{
    std::vector<RippleAddress> accounts;
    accounts.reserve (10);

    // This code should match the behavior of the JS method:
    // Meta#getAffectedAccounts
    for (auto const& it : mNodes)
    {
        int index = it.getFieldIndex ((it.getFName () == sfCreatedNode) ? sfNewFields : sfFinalFields);

        if (index != -1)
        {
            const STObject* inner = dynamic_cast<const STObject*> (&it.peekAtIndex (index));

            if (inner)
            {
                for (auto const& field : *inner)
                {
                    const STAccount* sa = dynamic_cast<const STAccount*> (&field);

                    if (sa)
                        addIfUnique (accounts, sa->getValueNCA ());
                    else if ((field.getFName () == sfLowLimit) || (field.getFName () == sfHighLimit) ||
                             (field.getFName () == sfTakerPays) || (field.getFName () == sfTakerGets))
                    {
                        const STAmount* lim = dynamic_cast<const STAmount*> (&field);

                        if (lim != nullptr)
                        {
                            auto issuer = lim->getIssuer ();

                            if (issuer.isNonZero ())
                            {
                                RippleAddress na;
                                na.setAccountID (issuer);
                                addIfUnique (accounts, na);
                            }
                        }
                        else
                        {
                            WriteLog (lsFATAL, TransactionMetaSet) << "limit is not amount " << field.getJson (0);
                        }
                    }
                }
            }
            else assert (false);
        }
    }

    return accounts;
}
std::vector<RippleAddress> SerializedTransaction::getMentionedAccounts () const
{
    std::vector<RippleAddress> accounts;

    BOOST_FOREACH (const SerializedType & it, peekData ())
    {
        const STAccount* sa = dynamic_cast<const STAccount*> (&it);

        if (sa != nullptr)
        {
            bool found = false;
            RippleAddress na = sa->getValueNCA ();
            BOOST_FOREACH (const RippleAddress & it, accounts)
            {
                if (it == na)
                {
                    found = true;
                    break;
                }
            }

            if (!found)
                accounts.push_back (na);
        }

        const STAmount* sam = dynamic_cast<const STAmount*> (&it);

        if (sam)
        {
            auto issuer = sam->getIssuer ();

            if (issuer.isNonZero ())
            {
                RippleAddress na;
                na.setAccountID (issuer);
                bool found = false;
                BOOST_FOREACH (const RippleAddress & it, accounts)
                {
                    if (it == na)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                    accounts.push_back (na);
            }
        }
Exemplo n.º 4
0
// {
//   ledger_hash : <ledger>
//   ledger_index : <ledger_index>
// }
Json::Value doLedgerRequest (RPC::Context& context)
{
    auto const hasHash = context.params.isMember (jss::ledger_hash);
    auto const hasIndex = context.params.isMember (jss::ledger_index);

    auto& ledgerMaster = getApp().getLedgerMaster();
    LedgerHash ledgerHash;

    if ((hasHash && hasIndex) || !(hasHash || hasIndex))
    {
        return RPC::make_param_error(
            "Exactly one of ledger_hash and ledger_index can be set.");
    }

    if (hasHash)
    {
        auto const& jsonHash = context.params[jss::ledger_hash];
        if (!jsonHash.isString() || !ledgerHash.SetHex (jsonHash.asString ()))
            return RPC::invalid_field_message (jss::ledger_hash);
    } else {
        auto const& jsonIndex = context.params[jss::ledger_index];
        if (!jsonIndex.isNumeric ())
            return RPC::invalid_field_message (jss::ledger_index);

        // We need a validated ledger to get the hash from the sequence
        if (ledgerMaster.getValidatedLedgerAge() > 120)
            return rpcError (rpcNO_CURRENT);

        auto ledgerIndex = jsonIndex.asInt();
        auto ledger = ledgerMaster.getValidatedLedger();

        if (ledgerIndex >= ledger->getLedgerSeq())
            return RPC::make_param_error("Ledger index too large");

        // Try to get the hash of the desired ledger from the validated ledger
        ledgerHash = ledger->getLedgerHash (ledgerIndex);

        if (ledgerHash == zero)
        {
            // Find a ledger more likely to have the hash of the desired ledger
            auto refIndex = (ledgerIndex + 255) & (~255);
            auto refHash = ledger->getLedgerHash (refIndex);
            assert (refHash.isNonZero ());

            ledger = ledgerMaster.getLedgerByHash (refHash);
            if (!ledger)
            {
                // We don't have the ledger we need to figure out which ledger
                // they want. Try to get it.

                if (auto il = getApp().getInboundLedgers().acquire (
                        refHash, refIndex, InboundLedger::fcGENERIC))
                    return getJson (LedgerFill (*il));

                if (auto il = getApp().getInboundLedgers().find (refHash))
                {
                    Json::Value jvResult = il->getJson (0);

                    jvResult[jss::error] = "ledgerNotFound";
                    return jvResult;
                }

                // Likely the app is shutting down
                return Json::Value();
            }

            ledgerHash = ledger->getLedgerHash (ledgerIndex);
            assert (ledgerHash.isNonZero ());
        }
    }

    auto ledger = ledgerMaster.getLedgerByHash (ledgerHash);
    if (ledger)
    {
        // We already have the ledger they want
        Json::Value jvResult;
        jvResult[jss::ledger_index] = ledger->getLedgerSeq();
        addJson (jvResult, {*ledger, 0});
        return jvResult;
    }
    else
    {
        // Try to get the desired ledger
        if (auto il = getApp ().getInboundLedgers ().acquire (
                ledgerHash, 0, InboundLedger::fcGENERIC))
            return getJson (LedgerFill (*il));

        if (auto il = getApp().getInboundLedgers().find (ledgerHash))
            return il->getJson (0);

        return RPC::make_error (
            rpcNOT_READY, "findCreate failed to return an inbound ledger");
    }
}