mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-27 00:50:45 +00:00
refactor: Move SponsorshipTransfer code around, add some comments (#7662)
This commit is contained in:
19
include/xrpl/ledger/helpers/OracleHelpers.h
Normal file
19
include/xrpl/ledger/helpers/OracleHelpers.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
constexpr uint32_t kMinOracleReserveCount = 1;
|
||||
constexpr uint32_t kMaxOracleReserveCount = 2;
|
||||
constexpr std::size_t kOracleReserveCountThreshold = 5;
|
||||
|
||||
inline uint32_t
|
||||
calculateOracleReserve(std::size_t priceDataSeriesCount)
|
||||
{
|
||||
return priceDataSeriesCount > kOracleReserveCountThreshold ? kMaxOracleReserveCount
|
||||
: kMinOracleReserveCount;
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/OracleHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
@@ -123,4 +124,99 @@ removeSponsorFromLedgerEntry(SLE::ref sle, SF_ACCOUNT const& field = sfSponsor)
|
||||
sle->makeFieldAbsent(field);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::optional<AccountID>
|
||||
getLedgerEntryOwner(ReadView const& view, T 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::signers(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:
|
||||
UNREACHABLE("Object is not supported by sponsorship.");
|
||||
return std::nullopt;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::uint32_t
|
||||
getLedgerEntryOwnerCount(T const& sle)
|
||||
{
|
||||
switch (sle->getType())
|
||||
{
|
||||
case ltORACLE: {
|
||||
return calculateOracleReserve(sle->getFieldArray(sfPriceDataSeries).size());
|
||||
}
|
||||
// Vaults require 2 owner counts (the vault and a pseudo-account)
|
||||
case ltVAULT:
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline SF_ACCOUNT const&
|
||||
getLedgerEntrySponsorField(T const& sle, AccountID const& owner)
|
||||
{
|
||||
switch (sle->getType())
|
||||
{
|
||||
case ltRIPPLE_STATE: {
|
||||
if (sle->isFlag(lsfHighReserve))
|
||||
{
|
||||
auto const highAccount = sle->getFieldAmount(sfHighLimit).getIssuer();
|
||||
if (highAccount == owner)
|
||||
return sfHighSponsor;
|
||||
}
|
||||
if (sle->isFlag(lsfLowReserve))
|
||||
{
|
||||
auto const lowAccount = sle->getFieldAmount(sfLowLimit).getIssuer();
|
||||
if (lowAccount == owner)
|
||||
return sfLowSponsor;
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
UNREACHABLE("Should not happen. Owner should be checked before calling this function.");
|
||||
return sfSponsor;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
default:
|
||||
return sfSponsor;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -22,12 +22,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
calculateOracleReserve(std::size_t count)
|
||||
{
|
||||
return count > 5 ? 2 : 1;
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/OracleHelpers.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STArray.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/transactors/oracle/OracleSet.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@@ -62,7 +62,7 @@ SponsorshipOwnerCountsMatch::visitEntry(
|
||||
if (!sle->isFieldPresent(sfSponsor))
|
||||
return 0;
|
||||
auto const priceDataSeries = sle->getFieldArray(sfPriceDataSeries);
|
||||
return OracleSet::calculateOracleReserve(priceDataSeries.size());
|
||||
return calculateOracleReserve(priceDataSeries.size());
|
||||
}
|
||||
case ltVAULT: {
|
||||
if (!sle->isFieldPresent(sfSponsor))
|
||||
|
||||
@@ -53,6 +53,9 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
|
||||
if (ctx.tx.isFlag(tfSponsorshipCreate))
|
||||
{
|
||||
// Sponsor must be included
|
||||
// SponsorFlags.spfSponsorReserve must be included
|
||||
// Sponsee must be excluded
|
||||
if (!isReserveSponsored(ctx.tx))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
@@ -68,6 +71,9 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
if (ctx.tx.isFlag(tfSponsorshipReassign))
|
||||
{
|
||||
// Sponsor must be included
|
||||
// SponsorFlags.spfSponsorReserve must be included
|
||||
// Sponsee must be excluded
|
||||
if (!isReserveSponsored(ctx.tx))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
@@ -83,6 +89,8 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
if (ctx.tx.isFlag(tfSponsorshipEnd))
|
||||
{
|
||||
// Sponsor must be excluded
|
||||
// SponsorFlags.spfSponsorReserve must be excluded
|
||||
if (isReserveSponsored(ctx.tx))
|
||||
{
|
||||
JLOG(ctx.j.debug())
|
||||
@@ -116,96 +124,18 @@ SponsorshipTransfer::preflight(PreflightContext const& ctx)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::optional<AccountID>
|
||||
getLedgerEntryOwner(ReadView const& view, T 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::signers(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:
|
||||
UNREACHABLE("Object is not supported by sponsorship.");
|
||||
return std::nullopt;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline SF_ACCOUNT const&
|
||||
getLedgerEntrySponsorField(T const& sle, AccountID const& owner)
|
||||
{
|
||||
switch (sle->getType())
|
||||
{
|
||||
case ltRIPPLE_STATE: {
|
||||
if (sle->isFlag(lsfHighReserve))
|
||||
{
|
||||
auto const highAccount = sle->getFieldAmount(sfHighLimit).getIssuer();
|
||||
if (highAccount == owner)
|
||||
return sfHighSponsor;
|
||||
}
|
||||
if (sle->isFlag(lsfLowReserve))
|
||||
{
|
||||
auto const lowAccount = sle->getFieldAmount(sfLowLimit).getIssuer();
|
||||
if (lowAccount == owner)
|
||||
return sfLowSponsor;
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
UNREACHABLE("Should not happen. Owner should be checked before calling this function.");
|
||||
return sfSponsor;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
default:
|
||||
return sfSponsor;
|
||||
}
|
||||
};
|
||||
|
||||
TER
|
||||
SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const index = ctx.tx[~sfObjectID];
|
||||
auto const newSponsorSle = getTxReserveSponsor(ctx.view, ctx.tx);
|
||||
if (!newSponsorSle)
|
||||
return newSponsorSle.error(); // LCOV_EXCL_LINE
|
||||
auto const newSponsorSleExpected = getTxReserveSponsor(ctx.view, ctx.tx);
|
||||
if (!newSponsorSleExpected)
|
||||
return newSponsorSleExpected.error(); // LCOV_EXCL_LINE
|
||||
auto const newSponsorSle = *newSponsorSleExpected;
|
||||
|
||||
bool const isObjectSponsor = index != std::nullopt;
|
||||
bool const isObjectSponsor = !!index;
|
||||
|
||||
auto const account = ctx.tx[sfAccount];
|
||||
|
||||
auto const sponseeID = ctx.tx[~sfSponsee].value_or(account);
|
||||
auto const sponseeSle = ctx.view.read(keylet::account(sponseeID));
|
||||
if (!sponseeSle)
|
||||
@@ -243,23 +173,23 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
std::uint32_t const ownerCountDelta = 1;
|
||||
|
||||
auto const owner = getLedgerEntryOwner(ctx.view, sle, sponseeID);
|
||||
if (!owner || owner != sponseeID)
|
||||
if (!owner.has_value() || owner.value() != sponseeID)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
auto const& sponsorField = getLedgerEntrySponsorField(sle, *owner);
|
||||
auto const& sponsorField = getLedgerEntrySponsorField(sle, owner.value());
|
||||
|
||||
if (ctx.tx.isFlag(tfSponsorshipCreate))
|
||||
{
|
||||
if (!*newSponsorSle)
|
||||
if (!newSponsorSle)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// check object is not sponsored yet
|
||||
// check that the object is not sponsored yet
|
||||
if (sle->isFieldPresent(sponsorField))
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
else if (ctx.tx.isFlag(tfSponsorshipReassign))
|
||||
{
|
||||
if (!*newSponsorSle)
|
||||
if (!newSponsorSle)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// check object is already ctx.sponsored
|
||||
@@ -268,7 +198,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
else if (ctx.tx.isFlag(tfSponsorshipEnd))
|
||||
{
|
||||
if (*newSponsorSle)
|
||||
if (newSponsorSle)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// check object is sponsored
|
||||
@@ -288,7 +218,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
ctx.tx,
|
||||
sponseeSle,
|
||||
sponseeSle->getFieldAmount(sfBalance),
|
||||
*newSponsorSle,
|
||||
newSponsorSle,
|
||||
ownerCountDelta,
|
||||
0,
|
||||
ctx.j);
|
||||
@@ -299,7 +229,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
if (ctx.tx.isFlag(tfSponsorshipCreate))
|
||||
{
|
||||
if (!*newSponsorSle)
|
||||
if (!newSponsorSle)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// check account is not sponsored yet
|
||||
@@ -308,7 +238,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
else if (ctx.tx.isFlag(tfSponsorshipReassign))
|
||||
{
|
||||
if (!*newSponsorSle)
|
||||
if (!newSponsorSle)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// check account is already sponsored
|
||||
@@ -317,7 +247,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
else if (ctx.tx.isFlag(tfSponsorshipEnd))
|
||||
{
|
||||
if (*newSponsorSle)
|
||||
if (newSponsorSle)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// check account is sponsored
|
||||
@@ -340,7 +270,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
ctx.tx,
|
||||
sponseeSle,
|
||||
sponseeSle->getFieldAmount(sfBalance),
|
||||
*newSponsorSle,
|
||||
newSponsorSle,
|
||||
0,
|
||||
1,
|
||||
ctx.j);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
|
||||
Reference in New Issue
Block a user