Exemple #1
0
TER computeForwardLiqudity (
    RippleCalc& rippleCalc,
    const unsigned int nodeIndex, PathState& pathState,
    const bool bMultiQuality)
{
    auto const& node = pathState.nodes()[nodeIndex];
    WriteLog (lsTRACE, RippleCalc)
        << "computeForwardLiqudity> nodeIndex=" << nodeIndex;

    TER resultCode = node.isAccount()
        ? computeForwardLiquidityForAccount (
            rippleCalc, nodeIndex, pathState, bMultiQuality)
        : computeForwardLiquidityForOffer (
              rippleCalc, nodeIndex, pathState, bMultiQuality);

    if (resultCode == tesSUCCESS && nodeIndex + 1 != pathState.nodes().size ())
        resultCode = computeForwardLiqudity (rippleCalc, nodeIndex + 1, pathState, bMultiQuality);

    if (resultCode == tesSUCCESS && !(pathState.inPass() && pathState.outPass()))
        resultCode = tecPATH_DRY;

    WriteLog (lsTRACE, RippleCalc)
        << "computeForwardLiqudity<"
        << " nodeIndex:" << nodeIndex
        << " resultCode:" << resultCode;

    return resultCode;
}
void pathNext (
    RippleCalc& rippleCalc,
    PathState& pathState, const bool bMultiQuality,
    const LedgerEntrySet& lesCheckpoint, LedgerEntrySet& lesCurrent)
{
    // The next state is what is available in preference order.
    // This is calculated when referenced accounts changed.
    pathState.clear();

    WriteLog (lsTRACE, RippleCalc)
        << "pathNext: Path In: " << pathState.getJson ();

    assert (pathState.nodes().size () >= 2);

    lesCurrent  = lesCheckpoint.duplicate ();  // Restore from checkpoint.

    for (unsigned int uIndex = pathState.nodes().size (); uIndex--;)
    {
        auto& node   = pathState.nodes()[uIndex];

        node.saRevRedeem.clear ();
        node.saRevIssue.clear ();
        node.saRevDeliver.clear ();
        node.saFwdDeliver.clear ();
    }

    pathState.setStatus(computeReverseLiquidity (
        rippleCalc, pathState, bMultiQuality));

    WriteLog (lsTRACE, RippleCalc)
        << "pathNext: Path after reverse: " << pathState.getJson ();

    if (tesSUCCESS == pathState.status())
    {
        // Do forward.
        lesCurrent = lesCheckpoint.duplicate ();   // Restore from checkpoint.

        pathState.setStatus(computeForwardLiquidity (
            rippleCalc, pathState, bMultiQuality));
    }

    if (tesSUCCESS == pathState.status())
    {
        CondLog (!pathState.inPass() || !pathState.outPass(), lsDEBUG, RippleCalc)
            << "pathNext: Error computeForwardLiquidity reported success for nothing:"
            << " saOutPass="******" inPass()=" << pathState.inPass();

        if (!pathState.outPass() || !pathState.inPass())
            throw std::runtime_error ("Made no progress.");

        // Calculate relative quality.
        pathState.setQuality(STAmount::getRate (
            pathState.outPass(), pathState.inPass()));

        WriteLog (lsTRACE, RippleCalc)
            << "pathNext: Path after forward: " << pathState.getJson ();
    }
    else
    {
        pathState.setQuality(0);
    }
}