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); }
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); }
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); }
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; }
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"; } } }