コード例 #1
0
ファイル: backupmain.c プロジェクト: tpbirajd/Pipelining-CDT
 int main(int argc, char *argv[])
{         
	   if (argc != 4) 
           {
           printf("Error message - Agruments invalid\n");  
           return -1;
	   }   
           clock=0;
           dispatch_list_counter=0; 
           execute_list_counter=0;
           issue_list_counter=0;
           queue_size=atoi(argv[1]);
           fetch_size=atoi(argv[2]);
           file=argv[3];
           fp = fopen (file,"r"); 
           for(i=0;i<128;i++)
            Register[i].tag=-1;  
           do
          {
           FakeRetire();
           Execute();
           Issue();
           Dispatch();
           fetch();
           clock++;
           }
           while(Advance_cycle());
 
           for(i=0;i<counter;i++)      
                 { 
                    printf(" %d fu{%d} src{%d,%d} dst{%d} IF{%d,1} ID{%d,%d} IS{%d,%d} EX{%d,%d} WB{%d,1} current_state = %d and arrival time is %d type %d\n",i,ROB[i].type,ROB[i].source_1,ROB[i].source_2,ROB[i].destination,ROB[i].IF_time,ROB[i].ID_time,ROB[i].IS_time-ROB[i].ID_time,ROB[i].IS_time,ROB[i].EX_time-ROB[i].IS_time,ROB[i].EX_time,ROB[i].timer,ROB[i].WB_time,ROB[i].current_state,ROB[i].arrival_clock,ROB[i].type);
               }
            return 0;
		
} 
コード例 #2
0
ファイル: Issue.test.cpp プロジェクト: BobWay/rippled
    void testIssueSet ()
    {
        Currency const c1 (1);
        Account   const i1 (1);
        Currency const c2 (2);
        Account   const i2 (2);
        IssueRef const a1 (c1, i1);
        IssueRef const a2 (c2, i2);

        {
            Set c;

            c.insert (a1);
            if (! expect (c.size () == 1)) return;
            c.insert (a2);
            if (! expect (c.size () == 2)) return;

            if (! expect (c.erase (Issue (c1, i2)) == 0)) return;
            if (! expect (c.erase (Issue (c1, i1)) == 1)) return;
            if (! expect (c.erase (Issue (c2, i2)) == 1)) return;
            if (! expect (c.empty ())) return;
        }

        {
            Set c;

            c.insert (a1);
            if (! expect (c.size () == 1)) return;
            c.insert (a2);
            if (! expect (c.size () == 2)) return;

            if (! expect (c.erase (IssueRef (c1, i2)) == 0)) return;
            if (! expect (c.erase (IssueRef (c1, i1)) == 1)) return;
            if (! expect (c.erase (IssueRef (c2, i2)) == 1)) return;
            if (! expect (c.empty ())) return;

    #if STL_SET_HAS_EMPLACE
            c.emplace (c1, i1);
            if (! expect (c.size() == 1)) return;
            c.emplace (c2, i2);
            if (! expect (c.size() == 2)) return;
    #endif
        }
    }
コード例 #3
0
ファイル: Issue.test.cpp プロジェクト: BobWay/rippled
    void testIssueMap ()
    {
        Currency const c1 (1);
        Account   const i1 (1);
        Currency const c2 (2);
        Account   const i2 (2);
        IssueRef const a1 (c1, i1);
        IssueRef const a2 (c2, i2);

        {
            Map c;

            c.insert (std::make_pair (a1, 1));
            if (! expect (c.size () == 1)) return;
            c.insert (std::make_pair (a2, 2));
            if (! expect (c.size () == 2)) return;

            if (! expect (c.erase (Issue (c1, i2)) == 0)) return;
            if (! expect (c.erase (Issue (c1, i1)) == 1)) return;
            if (! expect (c.erase (Issue (c2, i2)) == 1)) return;
            if (! expect (c.empty ())) return;
        }

        {
            Map c;

            c.insert (std::make_pair (a1, 1));
            if (! expect (c.size () == 1)) return;
            c.insert (std::make_pair (a2, 2));
            if (! expect (c.size () == 2)) return;

            if (! expect (c.erase (IssueRef (c1, i2)) == 0)) return;
            if (! expect (c.erase (IssueRef (c1, i1)) == 1)) return;
            if (! expect (c.erase (IssueRef (c2, i2)) == 1)) return;
            if (! expect (c.empty ())) return;
        }
    }
コード例 #4
0
ファイル: CreateOffer.cpp プロジェクト: CCJY/rippled
TER
CreateOffer::doApply ()
{
    if (m_journal.debug) m_journal.debug <<
        "OfferCreate> " << mTxn.getJson (0);

    std::uint32_t const uTxFlags = mTxn.getFlags ();

    bool const bPassive (uTxFlags & tfPassive);
    bool const bImmediateOrCancel (uTxFlags & tfImmediateOrCancel);
    bool const bFillOrKill (uTxFlags & tfFillOrKill);
    bool const bSell  (uTxFlags & tfSell);

    STAmount saTakerPays = mTxn.getFieldAmount (sfTakerPays);
    STAmount saTakerGets = mTxn.getFieldAmount (sfTakerGets);

    if (!saTakerPays.isLegalNet () || !saTakerGets.isLegalNet ())
        return temBAD_AMOUNT;

    auto const& uPaysIssuerID = saTakerPays.getIssuer ();
    auto const& uPaysCurrency = saTakerPays.getCurrency ();

    auto const& uGetsIssuerID = saTakerGets.getIssuer ();
    auto const& uGetsCurrency = saTakerGets.getCurrency ();

    bool const bHaveExpiration (mTxn.isFieldPresent (sfExpiration));
    bool const bHaveCancel (mTxn.isFieldPresent (sfOfferSequence));

    std::uint32_t const uExpiration = mTxn.getFieldU32 (sfExpiration);
    std::uint32_t const uCancelSequence = mTxn.getFieldU32 (sfOfferSequence);

    // FIXME understand why we use SequenceNext instead of current transaction
    //       sequence to determine the transaction. Why is the offer seuqnce
    //       number insufficient?

    std::uint32_t const uAccountSequenceNext = mTxnAccount->getFieldU32 (sfSequence);
    std::uint32_t const uSequence = mTxn.getSequence ();

    const uint256 uLedgerIndex = Ledger::getOfferIndex (mTxnAccountID, uSequence);

    if (m_journal.debug)
    {
        m_journal.debug <<
            "Creating offer node: " << to_string (uLedgerIndex) <<
            " uSequence=" << uSequence;

        if (bImmediateOrCancel)
            m_journal.debug << "Transaction: IoC set.";

        if (bFillOrKill)
            m_journal.debug << "Transaction: FoK set.";
    }

    // This is the original rate of this offer, and is the rate at which it will
    // be placed, even if crossing offers change the amounts.
    std::uint64_t const uRate = STAmount::getRate (saTakerGets, saTakerPays);

    TER terResult (tesSUCCESS);

    // This is the ledger view that we work against. Transactions are applied
    // as we go on processing transactions.
    core::LedgerView& view (mEngine->view ());

    // This is a checkpoint with just the fees paid. If something goes wrong
    // with this transaction, we roll back to this ledger.
    core::LedgerView view_checkpoint (view);

    view.bumpSeq (); // Begin ledger variance.

    SLE::pointer sleCreator = mEngine->entryCache (
        ltACCOUNT_ROOT, Ledger::getAccountRootIndex (mTxnAccountID));

    if (uTxFlags & tfOfferCreateMask)
    {
        if (m_journal.debug) m_journal.debug <<
            "Malformed transaction: Invalid flags set.";

        terResult = temINVALID_FLAG;
    }
    else if (bImmediateOrCancel && bFillOrKill)
    {
        if (m_journal.debug) m_journal.debug <<
            "Malformed transaction: both IoC and FoK set.";

        terResult = temINVALID_FLAG;
    }
    else if (bHaveExpiration && !uExpiration)
    {
        m_journal.warning <<
            "Malformed offer: bad expiration";

        terResult = temBAD_EXPIRATION;
    }
    else if (saTakerPays.isNative () && saTakerGets.isNative ())
    {
        m_journal.warning <<
            "Malformed offer: XRP for XRP";

        terResult = temBAD_OFFER;
    }
    else if (saTakerPays <= zero || saTakerGets <= zero)
    {
        m_journal.warning <<
            "Malformed offer: bad amount";

        terResult = temBAD_OFFER;
    }
    else if (uPaysCurrency == uGetsCurrency && uPaysIssuerID == uGetsIssuerID)
    {
        m_journal.warning <<
            "Malformed offer: redundant offer";

        terResult = temREDUNDANT;
    }
    // We don't allow a non-native currency to use the currency code XRP.
    else if (badCurrency() == uPaysCurrency || badCurrency() == uGetsCurrency)
    {
        m_journal.warning <<
            "Malformed offer: Bad currency.";

        terResult = temBAD_CURRENCY;
    }
    else if (saTakerPays.isNative () != !uPaysIssuerID ||
             saTakerGets.isNative () != !uGetsIssuerID)
    {
        m_journal.warning <<
            "Malformed offer: bad issuer";

        terResult = temBAD_ISSUER;
    }
    else if (view.isGlobalFrozen (uPaysIssuerID) || view.isGlobalFrozen (uGetsIssuerID))
    {
        m_journal.warning <<
            "Offer involves frozen asset";

        terResult = tecFROZEN;
    }
    else if (view.accountFunds (
        mTxnAccountID, saTakerGets, fhZERO_IF_FROZEN) <= zero)
    {
        m_journal.warning <<
            "delay: Offers must be at least partially funded.";

        terResult = tecUNFUNDED_OFFER;
    }
    // This can probably be simplified to make sure that you cancel sequences
    // before the transaction sequence number.
    else if (bHaveCancel && (!uCancelSequence || uAccountSequenceNext - 1 <= uCancelSequence))
    {
        if (m_journal.debug) m_journal.debug <<
            "uAccountSequenceNext=" << uAccountSequenceNext <<
            " uOfferSequence=" << uCancelSequence;

        terResult = temBAD_SEQUENCE;
    }

    if (terResult != tesSUCCESS)
    {
        if (m_journal.debug) m_journal.debug <<
            "final terResult=" << transToken (terResult);

        return terResult;
    }

    // Process a cancellation request that's passed along with an offer.
    if ((terResult == tesSUCCESS) && bHaveCancel)
    {
        uint256 const uCancelIndex (
            Ledger::getOfferIndex (mTxnAccountID, uCancelSequence));
        SLE::pointer sleCancel = mEngine->entryCache (ltOFFER, uCancelIndex);

        // It's not an error to not find the offer to cancel: it might have
        // been consumed or removed as we are processing.
        if (sleCancel)
        {
            m_journal.warning <<
                "Cancelling order with sequence " << uCancelSequence;

            terResult = view.offerDelete (sleCancel);
        }
    }

    // Expiration is defined in terms of the close time of the parent ledger,
    // because we definitively know the time that it closed but we do not
    // know the closing time of the ledger that is under construction.
    if (bHaveExpiration &&
        (mEngine->getLedger ()->getParentCloseTimeNC () >= uExpiration))
    {
        return tesSUCCESS;
    }

    // Make sure that we are authorized to hold what the taker will pay us.
    if (terResult == tesSUCCESS && !saTakerPays.isNative ())
        terResult = checkAcceptAsset (Issue (uPaysCurrency, uPaysIssuerID));

    bool crossed = false;
    bool const bOpenLedger (mParams & tapOPEN_LEDGER);

    if (terResult == tesSUCCESS)
    {
        // We reverse gets and pays because during offer crossing we are taking.
        core::Amounts const taker_amount (saTakerGets, saTakerPays);

        // The amount of the offer that we will need to place, after we finish
        // offer crossing processing. It may be equal to the original amount,
        // empty (fully crossed), or something in-between.
        core::Amounts place_offer;

        std::tie(terResult, place_offer) = crossOffers (view, taker_amount);

        if (terResult == tecFAILED_PROCESSING && bOpenLedger)
            terResult = telFAILED_PROCESSING;

        if (terResult == tesSUCCESS)
        {
            // We now need to reduce the offer by the cross flow. We reverse
            // in and out here, since during crossing we were takers.
            assert (saTakerPays.getCurrency () == place_offer.out.getCurrency ());
            assert (saTakerPays.getIssuer () == place_offer.out.getIssuer ());
            assert (saTakerGets.getCurrency () == place_offer.in.getCurrency ());
            assert (saTakerGets.getIssuer () == place_offer.in.getIssuer ());

            if (taker_amount != place_offer)
                crossed = true;

            if (m_journal.debug)
            {
                m_journal.debug << "Offer Crossing: " << transToken (terResult);

                if (terResult == tesSUCCESS)
                {
                    m_journal.debug <<
                        "    takerPays: " << saTakerPays.getFullText () <<
                        " -> " << place_offer.out.getFullText ();
                    m_journal.debug <<
                        "    takerGets: " << saTakerGets.getFullText () <<
                        " -> " << place_offer.in.getFullText ();
                }
            }

            saTakerPays = place_offer.out;
            saTakerGets = place_offer.in;
        }
    }

    if (terResult != tesSUCCESS)
    {
        m_journal.debug <<
            "final terResult=" << transToken (terResult);

        return terResult;
    }

    if (m_journal.debug)
    {
        m_journal.debug <<
            "takeOffers: saTakerPays=" <<saTakerPays.getFullText ();
        m_journal.debug <<
            "takeOffers: saTakerGets=" << saTakerGets.getFullText ();
        m_journal.debug <<
            "takeOffers: mTxnAccountID=" <<
            to_string (mTxnAccountID);
        m_journal.debug <<
            "takeOffers:         FUNDS=" << view.accountFunds (
            mTxnAccountID, saTakerGets, fhZERO_IF_FROZEN).getFullText ();
    }

    if (saTakerPays < zero || saTakerGets < zero)
    {
        // Earlier, we verified that the amounts, as specified in the offer,
        // were not negative. That they are now suggests that something went
        // very wrong with offer crossing.
        m_journal.fatal << (crossed ? "Partially consumed" : "Full") <<
            " offer has negative component:" <<
            " pays=" << saTakerPays.getFullText () <<
            " gets=" << saTakerGets.getFullText ();

        assert (saTakerPays >= zero);
        assert (saTakerGets >= zero);
        return tefINTERNAL;
    }

    if (bFillOrKill && (saTakerPays != zero || saTakerGets != zero))
    {
        // Fill or kill and have leftovers.
        view.swapWith (view_checkpoint); // Restore with just fees paid.
        return tesSUCCESS;
    }

    // What the reserve would be if this offer was placed.
    auto const accountReserve (mEngine->getLedger ()->getReserve (
        sleCreator->getFieldU32 (sfOwnerCount) + 1));

    if (saTakerPays == zero ||                // Wants nothing more.
        saTakerGets == zero ||                // Offering nothing more.
        bImmediateOrCancel)                   // Do not persist.
    {
        // Complete as is.
    }
    else if (mPriorBalance.getNValue () < accountReserve)
    {
        // If we are here, the signing account had an insufficient reserve
        // *prior* to our processing. We use the prior balance to simplify
        // client writing and make the user experience better.

        if (bOpenLedger) // Ledger is not final, can vote no.
        {
            // Hope for more reserve to come in or more offers to consume. If we
            // specified a local error this transaction will not be retried, so
            // specify a tec to distribute the transaction and allow it to be
            // retried. In particular, it may have been successful to a
            // degree (partially filled) and if it hasn't, it might succeed.
            terResult = tecINSUF_RESERVE_OFFER;
        }
        else if (!crossed)
        {
            // Ledger is final, insufficent reserve to create offer, processed
            // nothing.
            terResult = tecINSUF_RESERVE_OFFER;
        }
        else
        {
            // Ledger is final, insufficent reserve to create offer, processed
            // something.

            // Consider the offer unfunded. Treat as tesSUCCESS.
        }
    }
    else
    {
        assert (saTakerPays > zero);
        assert (saTakerGets > zero);

        // We need to place the remainder of the offer into its order book.
        if (m_journal.debug) m_journal.debug <<
            "offer not fully consumed:" <<
            " saTakerPays=" << saTakerPays.getFullText () <<
            " saTakerGets=" << saTakerGets.getFullText ();

        std::uint64_t uOwnerNode;
        std::uint64_t uBookNode;
        uint256 uDirectory;

        // Add offer to owner's directory.
        terResult = view.dirAdd (uOwnerNode,
            Ledger::getOwnerDirIndex (mTxnAccountID), uLedgerIndex,
            std::bind (
                &Ledger::ownerDirDescriber, std::placeholders::_1,
                std::placeholders::_2, mTxnAccountID));

        if (tesSUCCESS == terResult)
        {
            // Update owner count.
            view.ownerCountAdjust (mTxnAccountID, 1, sleCreator);

            uint256 const uBookBase (Ledger::getBookBase (
                {{uPaysCurrency, uPaysIssuerID},
                    {uGetsCurrency, uGetsIssuerID}}));

            if (m_journal.debug) m_journal.debug <<
                "adding to book: " << to_string (uBookBase) <<
                " : " << saTakerPays.getHumanCurrency () <<
                "/" << to_string (saTakerPays.getIssuer ()) <<
                " -> " << saTakerGets.getHumanCurrency () <<
                "/" << to_string (saTakerGets.getIssuer ());

            // We use the original rate to place the offer.
            uDirectory = Ledger::getQualityIndex (uBookBase, uRate);

            // Add offer to order book.
            terResult = view.dirAdd (uBookNode, uDirectory, uLedgerIndex,
                std::bind (
                    &Ledger::qualityDirDescriber, std::placeholders::_1,
                    std::placeholders::_2, saTakerPays.getCurrency (),
                    uPaysIssuerID, saTakerGets.getCurrency (),
                    uGetsIssuerID, uRate));
        }

        if (tesSUCCESS == terResult)
        {
            if (m_journal.debug)
            {
                m_journal.debug <<
                    "sfAccount=" <<
                    to_string (mTxnAccountID);
                m_journal.debug <<
                    "uPaysIssuerID=" <<
                    to_string (uPaysIssuerID);
                m_journal.debug <<
                    "uGetsIssuerID=" <<
                    to_string (uGetsIssuerID);
                m_journal.debug <<
                    "saTakerPays.isNative()=" <<
                    saTakerPays.isNative ();
                m_journal.debug <<
                    "saTakerGets.isNative()=" <<
                    saTakerGets.isNative ();
                m_journal.debug <<
                    "uPaysCurrency=" <<
                    saTakerPays.getHumanCurrency ();
                m_journal.debug <<
                    "uGetsCurrency=" <<
                    saTakerGets.getHumanCurrency ();
            }

            SLE::pointer sleOffer (mEngine->entryCreate (ltOFFER, uLedgerIndex));

            sleOffer->setFieldAccount (sfAccount, mTxnAccountID);
            sleOffer->setFieldU32 (sfSequence, uSequence);
            sleOffer->setFieldH256 (sfBookDirectory, uDirectory);
            sleOffer->setFieldAmount (sfTakerPays, saTakerPays);
            sleOffer->setFieldAmount (sfTakerGets, saTakerGets);
            sleOffer->setFieldU64 (sfOwnerNode, uOwnerNode);
            sleOffer->setFieldU64 (sfBookNode, uBookNode);

            if (uExpiration)
                sleOffer->setFieldU32 (sfExpiration, uExpiration);

            if (bPassive)
                sleOffer->setFlag (lsfPassive);

            if (bSell)
                sleOffer->setFlag (lsfSell);

            if (m_journal.debug) m_journal.debug <<
                "final terResult=" << transToken (terResult) <<
                " sleOffer=" << sleOffer->getJson (0);
        }
    }

    if (terResult != tesSUCCESS)
    {
        m_journal.debug <<
            "final terResult=" << transToken (terResult);
    }

    return terResult;
}
コード例 #5
0
// This function gets executed in each thread
void *startFunction(void *socketnumber)
{
	int s = *(int *)socketnumber;	
	char message[1000];
	
	//Send ACCEPTED to client acknowledge the client about the connection.
	strcpy(message, "ACCEPTED");
    send(s , message , strlen(message),0);

    int r;
    char query[1000];
    //Wait for client query.....
    while( (r = recv(s , query , 1000 , 0)) > 0 )
    {

    	//SEARCH for search, INSERT for insert, ISSUE for issue, RENEW for renew, RESERVE for reserve, EXIT for exit. 
    	if (query[0] == '1')
    	{
            //If writer is greater than 0 then donot allow any readers to enter.
            while(writers>0);
            readers++;
    		send(s, "1", strlen("1"),0);
    		//Receive Book Name in 
    		r = recv(s,query,1000,0);
            query[r] = '\0';
    		if (r==0 || r==-1)
    		{
    			break;
    		}
    		Search(query, message, myLibrary,nbooks);
            send(s,message,strlen(message),0);
            readers--;
    	}
    	else if (query[0] == '2')
    	{
            writers++;
            int thisWriter = turns++;
            //Wait for all the earliar readers to finish
            while(readers>0 || turn != thisWriter);//Do Nothing
    		send(s, "1", strlen("1"),0);
    		r = recv(s,query,1000,0);
            query[r] = '\0';
    		if (r==0 || r==-1)
    		{
    			break;
    		}
    		myLibrary = Insert(query,myLibrary,nbooks);
            send(s,"1",strlen("1"),0);
            writers--;
            turn++;
    	}
    	else if (query[0] == '3')
    	{
    		send(s, "1", strlen("1"),0);
    		r = recv(s,query,1000,0);
    		if (r==0 || r==-1)
    		{
    			break;
    		}
    		int result = Issue(atoi(query),message,myLibrary,nbooks);            
            send(s,message,strlen(message),0);
    	}
    	else if (query[0] == '4')
    	{
    		send(s, "1", strlen("1"),0);
    		r = recv(s,query,1000,0);
    		if (r==0 || r==-1)
    		{
    			break;
    		}
    		int result = Renew(atoi(query),message,myLibrary,nbooks);
            send(s,message,strlen(message),0);
    	}
    	else if (query[0] == '5')
    	{
    		send(s, "1", strlen("1"),0);
    		r = recv(s,query,1000,0);
    		if (r==0 || r==-1)
    		{
    			break;
    		}
    		int result = Reserve(atoi(query),message,myLibrary,nbooks);
            send(s,message,strlen(message),0);
    	}
    	else if (query[0] == '6')
    	{
            writers++;
            int thisWriter = turns++;
            send(s, "1", strlen("1"),0);
            int result = Exit(myLibrary,nbooks);
        }
        else if (query[0] == '7')
        {
            break;
        }
    }
     
    if(r == 0)
    {
        printf("Client %d disconnected\n",s );
    }
    else if(r == -1)
    {
        printf("Receive Failed from clien %d",s);
    }
    printf("Client %d disconnected\n",s );
    return(0);
}
コード例 #6
0
ファイル: Issue.test.cpp プロジェクト: BobWay/rippled
    void testIssueType ()
    {
        Currency const c1 (1); Account const i1 (1);
        Currency const c2 (2); Account const i2 (2);
        Currency const c3 (3); Account const i3 (3);

        expect (Issue (c1, i1) != Issue (c2, i1));
        expect (Issue (c1, i1) <  Issue (c2, i1));
        expect (Issue (c1, i1) <= Issue (c2, i1));
        expect (Issue (c2, i1) <= Issue (c2, i1));
        expect (Issue (c2, i1) == Issue (c2, i1));
        expect (Issue (c2, i1) >= Issue (c2, i1));
        expect (Issue (c3, i1) >= Issue (c2, i1));
        expect (Issue (c3, i1) >  Issue (c2, i1));
        expect (Issue (c1, i1) != Issue (c1, i2));
        expect (Issue (c1, i1) <  Issue (c1, i2));
        expect (Issue (c1, i1) <= Issue (c1, i2));
        expect (Issue (c1, i2) <= Issue (c1, i2));
        expect (Issue (c1, i2) == Issue (c1, i2));
        expect (Issue (c1, i2) >= Issue (c1, i2));
        expect (Issue (c1, i3) >= Issue (c1, i2));
        expect (Issue (c1, i3) >  Issue (c1, i2));

        std::hash <Issue> hash;

        expect (hash (Issue (c1, i1)) == hash (Issue (c1, i1)));
        expect (hash (Issue (c1, i2)) == hash (Issue (c1, i2)));
        expect (hash (Issue (c1, i3)) == hash (Issue (c1, i3)));
        expect (hash (Issue (c2, i1)) == hash (Issue (c2, i1)));
        expect (hash (Issue (c2, i2)) == hash (Issue (c2, i2)));
        expect (hash (Issue (c2, i3)) == hash (Issue (c2, i3)));
        expect (hash (Issue (c3, i1)) == hash (Issue (c3, i1)));
        expect (hash (Issue (c3, i2)) == hash (Issue (c3, i2)));
        expect (hash (Issue (c3, i3)) == hash (Issue (c3, i3)));
        expect (hash (Issue (c1, i1)) != hash (Issue (c1, i2)));
        expect (hash (Issue (c1, i1)) != hash (Issue (c1, i3)));
        expect (hash (Issue (c1, i1)) != hash (Issue (c2, i1)));
        expect (hash (Issue (c1, i1)) != hash (Issue (c2, i2)));
        expect (hash (Issue (c1, i1)) != hash (Issue (c2, i3)));
        expect (hash (Issue (c1, i1)) != hash (Issue (c3, i1)));
        expect (hash (Issue (c1, i1)) != hash (Issue (c3, i2)));
        expect (hash (Issue (c1, i1)) != hash (Issue (c3, i3)));
    }
コード例 #7
0
ファイル: Flow.cpp プロジェクト: bachase/rippled
path::RippleCalc::Output
flow (
    PaymentSandbox& sb,
    STAmount const& deliver,
    AccountID const& src,
    AccountID const& dst,
    STPathSet const& paths,
    bool defaultPaths,
    bool partialPayment,
    bool ownerPaysTransferFee,
    boost::optional<Quality> const& limitQuality,
    boost::optional<STAmount> const& sendMax,
    beast::Journal j,
    path::detail::FlowDebugInfo* flowDebugInfo)
{
    Issue const srcIssue = [&] {
        if (sendMax)
            return sendMax->issue ();
        if (!isXRP (deliver.issue ().currency))
            return Issue (deliver.issue ().currency, src);
        return xrpIssue ();
    }();

    Issue const dstIssue = deliver.issue ();

    boost::optional<Issue> sendMaxIssue;
    if (sendMax)
        sendMaxIssue = sendMax->issue ();

    // convert the paths to a collection of strands. Each strand is the collection
    // of account->account steps and book steps that may be used in this payment.
    auto sr = toStrands (sb, src, dst, dstIssue, sendMaxIssue, paths,
        defaultPaths, ownerPaysTransferFee, j);

    if (sr.first != tesSUCCESS)
    {
        path::RippleCalc::Output result;
        result.setResult (sr.first);
        return result;
    }

    auto& strands = sr.second;

    if (j.trace())
    {
        j.trace() << "\nsrc: " << src << "\ndst: " << dst
            << "\nsrcIssue: " << srcIssue << "\ndstIssue: " << dstIssue;
        j.trace() << "\nNumStrands: " << strands.size ();
        for (auto const& curStrand : strands)
        {
            j.trace() << "NumSteps: " << curStrand.size ();
            for (auto const& step : curStrand)
            {
                j.trace() << '\n' << *step << '\n';
            }
        }
    }

    const bool srcIsXRP = isXRP (srcIssue.currency);
    const bool dstIsXRP = isXRP (dstIssue.currency);

    auto const asDeliver = toAmountSpec (deliver);

    // The src account may send either xrp or iou. The dst account may receive
    // either xrp or iou. Since XRP and IOU amounts are represented by different
    // types, use templates to tell `flow` about the amount types.
    if (srcIsXRP && dstIsXRP)
    {
        return finishFlow (sb, srcIssue, dstIssue,
            flow<XRPAmount, XRPAmount> (
                sb, strands, asDeliver.xrp, defaultPaths, partialPayment,
                limitQuality, sendMax, j, flowDebugInfo));
    }

    if (srcIsXRP && !dstIsXRP)
    {
        return finishFlow (sb, srcIssue, dstIssue,
            flow<XRPAmount, IOUAmount> (
                sb, strands, asDeliver.iou, defaultPaths, partialPayment,
                limitQuality, sendMax, j, flowDebugInfo));
    }

    if (!srcIsXRP && dstIsXRP)
    {
        return finishFlow (sb, srcIssue, dstIssue,
            flow<IOUAmount, XRPAmount> (
                sb, strands, asDeliver.xrp, defaultPaths, partialPayment,
                limitQuality, sendMax, j, flowDebugInfo));
    }

    assert (!srcIsXRP && !dstIsXRP);
    return finishFlow (sb, srcIssue, dstIssue,
        flow<IOUAmount, IOUAmount> (
            sb, strands, asDeliver.iou, defaultPaths, partialPayment,
            limitQuality, sendMax, j, flowDebugInfo));

}