Example #1
0
std::unique_ptr <Transactor> make_CreateOffer (
    SerializedTransaction const& txn,
    TransactionEngineParams params,
    TransactionEngine* engine)
{
#if RIPPLE_ENABLE_AUTOBRIDGING
    STAmount const& amount_in = txn.getFieldAmount (sfTakerPays);
    STAmount const& amount_out = txn.getFieldAmount (sfTakerGets);

    // Autobridging is only in effect when an offer does not involve XRP
    if (!amount_in.isNative() && !amount_out.isNative ())
        return std::make_unique <CreateOfferBridged> (txn, params, engine);
#endif

    return std::make_unique <CreateOfferDirect> (txn, params, engine);
}
Example #2
0
TER Interpreter::interpret(Contract* contract,const SerializedTransaction& txn,std::vector<unsigned char>& code)
{
	mContract=contract;
	mCode=&code;
	mTotalFee=0;
	mInstructionPointer=0;
	while(mInstructionPointer<code.size())
	{
		unsigned int fun=(*mCode)[mInstructionPointer];
		mInstructionPointer++;

		if(fun>=mFunctionTable.size()) 
		{
			// TODO: log
			return(temMALFORMED);  // TODO: is this actually what we want to do?
		}

		mTotalFee += mFunctionTable[ fun ]->getFee(); // FIXME: You can't use fees this way, there's no consensus
		if(mTotalFee>txn.getTransactionFee().getNValue())
		{
			// TODO: log
			return(telINSUF_FEE_P);
		}else 
		{
			if(!mFunctionTable[ fun ]->work(this))
			{
				// TODO: log
				return(temMALFORMED);  // TODO: is this actually what we want to do?
			}
		}
	}
	return(tesSUCCESS);
}
Example #3
0
UPTR_T<Transactor> Transactor::makeTransactor (const SerializedTransaction& txn, TransactionEngineParams params, TransactionEngine* engine)
{
    switch (txn.getTxnType ())
    {
    case ttPAYMENT:
        return UPTR_T<Transactor> (new PaymentTransactor (txn, params, engine));

    case ttACCOUNT_SET:
        return UPTR_T<Transactor> (new AccountSetTransactor (txn, params, engine));

    case ttREGULAR_KEY_SET:
        return UPTR_T<Transactor> (new RegularKeySetTransactor (txn, params, engine));

    case ttTRUST_SET:
        return UPTR_T<Transactor> (new TrustSetTransactor (txn, params, engine));

    case ttOFFER_CREATE:
        return UPTR_T<Transactor> (new OfferCreateTransactor (txn, params, engine));

    case ttOFFER_CANCEL:
        return UPTR_T<Transactor> (new OfferCancelTransactor (txn, params, engine));

    case ttWALLET_ADD:
        return UPTR_T<Transactor> (new WalletAddTransactor (txn, params, engine));

    case ttFEATURE:
    case ttFEE:
        return UPTR_T<Transactor> (new ChangeTransactor (txn, params, engine));

    default:
        return UPTR_T<Transactor> ();
    }
}
std::unique_ptr<Transactor> Transactor::makeTransactor (
    SerializedTransaction const& txn,
    TransactionEngineParams params,
    TransactionEngine* engine)
{
    switch (txn.getTxnType ())
    {
    case ttPAYMENT:
        return std::unique_ptr<Transactor> (
            new PaymentTransactor (txn, params, engine));

    case ttGENESIS:
        return std::unique_ptr<Transactor> (
            new GenesisTransactor (txn, params, engine));

    case ttTRANSFER:
        return std::unique_ptr<Transactor> (
            new TransferTransactor (txn, params, engine));

    case ttINFLATION:
		return std::unique_ptr<Transactor>(
			new InflationTransactor(txn, params, engine));

    case ttACCOUNT_SET:
        return std::unique_ptr<Transactor> (
            new AccountSetTransactor (txn, params, engine));

    case ttACCOUNT_MERGE:
        return std::unique_ptr<Transactor>(
            new AccountMergeTransactor (txn, params, engine));

    case ttREGULAR_KEY_SET:
        return std::unique_ptr<Transactor> (
            new RegularKeySetTransactor (txn, params, engine));

    case ttTRUST_SET:
        return std::unique_ptr<Transactor> (
            new TrustSetTransactor (txn, params, engine));

    case ttOFFER_CREATE:
        return make_OfferCreateTransactor (txn, params, engine);

    case ttOFFER_CANCEL:
        return std::unique_ptr<Transactor> (
            new OfferCancelTransactor (txn, params, engine));

    case ttWALLET_ADD:
        return std::unique_ptr<Transactor> (
            new WalletAddTransactor (txn, params, engine));

    case ttAMENDMENT:
    case ttFEE:
        return std::unique_ptr<Transactor> (
            new ChangeTransactor (txn, params, engine));

    default:
        return std::unique_ptr<Transactor> ();
    }
}
/**
 * Decode a JSON value representing a ledger (as found in a dump file) into
 * a 3-tuple of: #1 a Ledger object, #2 a SHAMap holding a set of
 * transactions, and #3 a vector of transaction IDs indicating the order
 * that the transactions in the SHAMap were applied in the Ledger.
 */
static std::tuple<Ledger::pointer, SHAMap::pointer, std::vector<uint256> >
loadLedgerAndTransactionsFromJSON(Application& app, Json::Value const& j)
{
    require (j.isMember ("raw") && j["raw"].isString (),
             "JSON ledger \"raw\" entry missing or non-string");

    std::pair<Blob, bool> ledgerBlob = strUnHex (j["raw"].asString ());
    require (ledgerBlob.second, "Error decoding ledger \"raw\" field ");

    Ledger::pointer ledger = boost::make_shared<Ledger> (ledgerBlob.first, true);

    require (j.isMember ("txs") && j["txs"].isArray(),
             "JSON ledger \"txs\" entry missing or non-array");

    // Fill a SHAMap full of the current transactions.
    SHAMap::pointer txSet =
        boost::make_shared<SHAMap> (smtTRANSACTION, app.getFullBelowCache());

    std::vector<uint256> txOrder;

    for (auto const& jtx : j["txs"])
    {
        std::pair<Blob, bool> txBlob = strUnHex (jtx.asString ());
        require (txBlob.second, "Error decoding tx");

        Serializer ser (txBlob.first);
        SerializerIterator sit (ser);
        SerializedTransaction stx (sit);

        auto txID = stx.getTransactionID();
        require (txSet->addItem (SHAMapItem (txID, ser), true, true),
                 "Error adding transaction");
        txOrder.push_back (txID);
    }
    return std::make_tuple (ledger, txSet, txOrder);
}
Example #6
0
bool TransactionEngine::checkInvariants (TER result, const SerializedTransaction& txn, TransactionEngineParams params)
{
#if 0
    uint32                  txnSeq      = txn.getFieldU32 (sfSequence);

    LedgerEntryAction       leaAction;

    uint256                 srcActId    = Ledger::getAccountRootIndex (txn.getFieldAccount (sfAccount));
    SLE::pointer            origSrcAct  = mLedger->getSLE (srcActId);
    SLE::pointer            newSrcAct   = mNodes.getEntry (srcActId, leaAction);

    if (!newSrcAct || !origSrcAct)
    {
        WriteLog (lsFATAL, TransactionEngine) << "Transaction created or destroyed its issuing account";
        assert (false);
        return tefINTERNAL;
    }

    if ((newSrcAct->getFieldU32 (sfSequence) != (txnSeq + 1)) ||
            (origSrcAct->getFieldU32 (sfSequence) != txnSeq))
    {
        WriteLog (lsFATAL, TransactionEngine) << "Transaction mangles sequence numbers";
        WriteLog (lsFATAL, TransactionEngine) << "t:" << txnSeq << " o: " << origSrcAct->getFieldU32 (sfSequence)
                                              << " n: " << newSrcAct->getFieldU32 (sfSequence);
        assert (false);
        return tefINTERNAL;
    }

    int64 xrpChange = txn.getFieldAmount (sfFee).getSNValue ();

    for (LedgerEntrySet::const_iterator it = mNodes.begin (), end = mNodes.end (); it != end; ++it)
    {
        const LedgerEntrySetEntry& entry = it->second;

        if (entry.mAction == taaMODIFY)
        {
#if 0

            if (entry.mEntry->getType () == ltRIPPLE_STATE)
            {
                // if this transaction pushes a ripple state over its limit, make sure it also modifies
                // an offer placed by that same user
            }

#endif

            if (entry.mEntry->getType () == ltACCOUNT_ROOT)
            {
                // account modified
                xrpChange += entry.mEntry->getFieldAmount (sfBalance).getSNValue ();
                xrpChange -= mLedger->getSLE (it->first)->getFieldAmount (sfBalance).getSNValue ();
            }
        }
        else if (entry.mAction == taaCREATE)
        {
            if (entry.mEntry->getType () == ltRIPPLE_STATE)
            {
                if (entry.mEntry->getFieldAmount (sfLowLimit).getIssuer () ==
                        entry.mEntry->getFieldAmount (sfHighLimit).getIssuer ())
                {
                    WriteLog (lsFATAL, TransactionEngine) << "Ripple line to self";
                    assert (false);
                    return tefINTERNAL;
                }
            }

            if (entry.mEntry->getType () == ltACCOUNT_ROOT) // account created
                xrpChange += entry.mEntry->getFieldAmount (sfBalance).getSNValue ();
        }
    }

    if (xrpChange != 0)
    {
        WriteLog (lsFATAL, TransactionEngine) << "Transaction creates/destroys XRP";
        assert (false);
        return tefINTERNAL;
    }

#endif

    return true;
}
Example #7
0
void
FeeVoteImpl::doVoting (Ledger::ref lastClosedLedger,
    SHAMap::ref initialPosition)
{
    // LCL must be flag ledger
    assert ((lastClosedLedger->getLedgerSeq () % 256) == 0);

    detail::VotableInteger<std::uint64_t> baseFeeVote (
        lastClosedLedger->getBaseFee (), target_.reference_fee);

    detail::VotableInteger<std::uint32_t> baseReserveVote (
        lastClosedLedger->getReserve (0), target_.account_reserve);

    detail::VotableInteger<std::uint32_t> incReserveVote (
        lastClosedLedger->getReserveInc (), target_.owner_reserve);

    // get validations for ledger before flag
    ValidationSet const set =
        getApp().getValidations ().getValidations (
            lastClosedLedger->getParentHash ());
    for (auto const& e : set)
    {
        SerializedValidation const& val = *e.second;

        if (val.isTrusted ())
        {
            if (val.isFieldPresent (sfBaseFee))
            {
                baseFeeVote.addVote (val.getFieldU64 (sfBaseFee));
            }
            else
            {
                baseFeeVote.noVote ();
            }

            if (val.isFieldPresent (sfReserveBase))
            {
                baseReserveVote.addVote (val.getFieldU32 (sfReserveBase));
            }
            else
            {
                baseReserveVote.noVote ();
            }

            if (val.isFieldPresent (sfReserveIncrement))
            {
                incReserveVote.addVote (val.getFieldU32 (sfReserveIncrement));
            }
            else
            {
                incReserveVote.noVote ();
            }
        }
    }

    // choose our positions
    std::uint64_t const baseFee = baseFeeVote.getVotes ();
    std::uint32_t const baseReserve = baseReserveVote.getVotes ();
    std::uint32_t const incReserve = incReserveVote.getVotes ();

    // add transactions to our position
    if ((baseFee != lastClosedLedger->getBaseFee ()) ||
            (baseReserve != lastClosedLedger->getReserve (0)) ||
            (incReserve != lastClosedLedger->getReserveInc ()))
    {
        if (journal_.warning) journal_.warning <<
            "We are voting for a fee change: " << baseFee <<
            "/" << baseReserve <<
            "/" << incReserve;

        SerializedTransaction trans (ttFEE);
        trans.setFieldAccount (sfAccount, Account ());
        trans.setFieldU64 (sfBaseFee, baseFee);
        trans.setFieldU32 (sfReferenceFeeUnits, 10);
        trans.setFieldU32 (sfReserveBase, baseReserve);
        trans.setFieldU32 (sfReserveIncrement, incReserve);

        uint256 txID = trans.getTransactionID ();

        if (journal_.warning)
            journal_.warning << "Vote: " << txID;

        Serializer s;
        trans.add (s, true);

        SHAMapItem::pointer tItem = std::make_shared<SHAMapItem> (
            txID, s.peekData ());

        if (!initialPosition->addGiveItem (tItem, true, false))
        {
            if (journal_.warning) journal_.warning <<
                "Ledger already had fee change";
        }
    }
}