mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-24 07:30:30 +00:00
set up framework
This commit is contained in:
@@ -279,6 +279,7 @@ words:
|
||||
- sles
|
||||
- soci
|
||||
- socidb
|
||||
- sponsee
|
||||
- SRPMS
|
||||
- sslws
|
||||
- statsd
|
||||
@@ -327,6 +328,7 @@ words:
|
||||
- unserviced
|
||||
- unshareable
|
||||
- unshares
|
||||
- unsponsored
|
||||
- unsquelch
|
||||
- unsquelched
|
||||
- unsquelching
|
||||
|
||||
31
include/xrpl/ledger/helpers/OracleHelpers.h
Normal file
31
include/xrpl/ledger/helpers/OracleHelpers.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STArray.h> // IWYU pragma: keep
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
constexpr std::uint32_t kMinOracleReserveCount = 1;
|
||||
constexpr std::uint32_t kMaxOracleReserveCount = 2;
|
||||
constexpr std::size_t kOracleReserveCountThreshold = 5;
|
||||
|
||||
template <typename T>
|
||||
requires requires(T const& t) { t.size(); }
|
||||
inline std::uint32_t
|
||||
calculateOracleReserve(T const& priceDataSeries)
|
||||
{
|
||||
return priceDataSeries.size() > kOracleReserveCountThreshold ? kMaxOracleReserveCount
|
||||
: kMinOracleReserveCount;
|
||||
}
|
||||
|
||||
inline std::uint32_t
|
||||
calculateOracleReserve(SLE::const_ref oracleSle)
|
||||
{
|
||||
return calculateOracleReserve(oracleSle->getFieldArray(sfPriceDataSeries));
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
250
include/xrpl/ledger/helpers/SLEBase.h
Normal file
250
include/xrpl/ledger/helpers/SLEBase.h
Normal file
@@ -0,0 +1,250 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
|
||||
#include <concepts>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Concept to distinguish read-only vs writable view types
|
||||
template <typename V>
|
||||
concept WritableView = std::derived_from<V, ApplyView>;
|
||||
|
||||
/**
|
||||
* View-parameterized base class for all ledger entry wrappers.
|
||||
*
|
||||
* SLEBase<ReadView> — read-only: holds shared_ptr<SLE const> + ReadView const&
|
||||
* SLEBase<ApplyView> — writable: holds shared_ptr<SLE> + ApplyView& + Keylet,
|
||||
* plus insert/update/erase operations
|
||||
*
|
||||
* Write-only members are gated by `requires` clauses, providing compile-time
|
||||
* guarantees that read-only wrappers cannot mutate state.
|
||||
*
|
||||
* Derived classes should provide domain-specific accessors that hide
|
||||
* implementation details of the underlying ledger entry format.
|
||||
*/
|
||||
template <typename ViewT>
|
||||
class SLEBase
|
||||
{
|
||||
public:
|
||||
static constexpr bool kIsWritable = WritableView<ViewT>;
|
||||
|
||||
// SLE pointer type: mutable for writable views, const for read-only
|
||||
using sle_ptr_type = std::conditional_t<kIsWritable, std::shared_ptr<SLE>, SLE::const_pointer>;
|
||||
|
||||
// View reference type: ApplyView& for writable, ReadView const& for read-only
|
||||
using view_ref_type = std::conditional_t<kIsWritable, ApplyView&, ReadView const&>;
|
||||
|
||||
virtual ~SLEBase() = default;
|
||||
|
||||
SLEBase(SLEBase const&) = default;
|
||||
SLEBase(SLEBase&&) = default;
|
||||
SLEBase&
|
||||
operator=(SLEBase const&) = delete;
|
||||
SLEBase&
|
||||
operator=(SLEBase&&) = delete;
|
||||
SLEBase() = delete;
|
||||
|
||||
// --- Common interface (always available) ---
|
||||
|
||||
/** Returns true if the ledger entry exists */
|
||||
[[nodiscard]] bool
|
||||
exists() const
|
||||
{
|
||||
return sle_ != nullptr;
|
||||
}
|
||||
|
||||
/** Explicit conversion to bool for convenient existence checking */
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return exists();
|
||||
}
|
||||
|
||||
/** Returns the underlying SLE for read access */
|
||||
[[nodiscard]] SLE::const_pointer
|
||||
sle() const
|
||||
{
|
||||
return sle_;
|
||||
}
|
||||
|
||||
/** Returns the read view (always available; ApplyView inherits ReadView) */
|
||||
[[nodiscard]] ReadView const&
|
||||
readView() const
|
||||
{
|
||||
return view_;
|
||||
}
|
||||
|
||||
/** Const dereference operators (always available) */
|
||||
STLedgerEntry const*
|
||||
operator->() const
|
||||
{
|
||||
XRPL_ASSERT(exists(), "xrpl::SLEBase::operator-> : exists");
|
||||
return sle_.get();
|
||||
}
|
||||
|
||||
STLedgerEntry const&
|
||||
operator*() const
|
||||
{
|
||||
XRPL_ASSERT(exists(), "xrpl::SLEBase::operator* : exists");
|
||||
return *sle_;
|
||||
}
|
||||
|
||||
// --- Writable interface (compile-time gated) ---
|
||||
|
||||
/** Returns a mutable SLE for write operations */
|
||||
[[nodiscard]] sle_ptr_type const&
|
||||
mutableSle() const
|
||||
requires kIsWritable
|
||||
{
|
||||
return sle_;
|
||||
}
|
||||
|
||||
/** Returns true if this wrapper supports write operations */
|
||||
[[nodiscard]] bool
|
||||
canModify() const
|
||||
requires kIsWritable
|
||||
{
|
||||
return sle_ != nullptr;
|
||||
}
|
||||
|
||||
/** Returns the apply view for write operations */
|
||||
[[nodiscard]] ApplyView&
|
||||
applyView() const
|
||||
requires kIsWritable
|
||||
{
|
||||
return view_;
|
||||
}
|
||||
|
||||
/** Mutable dereference operators */
|
||||
STLedgerEntry*
|
||||
operator->()
|
||||
requires kIsWritable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::operator-> : can modify");
|
||||
return sle_.get();
|
||||
}
|
||||
|
||||
STLedgerEntry&
|
||||
operator*()
|
||||
requires kIsWritable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::operator* : can modify");
|
||||
return *sle_;
|
||||
}
|
||||
|
||||
void
|
||||
insert()
|
||||
requires kIsWritable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::insert : can modify");
|
||||
view_.insert(sle_);
|
||||
}
|
||||
|
||||
void
|
||||
erase()
|
||||
requires kIsWritable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::erase : can modify");
|
||||
view_.erase(sle_);
|
||||
}
|
||||
|
||||
void
|
||||
update()
|
||||
requires kIsWritable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::update : can modify");
|
||||
view_.update(sle_);
|
||||
}
|
||||
|
||||
void
|
||||
newSLE()
|
||||
requires kIsWritable
|
||||
{
|
||||
XRPL_ASSERT(!canModify(), "xrpl::SLEBase::newSLE : no existing SLE");
|
||||
sle_ = std::make_shared<SLE>(key_);
|
||||
}
|
||||
|
||||
[[nodiscard]] beast::Journal
|
||||
journal() const
|
||||
{
|
||||
return j_;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Constructor for read-only context */
|
||||
explicit SLEBase(
|
||||
SLE::const_pointer sle,
|
||||
ReadView const& view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
requires(!kIsWritable)
|
||||
: view_(view), sle_(std::move(sle)), j_(j)
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for read-only context (read from view by keylet) */
|
||||
explicit SLEBase(
|
||||
Keylet const& key,
|
||||
ReadView const& view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
requires(!kIsWritable)
|
||||
: view_(view), sle_(view.read(key)), j_(j)
|
||||
{
|
||||
}
|
||||
|
||||
/** Converting constructor: writable → read-only.
|
||||
* Enables implicit conversion from SLEBase<ApplyView> to
|
||||
* SLEBase<ReadView>, so functions taking ReadOnlySLE const& can
|
||||
* accept WritableSLE.
|
||||
*/
|
||||
template <WritableView OtherViewT>
|
||||
SLEBase(SLEBase<OtherViewT> const& other)
|
||||
requires(!kIsWritable)
|
||||
: view_(other.readView()), sle_(other.sle()), j_(other.journal())
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for writable context (from existing SLE) */
|
||||
explicit SLEBase(
|
||||
std::shared_ptr<SLE> sle,
|
||||
ApplyView& view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
requires kIsWritable
|
||||
: view_(view)
|
||||
, key_(sle ? Keylet(sle->getType(), sle->key()) : Keylet(ltANY, uint256{}))
|
||||
, sle_(std::move(sle))
|
||||
, j_(j)
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for writable context (peek from view by keylet) */
|
||||
explicit SLEBase(
|
||||
Keylet const& key,
|
||||
ApplyView& view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
requires kIsWritable
|
||||
: view_(view), key_(key), sle_(view_.peek(key)), j_(j)
|
||||
{
|
||||
}
|
||||
|
||||
view_ref_type view_{};
|
||||
|
||||
// Keylet is only meaningful for writable views, but we conditionally
|
||||
// include it to avoid wasting space in read-only wrappers.
|
||||
struct Empty
|
||||
{
|
||||
};
|
||||
[[no_unique_address]]
|
||||
std::conditional_t<kIsWritable, Keylet, Empty> key_{};
|
||||
|
||||
sle_ptr_type sle_{};
|
||||
beast::Journal j_;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
450
include/xrpl/ledger/helpers/SLEWrappers.h
Normal file
450
include/xrpl/ledger/helpers/SLEWrappers.h
Normal file
@@ -0,0 +1,450 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/helpers/SLEBase.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* Concrete, view-parameterized wrappers for each ledger entry type.
|
||||
*
|
||||
* Every wrapper derives from SLEBase<ViewT> and, for now, does nothing more
|
||||
* than translate the entry's "keylet parts" (the arguments to its keylet::
|
||||
* function) into a Keylet that the base class resolves against the view:
|
||||
*
|
||||
* AccountRoot<ApplyView> acct{id, view}; // peek (writable)
|
||||
* AccountRoot<ReadView> acct{id, readView}; // read (read-only)
|
||||
*
|
||||
* Domain-specific accessors will be layered onto each wrapper over time.
|
||||
*/
|
||||
|
||||
// Ordered to match include/xrpl/protocol/detail/ledger_entries.macro.
|
||||
|
||||
template <typename ViewT>
|
||||
class NFTokenOffer : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit NFTokenOffer(
|
||||
AccountID const& owner,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::nftokenOffer(owner, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Check : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Check(
|
||||
AccountID const& id,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::check(id, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class DID : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit DID(
|
||||
AccountID const& account,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::did(account), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class NegativeUNL : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit NegativeUNL(
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::negativeUNL(), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class NFTokenPage : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit NFTokenPage(
|
||||
Keylet const& page,
|
||||
uint256 const& token,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::nftokenPage(page, token), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class SignerList : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit SignerList(
|
||||
AccountID const& account,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::signerList(account), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Ticket : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Ticket(
|
||||
AccountID const& id,
|
||||
std::uint32_t ticketSeq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::ticket(id, ticketSeq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class AccountRoot : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit AccountRoot(
|
||||
AccountID const& id,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::account(id), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class DirectoryNode : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit DirectoryNode(
|
||||
AccountID const& id,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::ownerDir(id), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Amendments : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Amendments(
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::amendments(), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class LedgerHashes : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit LedgerHashes(
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::skip(), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Bridge : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Bridge(
|
||||
STXChainBridge const& bridge,
|
||||
STXChainBridge::ChainType chainType,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::bridge(bridge, chainType), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Offer : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Offer(
|
||||
AccountID const& id,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::offer(id, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class DepositPreauth : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit DepositPreauth(
|
||||
AccountID const& owner,
|
||||
AccountID const& preauthorized,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::depositPreauth(owner, preauthorized), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class XChainOwnedClaimID : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit XChainOwnedClaimID(
|
||||
STXChainBridge const& bridge,
|
||||
std::uint64_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::xChainClaimID(bridge, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class RippleState : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit RippleState(
|
||||
AccountID const& id0,
|
||||
AccountID const& id1,
|
||||
Currency const& currency,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::trustLine(id0, id1, currency), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class FeeSettings : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit FeeSettings(
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::feeSettings(), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class XChainOwnedCreateAccountClaimID : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit XChainOwnedCreateAccountClaimID(
|
||||
STXChainBridge const& bridge,
|
||||
std::uint64_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::xChainCreateAccountClaimID(bridge, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Escrow : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Escrow(
|
||||
AccountID const& src,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::escrow(src, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class PayChannel : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit PayChannel(
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::payChannel(src, dst, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class AMM : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit AMM(
|
||||
Asset const& issue1,
|
||||
Asset const& issue2,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::amm(issue1, issue2), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class MPTokenIssuance : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit MPTokenIssuance(
|
||||
std::uint32_t seq,
|
||||
AccountID const& issuer,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::mptokenIssuance(seq, issuer), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class MPToken : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit MPToken(
|
||||
MPTID const& issuanceID,
|
||||
AccountID const& holder,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::mptoken(issuanceID, holder), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Oracle : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Oracle(
|
||||
AccountID const& account,
|
||||
std::uint32_t documentID,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::oracle(account, documentID), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Credential : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Credential(
|
||||
AccountID const& subject,
|
||||
AccountID const& issuer,
|
||||
Slice const& credType,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::credential(subject, issuer, credType), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class PermissionedDomain : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit PermissionedDomain(
|
||||
AccountID const& account,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::permissionedDomain(account, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Delegate : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Delegate(
|
||||
AccountID const& account,
|
||||
AccountID const& authorizedAccount,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::delegate(account, authorizedAccount), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Vault : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Vault(
|
||||
AccountID const& owner,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::vault(owner, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class LoanBroker : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit LoanBroker(
|
||||
AccountID const& owner,
|
||||
std::uint32_t seq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::loanBroker(owner, seq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Loan : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Loan(
|
||||
uint256 const& loanBrokerID,
|
||||
std::uint32_t loanSeq,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::loan(loanBrokerID, loanSeq), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class Sponsorship : public SLEBase<ViewT>
|
||||
{
|
||||
public:
|
||||
explicit Sponsorship(
|
||||
AccountID const& sponsor,
|
||||
AccountID const& sponsee,
|
||||
typename SLEBase<ViewT>::view_ref_type view,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
: SLEBase<ViewT>(keylet::sponsorship(sponsor, sponsee), view, j)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
26
include/xrpl/ledger/helpers/SponsorHelpers.h
Normal file
26
include/xrpl/ledger/helpers/SponsorHelpers.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
std::optional<AccountID>
|
||||
getLedgerEntryOwner(ReadView const& view, SLE const& sle, AccountID const& account);
|
||||
|
||||
std::uint32_t
|
||||
getLedgerEntryOwnerCount(SLE const& sle);
|
||||
|
||||
} // namespace xrpl
|
||||
103
src/libxrpl/ledger/helpers/SponsorHelpers.cpp
Normal file
103
src/libxrpl/ledger/helpers/SponsorHelpers.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/OracleHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STArray.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
std::optional<AccountID>
|
||||
getLedgerEntryOwner(ReadView const& view, SLE const& sle, AccountID const& account)
|
||||
{
|
||||
switch (sle.getType())
|
||||
{
|
||||
case ltCHECK:
|
||||
case ltESCROW:
|
||||
case ltPAYCHAN:
|
||||
case ltMPTOKEN:
|
||||
case ltDELEGATE:
|
||||
case ltDEPOSIT_PREAUTH:
|
||||
return sle.getAccountID(sfAccount);
|
||||
case ltMPTOKEN_ISSUANCE:
|
||||
return sle.getAccountID(sfIssuer);
|
||||
case ltSIGNER_LIST: {
|
||||
auto const signerList = view.read(keylet::signerList(account));
|
||||
if (!signerList)
|
||||
return std::nullopt;
|
||||
if (signerList->key() == sle.key())
|
||||
return account;
|
||||
return std::nullopt;
|
||||
}
|
||||
case ltCREDENTIAL: {
|
||||
if (sle.isFlag(lsfAccepted))
|
||||
return sle.getAccountID(sfSubject);
|
||||
return sle.getAccountID(sfIssuer);
|
||||
}
|
||||
case ltRIPPLE_STATE: {
|
||||
if (sle.isFlag(lsfHighReserve))
|
||||
{
|
||||
auto const highAccount = sle.getFieldAmount(sfHighLimit).getIssuer();
|
||||
if (highAccount == account)
|
||||
return highAccount;
|
||||
}
|
||||
if (sle.isFlag(lsfLowReserve))
|
||||
{
|
||||
auto const lowAccount = sle.getFieldAmount(sfLowLimit).getIssuer();
|
||||
if (lowAccount == account)
|
||||
return lowAccount;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
default:
|
||||
// LCOV_EXCL_START
|
||||
UNREACHABLE("xrpl::getLedgerEntryOwner : object is not supported by sponsorship.");
|
||||
return std::nullopt;
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
getLedgerEntryOwnerCount(SLE const& sle)
|
||||
{
|
||||
switch (sle.getType())
|
||||
{
|
||||
case ltORACLE: {
|
||||
return calculateOracleReserve(sle.getFieldArray(sfPriceDataSeries));
|
||||
}
|
||||
// Vaults require 2 owner counts (the vault and a pseudo-account)
|
||||
case ltVAULT:
|
||||
return 2;
|
||||
case ltSIGNER_LIST: {
|
||||
// Mirror SignerListSet's owner-count accounting so that create and
|
||||
// delete agree. Modern lists (post-MultiSignReserve) carry the
|
||||
// lsfOneOwnerCount flag and cost a single owner count. Legacy
|
||||
// pre-MultiSignReserve lists cost 2 + signer_count owner counts
|
||||
if (sle.isFlag(lsfOneOwnerCount))
|
||||
return 1;
|
||||
return 2 + static_cast<std::uint32_t>(sle.getFieldArray(sfSignerEntries).size());
|
||||
}
|
||||
case ltACCOUNT_ROOT:
|
||||
UNREACHABLE("AccountRoots are not supported by object sponsorship.");
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
Reference in New Issue
Block a user