Example #1
0
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);
    }
}