20#ifndef RIPPLE_RPC_BOOKCHANGES_H_INCLUDED
21#define RIPPLE_RPC_BOOKCHANGES_H_INCLUDED
23#include <xrpl/json/json_value.h>
24#include <xrpl/protocol/LedgerFormats.h>
25#include <xrpl/protocol/STAmount.h>
26#include <xrpl/protocol/STObject.h>
27#include <xrpl/protocol/TxFormats.h>
28#include <xrpl/protocol/jss.h>
61 for (
auto& tx : lpAccepted->txs)
63 if (!tx.first || !tx.second ||
64 !tx.first->isFieldPresent(sfTransactionType))
68 uint16_t tt = tx.first->getFieldU16(sfTransactionType);
72 case ttOFFER_CREATE: {
73 if (tx.first->isFieldPresent(sfOfferSequence))
74 offerCancel = tx.first->getFieldU32(sfOfferSequence);
83 for (
auto const& node : tx.second->getFieldArray(sfAffectedNodes))
85 SField const& metaType = node.getFName();
86 uint16_t nodeType = node.getFieldU16(sfLedgerEntryType);
90 if (nodeType != ltOFFER || metaType == sfCreatedNode)
96 if (!node.isFieldPresent(sfFinalFields) ||
97 !node.isFieldPresent(sfPreviousFields))
100 auto const& ffBase = node.peekAtField(sfFinalFields);
101 auto const& finalFields = ffBase.template downcast<STObject>();
102 auto const& pfBase = node.peekAtField(sfPreviousFields);
103 auto const& previousFields = pfBase.template downcast<STObject>();
106 if (!finalFields.isFieldPresent(sfTakerGets) ||
107 !finalFields.isFieldPresent(sfTakerPays) ||
108 !previousFields.isFieldPresent(sfTakerGets) ||
109 !previousFields.isFieldPresent(sfTakerPays))
113 if (metaType == sfDeletedNode && offerCancel &&
114 finalFields.getFieldU32(sfSequence) == *offerCancel)
119 STAmount deltaGets = finalFields.getFieldAmount(sfTakerGets) -
120 previousFields.getFieldAmount(sfTakerGets);
121 STAmount deltaPays = finalFields.getFieldAmount(sfTakerPays) -
122 previousFields.getFieldAmount(sfTakerPays);
128 isXRP(deltaGets) ? true : (
isXRP(deltaPays) ? false : (g < p));
130 STAmount first = noswap ? deltaGets : deltaPays;
131 STAmount second = noswap ? deltaPays : deltaGets;
134 if (second == beast::zero)
139 if (first < beast::zero)
142 if (second < beast::zero)
153 if (tally.find(key) == tally.end())
165 auto& entry = tally[key];
167 std::get<0>(entry) += first;
168 std::get<1>(entry) += second;
170 if (std::get<2>(entry) <
rate)
171 std::get<2>(entry) =
rate;
173 if (std::get<3>(entry) >
rate)
174 std::get<3>(entry) =
rate;
176 std::get<5>(entry) =
rate;
182 jvObj[jss::type] =
"bookChanges";
185 jvObj[jss::validated] = lpAccepted->info().validated;
186 jvObj[jss::ledger_index] = lpAccepted->info().seq;
187 jvObj[jss::ledger_hash] =
to_string(lpAccepted->info().hash);
189 lpAccepted->info().closeTime.time_since_epoch().count());
193 for (
auto const& entry : tally)
197 STAmount volA = std::get<0>(entry.second);
198 STAmount volB = std::get<1>(entry.second);
200 inner[jss::currency_a] =
202 inner[jss::currency_b] =
205 inner[jss::volume_a] =
207 inner[jss::volume_b] =
210 inner[jss::high] =
to_string(std::get<2>(entry.second).iou());
211 inner[jss::low] =
to_string(std::get<3>(entry.second).iou());
212 inner[jss::open] =
to_string(std::get<4>(entry.second).iou());
213 inner[jss::close] =
to_string(std::get<5>(entry.second).iou());
Value & append(Value const &value)
Append value to array at the end.
Issue const & issue() const
JSON (JavaScript Object Notation).
@ arrayValue
array value (ordered list)
@ objectValue
object value (collection of name/value pairs).
Json::Value computeBookChanges(std::shared_ptr< L const > const &lpAccepted)
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
STAmount divide(STAmount const &amount, Rate const &rate)
bool isXRP(AccountID const &c)
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
std::string to_string(base_uint< Bits, Tag > const &a)