void OrderBookDB::addOrderBook(Book const& book) { bool toXDV = isXDV (book.out); ScopedLockType sl (mLock); if (toXDV) { // We don't want to search through all the to-XDV or from-XDV order // books! for (auto ob: mSourceMap[book.in]) { if (isXDV (ob->getCurrencyOut ())) // also to XDV return; } } else { for (auto ob: mDestMap[book.out]) { if (ob->getCurrencyIn() == book.in.currency && ob->getIssuerIn() == book.in.account) { return; } } } uint256 index = getBookBase(book); auto orderBook = std::make_shared<OrderBook> (index, book); mSourceMap[book.in].push_back (orderBook); mDestMap[book.out].push_back (orderBook); if (toXDV) mXDVBooks.insert(book.in); }
static void updateHelper (SLE::ref entry, hash_set< uint256 >& seen, OrderBookDB::IssueToOrderBook& destMap, OrderBookDB::IssueToOrderBook& sourceMap, hash_set< Issue >& XDVBooks, int& books) { if (entry->getType () == ltDIR_NODE && entry->isFieldPresent (sfExchangeRate) && entry->getFieldH256 (sfRootIndex) == entry->getIndex()) { Book book; book.in.currency.copyFrom (entry->getFieldH160 (sfTakerPaysCurrency)); book.in.account.copyFrom (entry->getFieldH160 (sfTakerPaysIssuer)); book.out.account.copyFrom (entry->getFieldH160 (sfTakerGetsIssuer)); book.out.currency.copyFrom (entry->getFieldH160 (sfTakerGetsCurrency)); uint256 index = getBookBase (book); if (seen.insert (index).second) { auto orderBook = std::make_shared<OrderBook> (index, book); sourceMap[book.in].push_back (orderBook); destMap[book.out].push_back (orderBook); if (isXDV(book.out)) XDVBooks.insert(book.in); ++books; } } }
std::vector<RippleAddress> STTx::getMentionedAccounts () const { std::vector<RippleAddress> accounts; for (auto const& it : peekData ()) { if (auto sa = dynamic_cast<STAccount const*> (&it)) { auto const na = sa->getValueNCA (); if (std::find (accounts.cbegin (), accounts.cend (), na) == accounts.cend ()) accounts.push_back (na); } else if (auto sa = dynamic_cast<STAmount const*> (&it)) { auto const& issuer = sa->getIssuer (); if (isXDV (issuer)) continue; RippleAddress na; na.setAccountID (issuer); if (std::find (accounts.cbegin (), accounts.cend (), na) == accounts.cend ()) accounts.push_back (na); } } return accounts; }
Json::Value trust (Account const& account, STAmount const& amount) { if (isXDV(amount)) throw std::runtime_error( "trust() requires IOU"); Json::Value jv; jv[jss::Account] = account.human(); jv[jss::LimitAmount] = amount.getJson(0); jv[jss::TransactionType] = "TrustSet"; jv[jss::Flags] = 0; // tfClearNoDivvy; return jv; }
Json::Value doBookOffers (RPC::Context& context) { // VFALCO TODO Here is a terrible place for this kind of business // logic. It needs to be moved elsewhere and documented, // and encapsulated into a function. if (getApp().getJobQueue ().getJobCountGE (jtCLIENT) > 200) return rpcError (rpcTOO_BUSY); Ledger::pointer lpLedger; Json::Value jvResult ( RPC::lookupLedger (context.params, lpLedger, context.netOps)); if (!lpLedger) return jvResult; if (!context.params.isMember (jss::taker_pays)) return RPC::missing_field_error (jss::taker_pays); if (!context.params.isMember (jss::taker_gets)) return RPC::missing_field_error (jss::taker_gets); if (!context.params[jss::taker_pays].isObject ()) return RPC::object_field_error (jss::taker_pays); if (!context.params[jss::taker_gets].isObject ()) return RPC::object_field_error (jss::taker_gets); Json::Value const& taker_pays (context.params[jss::taker_pays]); if (!taker_pays.isMember (jss::currency)) return RPC::missing_field_error ("taker_pays.currency"); if (! taker_pays [jss::currency].isString ()) return RPC::expected_field_error ("taker_pays.currency", "string"); Json::Value const& taker_gets = context.params[jss::taker_gets]; if (! taker_gets.isMember (jss::currency)) return RPC::missing_field_error ("taker_gets.currency"); if (! taker_gets [jss::currency].isString ()) return RPC::expected_field_error ("taker_gets.currency", "string"); Currency pay_currency; if (!to_currency (pay_currency, taker_pays [jss::currency].asString ())) { WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency."; return RPC::make_error (rpcSRC_CUR_MALFORMED, "Invalid field 'taker_pays.currency', bad currency."); } Currency get_currency; if (!to_currency (get_currency, taker_gets [jss::currency].asString ())) { WriteLog (lsINFO, RPCHandler) << "Bad taker_gets currency."; return RPC::make_error (rpcDST_AMT_MALFORMED, "Invalid field 'taker_gets.currency', bad currency."); } AccountID pay_issuer; if (taker_pays.isMember (jss::issuer)) { if (! taker_pays [jss::issuer].isString()) return RPC::expected_field_error ("taker_pays.issuer", "string"); if (!to_issuer( pay_issuer, taker_pays [jss::issuer].asString ())) return RPC::make_error (rpcSRC_ISR_MALFORMED, "Invalid field 'taker_pays.issuer', bad issuer."); if (pay_issuer == noAccount ()) return RPC::make_error (rpcSRC_ISR_MALFORMED, "Invalid field 'taker_pays.issuer', bad issuer account one."); } else { pay_issuer = xdvAccount (); } if (isXDV (pay_currency) && ! isXDV (pay_issuer)) return RPC::make_error ( rpcSRC_ISR_MALFORMED, "Unneeded field 'taker_pays.issuer' for " "XDV currency specification."); if (!isXDV (pay_currency) && isXDV (pay_issuer)) return RPC::make_error (rpcSRC_ISR_MALFORMED, "Invalid field 'taker_pays.issuer', expected non-XDV issuer."); AccountID get_issuer; if (taker_gets.isMember (jss::issuer)) { if (! taker_gets [jss::issuer].isString()) return RPC::expected_field_error ("taker_gets.issuer", "string"); if (! to_issuer ( get_issuer, taker_gets [jss::issuer].asString ())) return RPC::make_error (rpcDST_ISR_MALFORMED, "Invalid field 'taker_gets.issuer', bad issuer."); if (get_issuer == noAccount ()) return RPC::make_error (rpcDST_ISR_MALFORMED, "Invalid field 'taker_gets.issuer', bad issuer account one."); } else { get_issuer = xdvAccount (); } if (isXDV (get_currency) && ! isXDV (get_issuer)) return RPC::make_error (rpcDST_ISR_MALFORMED, "Unneeded field 'taker_gets.issuer' for " "XDV currency specification."); if (!isXDV (get_currency) && isXDV (get_issuer)) return RPC::make_error (rpcDST_ISR_MALFORMED, "Invalid field 'taker_gets.issuer', expected non-XDV issuer."); DivvyAddress raTakerID; if (context.params.isMember (jss::taker)) { if (! context.params [jss::taker].isString ()) return RPC::expected_field_error (jss::taker, "string"); if (! raTakerID.setAccountID (context.params [jss::taker].asString ())) return RPC::invalid_field_error (jss::taker); } else { raTakerID.setAccountID (noAccount()); } if (pay_currency == get_currency && pay_issuer == get_issuer) { WriteLog (lsINFO, RPCHandler) << "taker_gets same as taker_pays."; return RPC::make_error (rpcBAD_MARKET); } unsigned int iLimit; if (context.params.isMember (jss::limit)) { auto const& jvLimit (context.params[jss::limit]); if (! jvLimit.isIntegral ()) return RPC::expected_field_error (jss::limit, "unsigned integer"); iLimit = jvLimit.isUInt () ? jvLimit.asUInt () : std::max (0, jvLimit.asInt ()); } else { iLimit = 0; } bool const bProof (context.params.isMember (jss::proof)); Json::Value const jvMarker (context.params.isMember (jss::marker) ? context.params[jss::marker] : Json::Value (Json::nullValue)); context.netOps.getBookPage ( context.role == Role::ADMIN, lpLedger, {{pay_currency, pay_issuer}, {get_currency, get_issuer}}, raTakerID.getAccountID (), bProof, iLimit, jvMarker, jvResult); context.loadType = Resource::feeMediumBurdenRPC; return jvResult; }