Beispiel #1
0
std::vector <RippleState::pointer>
getRippleStateItems (
    AccountID const& accountID,
    Ledger::ref ledger)
{
    std::vector <RippleState::pointer> items;
    forEachItem(*ledger, accountID, getApp().getSLECache(),
        [&items,&accountID](
        std::shared_ptr<SLE const> const&sleCur)
        {
             auto ret = RippleState::makeItem (accountID, sleCur);
             if (ret)
                items.push_back (ret);
        });

    return items;
}
Beispiel #2
0
Json::Value doGatewayBalances (RPC::Context& context)
{
    auto& params = context.params;

    // Get the current ledger
    std::shared_ptr<ReadView const> ledger;
    auto result = RPC::lookupLedger (ledger, context);

    if (!ledger)
        return result;

    if (!(params.isMember (jss::account) || params.isMember (jss::ident)))
        return RPC::missing_field_error (jss::account);

    std::string const strIdent (params.isMember (jss::account)
        ? params[jss::account].asString ()
        : params[jss::ident].asString ());

    bool const bStrict = params.isMember (jss::strict) &&
            params[jss::strict].asBool ();

    // Get info on account.
    AccountID accountID;
    auto jvAccepted = RPC::accountFromString (accountID, strIdent, bStrict);

    if (jvAccepted)
        return jvAccepted;

    context.loadType = Resource::feeHighBurdenRPC;

    result[jss::account] = getApp().accountIDCache().toBase58 (accountID);

    // Parse the specified hotwallet(s), if any
    std::set <AccountID> hotWallets;

    if (params.isMember ("hotwallet"))
    {
        Json::Value const& hw = params["hotwallet"];
        bool valid = true;

        auto addHotWallet = [&valid, &hotWallets](Json::Value const& j)
        {
            if (j.isString())
            {
                RippleAddress ra;
                if (ra.setAccountPublic (j.asString ()))
                {
                    hotWallets.insert(calcAccountID(ra));
                }
                else
                {
                    auto const a =parseBase58<AccountID>(j.asString());
                    if (! a)
                        valid = false;
                    else
                      hotWallets.insert(*a);
                }
            }
            else
            {
                valid = false;
            }
        };

        if (hw.isArray())
        {
            for (unsigned i = 0; i < hw.size(); ++i)
                addHotWallet (hw[i]);
        }
        else if (hw.isString())
        {
            addHotWallet (hw);
        }
        else
        {
            valid = false;
        }

        if (! valid)
        {
            result[jss::error]   = "invalidHotWallet";
            return result;
        }

    }

    std::map <Currency, STAmount> sums;
    std::map <AccountID, std::vector <STAmount>> hotBalances;
    std::map <AccountID, std::vector <STAmount>> assets;

    // Traverse the cold wallet's trust lines
    {
        forEachItem(*ledger, accountID,
            [&](std::shared_ptr<SLE const> const& sle)
            {
                auto rs = RippleState::makeItem (accountID, sle);

                if (!rs)
                    return;

                int balSign = rs->getBalance().signum();
                if (balSign == 0)
                    return;

                auto const& peer = rs->getAccountIDPeer();

                // Here, a negative balance means the cold wallet owes (normal)
                // A positive balance means the cold wallet has an asset (unusual)

                if (hotWallets.count (peer) > 0)
                {
                    // This is a specified hot wallt
                    hotBalances[peer].push_back (-rs->getBalance ());
                }
                else if (balSign > 0)
                {
                    // This is a gateway asset
                    assets[peer].push_back (rs->getBalance ());
                }
                else
                {
                    // normal negative balance, obligation to customer
                    auto& bal = sums[rs->getBalance().getCurrency()];
                    if (bal == zero)
                    {
                        // This is needed to set the currency code correctly
                        bal = -rs->getBalance();
                    }
                    else
                        bal -= rs->getBalance();
                }
            });
    }

    if (! sums.empty())
    {
        Json::Value& j = (result [jss::obligations] = Json::objectValue);
        for (auto const& e : sums)
        {
            j[to_string (e.first)] = e.second.getText ();
        }
    }

    if (! hotBalances.empty())
    {
        Json::Value& j = (result [jss::balances] = Json::objectValue);
        for (auto const& account : hotBalances)
        {
            Json::Value& balanceArray = (j[to_string (account.first)] = Json::arrayValue);
            for (auto const& balance : account.second)
            {
                Json::Value& entry = balanceArray.append (Json::objectValue);
                entry[jss::currency] = to_string (balance.issue ().currency);
                entry[jss::value] = balance.getText();
            }
        }
    }

    if (! assets.empty())
    {
        Json::Value& j = (result [jss::assets] = Json::objectValue);

        for (auto const& account : assets)
        {
            Json::Value& balanceArray = (j[to_string (account.first)] = Json::arrayValue);
            for (auto const& balance : account.second)
            {
                Json::Value& entry = balanceArray.append (Json::objectValue);
                entry[jss::currency] = to_string (balance.issue ().currency);
                entry[jss::value] = balance.getText();
            }
        }
    }

    return result;
}
Beispiel #3
0
Json::Value doGatewayBalances (RPC::Context& context)
{
    auto& params = context.params;

    // Get the current ledger
    std::shared_ptr<ReadView const> ledger;
    auto result = RPC::lookupLedger (ledger, context);

    if (!ledger)
        return result;

    if (!(params.isMember (jss::account) || params.isMember (jss::ident)))
        return RPC::missing_field_error (jss::account);

    std::string const strIdent (params.isMember (jss::account)
        ? params[jss::account].asString ()
        : params[jss::ident].asString ());

    bool const bStrict = params.isMember (jss::strict) &&
            params[jss::strict].asBool ();

    // Get info on account.
    AccountID accountID;
    auto jvAccepted = RPC::accountFromString (accountID, strIdent, bStrict);

    if (jvAccepted)
        return jvAccepted;

    context.loadType = Resource::feeHighBurdenRPC;

    result[jss::account] = context.app.accountIDCache().toBase58 (accountID);

    // Parse the specified hotwallet(s), if any
    std::set <AccountID> hotWallets;

    if (params.isMember (jss::hotwallet))
    {

        auto addHotWallet = [&hotWallets](Json::Value const& j)
        {
            if (j.isString())
            {
                auto const pk = parseBase58<PublicKey>(
                    TokenType::TOKEN_ACCOUNT_PUBLIC,
                    j.asString ());
                if (pk)
                {
                    hotWallets.insert(calcAccountID(*pk));
                    return true;
                }

                auto const id = parseBase58<AccountID>(j.asString());

                if (id)
                {
                    hotWallets.insert(*id);
                    return true;
                }
            }

            return false;
        };

        Json::Value const& hw = params[jss::hotwallet];
        bool valid = true;

        if (hw.isArray())
        {
            for (unsigned i = 0; i < hw.size(); ++i)
                valid &= addHotWallet (hw[i]);
        }
        else if (hw.isString())
        {
            valid &= addHotWallet (hw);
        }
        else
        {
            valid = false;
        }

        if (! valid)
        {
            result[jss::error]   = "invalidHotWallet";
            return result;
        }

    }

    std::map <Currency, STAmount> sums;
    std::map <AccountID, std::vector <STAmount>> hotBalances;
    std::map <AccountID, std::vector <STAmount>> assets;
    std::map <AccountID, std::vector <STAmount>> frozenBalances;

    // Traverse the cold wallet's trust lines
    {
        forEachItem(*ledger, accountID,
            [&](std::shared_ptr<SLE const> const& sle)
            {
                auto rs = RippleState::makeItem (accountID, sle);

                if (!rs)
                    return;

                int balSign = rs->getBalance().signum();
                if (balSign == 0)
                    return;

                auto const& peer = rs->getAccountIDPeer();

                // Here, a negative balance means the cold wallet owes (normal)
                // A positive balance means the cold wallet has an asset (unusual)

                if (hotWallets.count (peer) > 0)
                {
                    // This is a specified hot wallet
                    hotBalances[peer].push_back (-rs->getBalance ());
                }
                else if (balSign > 0)
                {
                    // This is a gateway asset
                    assets[peer].push_back (rs->getBalance ());
                }
                else if (rs->getFreeze())
                {
                    // An obligation the gateway has frozen
                    frozenBalances[peer].push_back (-rs->getBalance ());
                }
                else
                {
                    // normal negative balance, obligation to customer
                    auto& bal = sums[rs->getBalance().getCurrency()];
                    if (bal == zero)
                    {
                        // This is needed to set the currency code correctly
                        bal = -rs->getBalance();
                    }
                    else
                        bal -= rs->getBalance();
                }
            });
    }

    if (! sums.empty())
    {
        Json::Value j;
        for (auto const& e : sums)
        {
            j[to_string (e.first)] = e.second.getText ();
        }
        result [jss::obligations] = std::move (j);
    }

    auto populate = [](
        std::map <AccountID, std::vector <STAmount>> const& array,
        Json::Value& result,
        Json::StaticString const& name)
        {
            if (!array.empty())
            {
                Json::Value j;
                for (auto const& account : array)
                {
                    Json::Value balanceArray;
                    for (auto const& balance : account.second)
                    {
                        Json::Value entry;
                        entry[jss::currency] = to_string (balance.issue ().currency);
                        entry[jss::value] = balance.getText();
                        balanceArray.append (std::move (entry));
                    }
                    j [to_string (account.first)] = std::move (balanceArray);
                }
                result [name] = std::move (j);
            }
        };

    populate (hotBalances, result, jss::balances);
    populate (frozenBalances, result, jss::frozen_balances);
    populate (assets, result, jss::assets);

    return result;
}