Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
GetAggregatePrice.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2024, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "data/BackendInterface.hpp"
23#include "rpc/Errors.hpp"
24#include "rpc/JS.hpp"
25#include "rpc/common/MetaProcessors.hpp"
26#include "rpc/common/Modifiers.hpp"
27#include "rpc/common/Specs.hpp"
28#include "rpc/common/Types.hpp"
29#include "rpc/common/Validators.hpp"
30
31#include <boost/asio/spawn.hpp>
32#include <boost/json/array.hpp>
33#include <boost/json/conversion.hpp>
34#include <xrpl/basics/Number.h>
35#include <xrpl/protocol/AccountID.h>
36#include <xrpl/protocol/STAmount.h>
37#include <xrpl/protocol/STObject.h>
38#include <xrpl/protocol/jss.h>
39
40#include <cstdint>
41#include <functional>
42#include <memory>
43#include <optional>
44#include <string>
45#include <string_view>
46#include <vector>
47
48namespace rpc {
49
54 std::shared_ptr<BackendInterface> sharedPtrBackend_;
55
56public:
60 struct Stats {
61 ripple::STAmount avg{}; // NOLINT(readability-redundant-member-init)
62 // standard deviation
63 ripple::Number sd{}; // NOLINT(readability-redundant-member-init)
64 uint32_t size{0};
65 };
66
70 struct Output {
71 uint32_t time;
72 Stats extireStats{};
73 std::optional<Stats> trimStats;
74 std::string ledgerHash;
75 uint32_t ledgerIndex;
76 std::string median;
77 bool validated = true;
78 };
79
83 struct Oracle {
84 std::uint32_t documentId{0};
85 ripple::AccountID account;
86 };
87
91 struct Input {
92 std::optional<std::string> ledgerHash;
93 std::optional<std::uint32_t> ledgerIndex;
94 std::vector<Oracle> oracles; // valid range is 1-200
95 std::string baseAsset;
96 std::string quoteAsset;
97 std::optional<std::uint32_t> timeThreshold;
98 std::optional<std::uint8_t> trim; // valid range is 1-25
99 };
100
101 using Result = HandlerReturnType<Output>;
102
108 GetAggregatePriceHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
109 : sharedPtrBackend_(sharedPtrBackend)
110 {
111 }
112
119 static RpcSpecConstRef
120 spec([[maybe_unused]] uint32_t apiVersion)
121 {
122 static constexpr auto kORACLES_MAX = 200;
123
124 static auto const kORACLES_VALIDATOR =
125 modifiers::CustomModifier{[](boost::json::value& value, std::string_view) -> MaybeError {
126 if (!value.is_array() or value.as_array().empty() or value.as_array().size() > kORACLES_MAX)
127 return Error{Status{RippledError::rpcORACLE_MALFORMED}};
128
129 for (auto& oracle : value.as_array()) {
130 if (!oracle.is_object() or !oracle.as_object().contains(JS(oracle_document_id)) or
131 !oracle.as_object().contains(JS(account)))
132 return Error{Status{RippledError::rpcORACLE_MALFORMED}};
133
135 oracle.as_object(), JS(oracle_document_id)
136 );
137 if (!maybeError)
138 return maybeError;
139
140 maybeError = modifiers::ToNumber::modify(oracle, JS(oracle_document_id));
141 if (!maybeError)
142 return maybeError;
143
144 maybeError =
145 validation::CustomValidators::accountBase58Validator.verify(oracle.as_object(), JS(account));
146 if (!maybeError)
147 return Error{Status{RippledError::rpcINVALID_PARAMS}};
148 };
149
150 return MaybeError{};
151 }};
152
153 static auto const kRPC_SPEC = RpcSpec{
156 // validate quoteAsset and base_asset in accordance to the currency code found in XRPL doc:
157 // https://xrpl.org/docs/references/protocol/data-types/currency-formats#currency-codes
158 // usually Clio returns rpcMALFORMED_CURRENCY , return InvalidParam here just to mimic rippled
159 {JS(base_asset),
162 validation::CustomValidators::currencyValidator, Status(RippledError::rpcINVALID_PARAMS)
163 }},
164 {JS(quote_asset),
167 validation::CustomValidators::currencyValidator, Status(RippledError::rpcINVALID_PARAMS)
168 }},
169 {JS(oracles), validation::Required{}, kORACLES_VALIDATOR},
170 // note: Unlike `rippled`, Clio only supports UInt as input, no string, no `null`, etc.
171 {JS(time_threshold), validation::Type<std::uint32_t>{}},
172 {
173 JS(trim),
176 }
177 };
178
179 return kRPC_SPEC;
180 }
181
189 Result
190 process(Input const& input, Context const& ctx) const;
191
192private:
198 void
199 tracebackOracleObject(
200 boost::asio::yield_context yield,
201 ripple::STObject const& oracleObject,
202 std::function<bool(ripple::STObject const&)> const& callback
203 ) const;
204
211 friend void
212 tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
213
220 friend Input
221 tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
222};
223
224} // namespace rpc
The get_aggregate_price method.
Definition GetAggregatePrice.hpp:53
static RpcSpecConstRef spec(uint32_t apiVersion)
Returns the API specification for the command.
Definition GetAggregatePrice.hpp:120
GetAggregatePriceHandler(std::shared_ptr< BackendInterface > const &sharedPtrBackend)
Construct a new GetAggregatePrice handler object.
Definition GetAggregatePrice.hpp:108
friend void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, Output const &output)
Convert the Output to a JSON object.
Definition GetAggregatePrice.cpp:296
Result process(Input const &input, Context const &ctx) const
Process the GetAggregatePrice command.
Definition GetAggregatePrice.cpp:61
A meta-processor that wraps a validator and produces a custom error in case the wrapped validator fai...
Definition MetaProcessors.hpp:166
Customised modifier allowing user define how to modify input in provided callable.
Definition Modifiers.hpp:145
Validate that value is between specified min and max.
Definition Validators.hpp:170
MaybeError verify(boost::json::value const &value, std::string_view key) const
Verify that the JSON value is valid according to the custom validation function stored.
Definition Validators.cpp:79
This namespace contains all the RPC logic and handlers.
Definition AMMHelpers.cpp:37
RpcSpec const & RpcSpecConstRef
An alias for a const reference to RpcSpec.
Definition Specs.hpp:145
std::expected< OutputType, Status > HandlerReturnType
Return type for each individual handler.
Definition Types.hpp:81
std::expected< void, Status > MaybeError
Return type used for Validators that can return error but don't have specific value to return.
Definition Types.hpp:55
std::unexpected< Status > Error
The type that represents just the error part of MaybeError.
Definition Types.hpp:75
Context of an RPC call.
Definition Types.hpp:118
A struct to hold the input data for the command.
Definition GetAggregatePrice.hpp:91
A struct to hold the input oracle data.
Definition GetAggregatePrice.hpp:83
A struct to hold the output data of the command.
Definition GetAggregatePrice.hpp:70
A struct to hold the statistics.
Definition GetAggregatePrice.hpp:60
Result type used to return responses or error statuses to the Webserver subsystem.
Definition Types.hpp:129
Represents a Specification of an entire RPC command.
Definition Specs.hpp:98
A status returned from any RPC handler.
Definition Errors.hpp:83
static MaybeError modify(boost::json::value &value, std::string_view key)
Update the input string to integer if it can be converted to integer by stoi.
Definition Modifiers.hpp:121
static CustomValidator currencyValidator
Provides a commonly used validator for currency, including standard currency code and token code.
Definition Validators.hpp:554
static CustomValidator ledgerIndexValidator
Provides a commonly used validator for ledger index.
Definition Validators.hpp:487
static CustomValidator uint256HexStringValidator
Provides a commonly used validator for uint256 hex string.
Definition Validators.hpp:549
static CustomValidator accountBase58Validator
Provides a commonly used validator for accounts.
Definition Validators.hpp:509
A validator that simply requires a field to be present.
Definition Validators.hpp:47
Validates that the type of the value is one of the given types.
Definition Validators.hpp:142
MaybeError verify(boost::json::value const &value, std::string_view key) const
Verify that the JSON value is (one) of specified type(s).
Definition Validators.hpp:151