mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
330 lines
9.0 KiB
C++
330 lines
9.0 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
This file is part of rippled: https://github.com/ripple/rippled
|
|
Copyright (c) 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.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#ifndef RIPPLE_APP_BOOK_TAKER_H_INCLUDED
|
|
#define RIPPLE_APP_BOOK_TAKER_H_INCLUDED
|
|
|
|
#include <ripple/app/tx/impl/Offer.h>
|
|
#include <ripple/core/Config.h>
|
|
#include <ripple/ledger/View.h>
|
|
#include <ripple/protocol/Quality.h>
|
|
#include <ripple/protocol/TER.h>
|
|
#include <ripple/protocol/TxFlags.h>
|
|
#include <beast/utility/Journal.h>
|
|
#include <beast/utility/noexcept.h>
|
|
#include <functional>
|
|
|
|
namespace ripple {
|
|
|
|
/** The flavor of an offer crossing */
|
|
enum class CrossType
|
|
{
|
|
XrpToIou,
|
|
IouToXrp,
|
|
IouToIou
|
|
};
|
|
|
|
/** State for the active party during order book or payment operations. */
|
|
class BasicTaker
|
|
{
|
|
private:
|
|
class Rate
|
|
{
|
|
private:
|
|
std::uint32_t quality_;
|
|
STAmount rate_;
|
|
|
|
public:
|
|
Rate (std::uint32_t quality)
|
|
: quality_ (quality)
|
|
{
|
|
assert (quality_ != 0);
|
|
rate_ = amountFromRate (quality_);
|
|
}
|
|
|
|
STAmount
|
|
divide (STAmount const& amount) const;
|
|
|
|
STAmount
|
|
multiply (STAmount const& amount) const;
|
|
};
|
|
|
|
private:
|
|
AccountID account_;
|
|
Quality quality_;
|
|
Quality threshold_;
|
|
|
|
bool sell_;
|
|
|
|
// The original in and out quantities.
|
|
Amounts const original_;
|
|
|
|
// The amounts still left over for us to try and take.
|
|
Amounts remaining_;
|
|
|
|
// The issuers for the input and output
|
|
Issue const& issue_in_;
|
|
Issue const& issue_out_;
|
|
|
|
// The rates that will be paid when the input and output currencies are
|
|
// transfer when the currency issuer isn't involved:
|
|
std::uint32_t const m_rate_in;
|
|
std::uint32_t const m_rate_out;
|
|
|
|
// The type of crossing that we are performing
|
|
CrossType cross_type_;
|
|
|
|
protected:
|
|
beast::Journal journal_;
|
|
|
|
struct Flow
|
|
{
|
|
Amounts order;
|
|
Amounts issuers;
|
|
|
|
bool sanity_check () const
|
|
{
|
|
if (isXRP (order.in) && isXRP (order.out))
|
|
return false;
|
|
|
|
return order.in >= zero &&
|
|
order.out >= zero &&
|
|
issuers.in >= zero &&
|
|
issuers.out >= zero;
|
|
}
|
|
};
|
|
|
|
private:
|
|
void
|
|
log_flow (char const* description, Flow const& flow);
|
|
|
|
Flow
|
|
flow_xrp_to_iou (Amounts const& offer, Quality quality,
|
|
STAmount const& owner_funds, STAmount const& taker_funds,
|
|
Rate const& rate_out);
|
|
|
|
Flow
|
|
flow_iou_to_xrp (Amounts const& offer, Quality quality,
|
|
STAmount const& owner_funds, STAmount const& taker_funds,
|
|
Rate const& rate_in);
|
|
|
|
Flow
|
|
flow_iou_to_iou (Amounts const& offer, Quality quality,
|
|
STAmount const& owner_funds, STAmount const& taker_funds,
|
|
Rate const& rate_in, Rate const& rate_out);
|
|
|
|
// Calculates the transfer rate that we should use when calculating
|
|
// flows for a particular issue between two accounts.
|
|
static
|
|
Rate
|
|
effective_rate (std::uint32_t rate, Issue const &issue,
|
|
AccountID const& from, AccountID const& to);
|
|
|
|
// The transfer rate for the input currency between the given accounts
|
|
Rate
|
|
in_rate (AccountID const& from, AccountID const& to) const
|
|
{
|
|
return effective_rate (m_rate_in, original_.in.issue (), from, to);
|
|
}
|
|
|
|
// The transfer rate for the output currency between the given accounts
|
|
Rate
|
|
out_rate (AccountID const& from, AccountID const& to) const
|
|
{
|
|
return effective_rate (m_rate_out, original_.out.issue (), from, to);
|
|
}
|
|
|
|
public:
|
|
BasicTaker () = delete;
|
|
BasicTaker (BasicTaker const&) = delete;
|
|
|
|
BasicTaker (
|
|
CrossType cross_type, AccountID const& account, Amounts const& amount,
|
|
Quality const& quality, std::uint32_t flags, std::uint32_t rate_in,
|
|
std::uint32_t rate_out, beast::Journal journal = beast::Journal ());
|
|
|
|
virtual ~BasicTaker () = default;
|
|
|
|
/** Returns the amount remaining on the offer.
|
|
This is the amount at which the offer should be placed. It may either
|
|
be for the full amount when there were no crossing offers, or for zero
|
|
when the offer fully crossed, or any amount in between.
|
|
It is always at the original offer quality (quality_)
|
|
*/
|
|
Amounts
|
|
remaining_offer () const;
|
|
|
|
/** Returns the amount that the offer was originally placed at. */
|
|
Amounts const&
|
|
original_offer () const;
|
|
|
|
/** Returns the account identifier of the taker. */
|
|
AccountID const&
|
|
account () const noexcept
|
|
{
|
|
return account_;
|
|
}
|
|
|
|
/** Returns `true` if the quality does not meet the taker's requirements. */
|
|
bool
|
|
reject (Quality const& quality) const noexcept
|
|
{
|
|
return quality < threshold_;
|
|
}
|
|
|
|
/** Returns the type of crossing that is being performed */
|
|
CrossType
|
|
cross_type () const
|
|
{
|
|
return cross_type_;
|
|
}
|
|
|
|
/** Returns the Issue associated with the input of the offer */
|
|
Issue const&
|
|
issue_in () const
|
|
{
|
|
return issue_in_;
|
|
}
|
|
|
|
/** Returns the Issue associated with the output of the offer */
|
|
Issue const&
|
|
issue_out () const
|
|
{
|
|
return issue_out_;
|
|
}
|
|
|
|
/** Returns `true` if order crossing should not continue.
|
|
Order processing is stopped if the taker's order quantities have
|
|
been reached, or if the taker has run out of input funds.
|
|
*/
|
|
bool
|
|
done () const;
|
|
|
|
/** Perform direct crossing through given offer.
|
|
@return an `Amounts` describing the flow achieved during cross
|
|
*/
|
|
BasicTaker::Flow
|
|
do_cross (Amounts offer, Quality quality, AccountID const& owner);
|
|
|
|
/** Perform bridged crossing through given offers.
|
|
@return a pair of `Amounts` describing the flow achieved during cross
|
|
*/
|
|
std::pair<BasicTaker::Flow, BasicTaker::Flow>
|
|
do_cross (
|
|
Amounts offer1, Quality quality1, AccountID const& owner1,
|
|
Amounts offer2, Quality quality2, AccountID const& owner2);
|
|
|
|
virtual
|
|
STAmount
|
|
get_funds (AccountID const& account, STAmount const& funds) const = 0;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
class Taker
|
|
: public BasicTaker
|
|
{
|
|
public:
|
|
Taker () = delete;
|
|
Taker (Taker const&) = delete;
|
|
|
|
Taker (CrossType cross_type, ApplyView& view,
|
|
AccountID const& account, Amounts const& offer,
|
|
std::uint32_t flags,
|
|
beast::Journal journal);
|
|
~Taker () = default;
|
|
|
|
void
|
|
consume_offer (Offer const& offer, Amounts const& order);
|
|
|
|
STAmount
|
|
get_funds (AccountID const& account, STAmount const& funds) const;
|
|
|
|
STAmount const&
|
|
get_xrp_flow () const
|
|
{
|
|
return xrp_flow_;
|
|
}
|
|
|
|
std::uint32_t
|
|
get_direct_crossings () const
|
|
{
|
|
return direct_crossings_;
|
|
}
|
|
|
|
std::uint32_t
|
|
get_bridge_crossings () const
|
|
{
|
|
return bridge_crossings_;
|
|
}
|
|
|
|
/** Perform a direct or bridged offer crossing as appropriate.
|
|
Funds will be transferred accordingly, and offers will be adjusted.
|
|
@return tesSUCCESS if successful, or an error code otherwise.
|
|
*/
|
|
/** @{ */
|
|
TER
|
|
cross (Offer const& offer);
|
|
|
|
TER
|
|
cross (Offer const& leg1, Offer const& leg2);
|
|
/** @} */
|
|
|
|
private:
|
|
static
|
|
std::uint32_t
|
|
calculateRate (ApplyView const& view,
|
|
AccountID const& issuer,
|
|
AccountID const& account);
|
|
|
|
TER
|
|
fill (BasicTaker::Flow const& flow, Offer const& offer);
|
|
|
|
TER
|
|
fill (
|
|
BasicTaker::Flow const& flow1, Offer const& leg1,
|
|
BasicTaker::Flow const& flow2, Offer const& leg2);
|
|
|
|
TER
|
|
transferXRP (AccountID const& from, AccountID const& to, STAmount const& amount);
|
|
|
|
TER
|
|
redeemIOU (AccountID const& account, STAmount const& amount, Issue const& issue);
|
|
|
|
TER
|
|
issueIOU (AccountID const& account, STAmount const& amount, Issue const& issue);
|
|
|
|
private:
|
|
// The underlying ledger entry we are dealing with
|
|
ApplyView& view_;
|
|
|
|
// The amount of XRP that flowed if we were autobridging
|
|
STAmount xrp_flow_;
|
|
|
|
// The number direct crossings that we performed
|
|
std::uint32_t direct_crossings_;
|
|
|
|
// The number autobridged crossings that we performed
|
|
std::uint32_t bridge_crossings_;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|