mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-19 18:15:50 +00:00
add rpc
This commit is contained in:
@@ -634,6 +634,7 @@ target_sources (rippled PRIVATE
|
||||
src/ripple/rpc/handlers/NFTOffers.cpp
|
||||
src/ripple/rpc/handlers/NodeToShard.cpp
|
||||
src/ripple/rpc/handlers/NoRippleCheck.cpp
|
||||
src/ripple/rpc/handlers/OptionBookOffers.cpp
|
||||
src/ripple/rpc/handlers/OwnerInfo.cpp
|
||||
src/ripple/rpc/handlers/PathFind.cpp
|
||||
src/ripple/rpc/handlers/PayChanClaim.cpp
|
||||
|
||||
@@ -350,6 +350,15 @@ public:
|
||||
unsigned int iLimit,
|
||||
Json::Value const& jvMarker,
|
||||
Json::Value& jvResult) override;
|
||||
|
||||
void
|
||||
getOptionBookPage(
|
||||
std::shared_ptr<ReadView const>& lpLedger,
|
||||
STAmount const&,
|
||||
std::uint32_t const& expiration,
|
||||
unsigned int iLimit,
|
||||
Json::Value const& jvMarker,
|
||||
Json::Value& jvResult) override;
|
||||
|
||||
// Ledger proposal/close functions.
|
||||
bool
|
||||
@@ -4581,6 +4590,114 @@ NetworkOPsImp::getBookPage(
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
NetworkOPsImp::getOptionBookPage(
|
||||
std::shared_ptr<ReadView const>& lpLedger,
|
||||
STAmount const& strikePrice,
|
||||
std::uint32_t const& expiration,
|
||||
unsigned int iLimit,
|
||||
Json::Value const& jvMarker,
|
||||
Json::Value& jvResult)
|
||||
{
|
||||
Json::Value& jvOffers = (jvResult[jss::offers] = Json::Value(Json::arrayValue));
|
||||
|
||||
const uint256 uBookBase = getOptionBookBase(
|
||||
strikePrice.getIssuer(),
|
||||
strikePrice.getCurrency(),
|
||||
strikePrice.mantissa(),
|
||||
expiration);
|
||||
const uint256 uBookEnd = getOptionQualityNext(uBookBase);
|
||||
|
||||
uint256 uTipIndex = uBookBase;
|
||||
|
||||
if (auto stream = m_journal.trace())
|
||||
{
|
||||
stream << "getBookPage:" << strikePrice;
|
||||
stream << "getBookPage: uBookBase=" << uBookBase;
|
||||
stream << "getBookPage: uBookEnd=" << uBookEnd;
|
||||
stream << "getBookPage: uTipIndex=" << uTipIndex;
|
||||
}
|
||||
|
||||
ReadView const& view = *lpLedger;
|
||||
|
||||
bool bDone = false;
|
||||
bool bDirectAdvance = true;
|
||||
|
||||
std::shared_ptr<SLE const> sleOfferDir;
|
||||
uint256 offerIndex;
|
||||
unsigned int uBookEntry;
|
||||
STAmount saDirRate;
|
||||
|
||||
auto viewJ = app_.journal("View");
|
||||
|
||||
while (!bDone && iLimit-- > 0)
|
||||
{
|
||||
if (bDirectAdvance)
|
||||
{
|
||||
bDirectAdvance = false;
|
||||
|
||||
JLOG(m_journal.trace()) << "getBookPage: bDirectAdvance";
|
||||
|
||||
auto const ledgerIndex = view.succ(uTipIndex, uBookEnd);
|
||||
if (ledgerIndex)
|
||||
{
|
||||
sleOfferDir = view.read(keylet::page(*ledgerIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
sleOfferDir.reset();
|
||||
}
|
||||
|
||||
if (!sleOfferDir)
|
||||
{
|
||||
JLOG(m_journal.trace()) << "getBookPage: bDone";
|
||||
bDone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uTipIndex = sleOfferDir->key();
|
||||
cdirFirst(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex);
|
||||
|
||||
JLOG(m_journal.trace())
|
||||
<< "getBookPage: uTipIndex=" << uTipIndex;
|
||||
JLOG(m_journal.trace())
|
||||
<< "getBookPage: offerIndex=" << offerIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bDone)
|
||||
{
|
||||
auto sleOffer = view.read(keylet::optionOffer(offerIndex));
|
||||
|
||||
if (sleOffer)
|
||||
{
|
||||
STAmount premium = sleOffer->getFieldAmount(sfAmount);
|
||||
auto const optionQuality = getOptionQuality(uTipIndex);
|
||||
STAmount saDirRate = STAmount(premium.issue(), optionQuality);
|
||||
|
||||
Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
|
||||
|
||||
Json::Value& jvOf = jvOffers.append(jvOffer);
|
||||
jvOf[jss::quality] = saDirRate.getText();
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(m_journal.warn()) << "Missing offer";
|
||||
}
|
||||
|
||||
if (!cdirNext(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex))
|
||||
{
|
||||
bDirectAdvance = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(m_journal.trace())
|
||||
<< "getBookPage: offerIndex=" << offerIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
NetworkOPsImp::collect_metrics()
|
||||
{
|
||||
|
||||
@@ -163,6 +163,15 @@ public:
|
||||
unsigned int iLimit,
|
||||
Json::Value const& jvMarker,
|
||||
Json::Value& jvResult) = 0;
|
||||
|
||||
virtual void
|
||||
getOptionBookPage(
|
||||
std::shared_ptr<ReadView const>& lpLedger,
|
||||
STAmount const& strikePrice,
|
||||
std::uint32_t const& expiration,
|
||||
unsigned int iLimit,
|
||||
Json::Value const& jvMarker,
|
||||
Json::Value& jvResult) = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -315,6 +315,12 @@ optionBook(AccountID const& issuer, Currency const& currency, std::uint64_t stri
|
||||
Keylet
|
||||
optionOffer(AccountID const& id, std::uint32_t seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
optionOffer(uint256 const& key) noexcept
|
||||
{
|
||||
return {ltOPTION_OFFER, key};
|
||||
}
|
||||
|
||||
Keylet
|
||||
optionQuality(Keylet const& k, std::uint64_t q) noexcept;
|
||||
|
||||
|
||||
@@ -515,6 +515,7 @@ JSS(open); // out: handlers/Ledger
|
||||
JSS(open_ledger_cost); // out: SubmitTransaction
|
||||
JSS(open_ledger_fee); // out: TxQ
|
||||
JSS(open_ledger_level); // out: TxQ
|
||||
JSS(option); // out: AccountObjects
|
||||
JSS(owner); // in: LedgerEntry, out: NetworkOPs
|
||||
JSS(owner_funds); // in/out: Ledger, NetworkOPs, AcceptedLedgerTx
|
||||
JSS(page_index);
|
||||
@@ -635,6 +636,7 @@ JSS(stop_history_tx_only); // in: Unsubscribe, stop history tx stream
|
||||
JSS(storedSeqs); // out: NodeToShardStatus
|
||||
JSS(streams); // in: Subscribe, Unsubscribe
|
||||
JSS(strict); // in: AccountCurrencies, AccountInfo
|
||||
JSS(strike_price); // in: NetworkOPs
|
||||
JSS(sub_index); // in: LedgerEntry
|
||||
JSS(subcommand); // in: PathFind
|
||||
JSS(success); // rpc
|
||||
|
||||
@@ -208,6 +208,7 @@ doAccountObjects(RPC::JsonContext& context)
|
||||
{jss::hook, ltHOOK},
|
||||
{jss::payment_channel, ltPAYCHAN},
|
||||
{jss::uri_token, ltURI_TOKEN},
|
||||
{jss::option, ltOPTION},
|
||||
{jss::state, ltRIPPLE_STATE}};
|
||||
|
||||
typeFilter.emplace();
|
||||
|
||||
@@ -103,6 +103,8 @@ doNodeToShard(RPC::JsonContext&);
|
||||
Json::Value
|
||||
doNoRippleCheck(RPC::JsonContext&);
|
||||
Json::Value
|
||||
doOptionBookOffers(RPC::JsonContext&);
|
||||
Json::Value
|
||||
doOwnerInfo(RPC::JsonContext&);
|
||||
Json::Value
|
||||
doPathFind(RPC::JsonContext&);
|
||||
|
||||
160
src/ripple/rpc/handlers/OptionBookOffers.cpp
Normal file
160
src/ripple/rpc/handlers/OptionBookOffers.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012-2014 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/ledger/ReadView.h>
|
||||
#include <ripple/net/RPCErr.h>
|
||||
#include <ripple/protocol/ErrorCodes.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <ripple/resource/Fees.h>
|
||||
#include <ripple/rpc/Context.h>
|
||||
#include <ripple/rpc/impl/RPCHelpers.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
Json::Value
|
||||
doOptionBookOffers(RPC::JsonContext& 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 (context.app.getJobQueue().getJobCountGE(jtCLIENT) > 200)
|
||||
return rpcError(rpcTOO_BUSY);
|
||||
|
||||
std::shared_ptr<ReadView const> lpLedger;
|
||||
auto jvResult = RPC::lookupLedger(lpLedger, context);
|
||||
|
||||
if (!lpLedger)
|
||||
return jvResult;
|
||||
|
||||
if (!context.params.isMember(jss::strike_price))
|
||||
return RPC::missing_field_error(jss::strike_price);
|
||||
|
||||
Json::Value const& strike_price = context.params[jss::strike_price];
|
||||
|
||||
if (!strike_price.isObjectOrNull())
|
||||
return RPC::object_field_error(jss::strike_price);
|
||||
|
||||
// if (!taker_gets.isObjectOrNull())
|
||||
// return RPC::object_field_error(jss::taker_gets);
|
||||
|
||||
if (!strike_price.isMember(jss::currency))
|
||||
return RPC::missing_field_error("strike_price.currency");
|
||||
|
||||
if (!strike_price[jss::currency].isString())
|
||||
return RPC::expected_field_error("strike_price.currency", "string");
|
||||
|
||||
// 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, strike_price[jss::currency].asString()))
|
||||
{
|
||||
JLOG(context.j.info()) << "Bad strike_price currency.";
|
||||
return RPC::make_error(
|
||||
rpcSRC_CUR_MALFORMED,
|
||||
"Invalid field 'strike_price.currency', bad currency.");
|
||||
}
|
||||
|
||||
AccountID pay_issuer;
|
||||
|
||||
if (strike_price.isMember(jss::issuer))
|
||||
{
|
||||
if (!strike_price[jss::issuer].isString())
|
||||
return RPC::expected_field_error("strike_price.issuer", "string");
|
||||
|
||||
if (!to_issuer(pay_issuer, strike_price[jss::issuer].asString()))
|
||||
return RPC::make_error(
|
||||
rpcSRC_ISR_MALFORMED,
|
||||
"Invalid field 'strike_price.issuer', bad issuer.");
|
||||
|
||||
if (pay_issuer == noAccount())
|
||||
return RPC::make_error(
|
||||
rpcSRC_ISR_MALFORMED,
|
||||
"Invalid field 'strike_price.issuer', bad issuer account one.");
|
||||
}
|
||||
else
|
||||
{
|
||||
pay_issuer = xrpAccount();
|
||||
}
|
||||
|
||||
std::optional<std::uint64_t> pay_value;
|
||||
if (strike_price.isMember(jss::value))
|
||||
{
|
||||
if (!strike_price[jss::value].isString())
|
||||
return RPC::expected_field_error("strike_price.value", "string");
|
||||
|
||||
pay_value = strike_price[jss::value].asInt();
|
||||
if (!pay_value)
|
||||
return RPC::invalid_field_error(jss::value);
|
||||
}
|
||||
|
||||
if (isXRP(pay_currency) && !isXRP(pay_issuer))
|
||||
return RPC::make_error(
|
||||
rpcSRC_ISR_MALFORMED,
|
||||
"Unneeded field 'taker_pays.issuer' for "
|
||||
"XRP currency specification.");
|
||||
|
||||
if (!isXRP(pay_currency) && isXRP(pay_issuer))
|
||||
return RPC::make_error(
|
||||
rpcSRC_ISR_MALFORMED,
|
||||
"Invalid field 'taker_pays.issuer', expected non-XRP issuer.");
|
||||
|
||||
std::optional<std::uint32_t> expiration;
|
||||
if (context.params.isMember(jss::expiration))
|
||||
{
|
||||
if (!context.params[jss::expiration].isString())
|
||||
return RPC::expected_field_error(jss::expiration, "string");
|
||||
|
||||
expiration = context.params[jss::expiration].asInt();
|
||||
if (!expiration)
|
||||
return RPC::invalid_field_error(jss::expiration);
|
||||
}
|
||||
|
||||
unsigned int limit;
|
||||
if (auto err = readLimitField(limit, RPC::Tuning::bookOffers, context))
|
||||
return *err;
|
||||
|
||||
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.getOptionBookPage(
|
||||
lpLedger,
|
||||
STAmount(Issue(pay_currency, pay_issuer), pay_value ? *pay_value : 0),
|
||||
expiration ? *expiration : 0,
|
||||
limit,
|
||||
jvMarker,
|
||||
jvResult);
|
||||
|
||||
context.loadType = Resource::feeMediumBurdenRPC;
|
||||
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
@@ -118,6 +118,7 @@ Handler const handlerArray[]{
|
||||
{"nft_sell_offers", byRef(&doNFTSellOffers), Role::USER, NO_CONDITION},
|
||||
{"node_to_shard", byRef(&doNodeToShard), Role::ADMIN, NO_CONDITION},
|
||||
{"noripple_check", byRef(&doNoRippleCheck), Role::USER, NO_CONDITION},
|
||||
{"option_book_offers", byRef(&doOptionBookOffers), Role::USER, NO_CONDITION},
|
||||
{"owner_info", byRef(&doOwnerInfo), Role::USER, NEEDS_CURRENT_LEDGER},
|
||||
{"peers", byRef(&doPeers), Role::ADMIN, NO_CONDITION},
|
||||
{"path_find", byRef(&doPathFind), Role::USER, NEEDS_CURRENT_LEDGER},
|
||||
|
||||
Reference in New Issue
Block a user