20#include <xrpld/app/ledger/LedgerMaster.h>
21#include <xrpld/app/main/Application.h>
22#include <xrpld/app/misc/NetworkOPs.h>
23#include <xrpld/ledger/ReadView.h>
24#include <xrpld/net/RPCSub.h>
25#include <xrpld/rpc/Context.h>
26#include <xrpld/rpc/Role.h>
27#include <xrpld/rpc/detail/RPCHelpers.h>
29#include <xrpl/basics/Log.h>
30#include <xrpl/protocol/ErrorCodes.h>
31#include <xrpl/protocol/RPCErr.h>
32#include <xrpl/protocol/jss.h>
33#include <xrpl/resource/Fees.h>
46 JLOG(context.
j.
info()) <<
"doSubscribe: RPC subscribe requires a url";
74 JLOG(context.
j.
debug()) <<
"doSubscribe: building: " << strUrl;
86 strUrl, std::dynamic_pointer_cast<InfoSub>(rspSub));
95 JLOG(context.
j.
trace()) <<
"doSubscribe: reusing: " << strUrl;
97 if (
auto rpcSub = std::dynamic_pointer_cast<RPCSub>(ispSub))
103 rpcSub->setUsername(strUsername);
106 rpcSub->setPassword(strPassword);
120 JLOG(context.
j.
info()) <<
"doSubscribe: streams requires an array.";
124 for (
auto const& it : context.
params[jss::streams])
130 if (streamName ==
"server")
135 else if (streamName ==
"ledger")
139 else if (streamName ==
"book_changes")
143 else if (streamName ==
"manifests")
147 else if (streamName ==
"transactions")
152 streamName ==
"transactions_proposed" ||
153 streamName ==
"rt_transactions")
157 else if (streamName ==
"validations")
161 else if (streamName ==
"peer_status")
167 else if (streamName ==
"consensus")
178 auto accountsProposed = context.
params.
isMember(jss::accounts_proposed)
179 ? jss::accounts_proposed
201 JLOG(context.
j.
debug()) <<
"doSubscribe: accounts: " << ids.size();
210 auto const& req = context.
params[jss::account_history_tx_stream];
211 if (!req.isMember(jss::account) || !req[jss::account].isString())
214 auto const id = parseBase58<AccountID>(req[jss::account].asString());
224 jvResult[jss::warning] =
225 "account_history_tx_stream is an experimental feature and likely "
226 "to be removed in the future";
228 <<
"doSubscribe: account_history_tx_stream: " <<
toBase58(*
id);
236 for (
auto& j : context.
params[jss::books])
238 if (!j.isObject() || !j.isMember(jss::taker_pays) ||
239 !j.isMember(jss::taker_gets) ||
240 !j[jss::taker_pays].isObjectOrNull() ||
241 !j[jss::taker_gets].isObjectOrNull())
249 if (!taker_pays.
isMember(jss::currency) ||
253 JLOG(context.
j.
info()) <<
"Bad taker_pays currency.";
258 if (((taker_pays.
isMember(jss::issuer)) &&
259 (!taker_pays[jss::issuer].
isString() ||
266 JLOG(context.
j.
info()) <<
"Bad taker_pays issuer.";
271 if (!taker_gets.
isMember(jss::currency) ||
275 JLOG(context.
j.
info()) <<
"Bad taker_gets currency.";
280 if (((taker_gets.
isMember(jss::issuer)) &&
281 (!taker_gets[jss::issuer].
isString() ||
288 JLOG(context.
j.
info()) <<
"Bad taker_gets issuer.";
295 JLOG(context.
j.
info()) <<
"taker_gets same as taker_pays.";
301 if (j.isMember(jss::taker))
303 takerID = parseBase58<AccountID>(j[jss::taker].asString());
310 JLOG(context.
j.
warn()) <<
"Bad market: " << book;
318 (j.isMember(jss::both) && j[jss::both].asBool()) ||
319 (j.isMember(jss::both_sides) && j[jss::both_sides].asBool());
325 if ((j.isMember(jss::snapshot) && j[jss::snapshot].asBool()) ||
326 (j.isMember(jss::state_now) && j[jss::state_now].asBool()))
339 field == jss::asks ?
reversed(book) : book,
349 for (
auto const& e : jvOffers[jss::offers])
354 jvResult[field] = jvOffers[jss::offers];
Lightweight wrapper to tag static string.
Value & append(const Value &value)
Append value to array at the end.
std::string asString() const
Returns the unquoted string value.
bool isMember(const char *key) const
Return true if the object has a member named key.
Stream trace() const
Severity stream access functions.
virtual Config & config()=0
virtual JobQueue & getJobQueue()=0
virtual NetworkOPs & getOPs()=0
virtual boost::asio::io_service & getIOService()=0
virtual LedgerMaster & getLedgerMaster()=0
virtual error_code_i subAccountHistory(ref ispListener, AccountID const &account)=0
subscribe an account's new transactions and retrieve the account's historical transactions
virtual bool subValidations(ref ispListener)=0
virtual bool subBook(ref ispListener, Book const &)=0
virtual bool subServer(ref ispListener, Json::Value &jvResult, bool admin)=0
virtual bool subBookChanges(ref ispListener)=0
virtual bool subConsensus(ref ispListener)=0
virtual bool subManifests(ref ispListener)=0
virtual pointer findRpcSub(std::string const &strUrl)=0
virtual bool subPeerStatus(ref ispListener)=0
virtual bool subTransactions(ref ispListener)=0
virtual bool subLedger(ref ispListener, Json::Value &jvResult)=0
virtual pointer addRpcSub(std::string const &strUrl, ref rspEntry)=0
virtual void subAccount(ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool realTime)=0
virtual bool subRTTransactions(ref ispListener)=0
void setApiVersion(unsigned int apiVersion)
std::shared_ptr< ReadView const > getPublishedLedger()
virtual void getBookPage(std::shared_ptr< ReadView const > &lpLedger, Book const &book, AccountID const &uTakerID, bool const bProof, unsigned int iLimit, Json::Value const &jvMarker, Json::Value &jvResult)=0
@ objectValue
object value (collection of name/value pairs).
static LimitRange constexpr bookOffers
Limits for the book_offers command.
Json::Value make_param_error(std::string const &message)
Returns a new json object that indicates invalid parameters.
hash_set< AccountID > parseAccountIds(Json::Value const &jvArray)
Charge const feeMediumBurdenRPC
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
AccountID const & noAccount()
A placeholder for empty accounts.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
bool isConsistent(Book const &book)
bool to_issuer(AccountID &, std::string const &)
Convert hex or base58 string to AccountID.
Book reversed(Book const &book)
std::shared_ptr< RPCSub > make_RPCSub(InfoSub::Source &source, boost::asio::io_service &io_service, JobQueue &jobQueue, std::string const &strUrl, std::string const &strUsername, std::string const &strPassword, Logs &logs)
Json::Value rpcError(int iError)
Json::Value doSubscribe(RPC::JsonContext &)
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
Resource::Charge & loadType